auto select first ng-repeat element in angularjs? - javascript

any idea on how to do this?
i basically have 1 controller set up and if you click on an element, an animation appears above, however, the first element should be active/clicked as soon as the page loads...
some code:
Animation Appears here:
<div class="animation">
<div ng-repeat="theme in themes" ng-show="isActive($index);" ng-if="isActive($index);">
<img id="id_{{ theme.animation_id }}" ng-src="{{ theme.animation_gif_url }}" class="active" />
</div>
</div>
Animation selection here:
<div class="theme-select animated fadeInUp">
<div class="theme-container" ng-repeat="theme in themes" ng-click="showAnimation($index);">
<div id="theme_{{ theme.animation_id }}" class="theme">
<img ng-src="{{ theme.icon_url }}" />
<div class="name">
{{ theme.name }}
</div>
</div>
</div>
</div>
Here's my controller:
themeFunction(function(themeData) {
name = [];
themeID = [];
animationURL = [];
var themes = $scope.themes = themeData.themes;
for (var t = 0; t < themes.length; t++) {
animationURL = themes[t].animation_url;
themeID = themes[t].animation_id;
iconURL = themes[t].icon_url;
name = themes[t].name;
animationGifUrl = themes[t].animation_gif_url;
$scope.themeID = themeID;
if ($scope.themes[t].animation_gif_url == 'NULL' || $scope.themes[t].animation_gif_url == null || $scope.themes[t].animation_gif_url == '.gif') {
// console.log(name + " are null or weird");
$scope.themes[t].animation_gif_url = iconURL;
} else {
$scope.themes[t].animation_gif_url = animationGifUrl;
}
}
$scope._Index = 0;
$scope.isActive = function(index) {
return $scope._Index === index;
};
$scope.showAnimation = function(index) {
selectedTheme = $(this).attr('theme');
console.log('Selected ' + selectedTheme.animation_id);
$scope._Index = index;
};
});

In your controller, after your list loads up, call the showAnimation on the first index
...list loads up
$scope.themes = data;
if (data.length) $scope.showAnimation(0);

Because:
[] == false
So, you can do if simply like this:
if (themes) $scope.showAnimation(0);
If themes is a empty array, not thing will happened.
If themes is a array has at least one theme, will trigger showAnimation function

Related

How to push and pop the details into the array in javascript based on the selection of cards?

I am having 6 bootstrap cards in my web page where every card consists of details like id and content. When I clicked the card the details of the card should be pushed into the array and when I clicked the same card the details should be popped from the array.
My html page in django:
<div class="row">
{% for j in goal %}
<div class="col-4" onclick="getGoal({{j.id}})">
<div class="card4 mt-3" id="room_{{j.id}}" style="width: 12rem; height:9rem;">
<center>
<div class="card-body">
<p class="card-text mt-4" id="cont_{{j.id}}"><b>{{j.goal}}</b></p>
</center>
</div>
</div>
</div>
{% endfor %}
My js code is
var goal = []
function getGoal(id ,content){
if (goal !== []) {
for(var i=0; i<goal.length; i++){
if(goal[i].id == id) {
var index = goal.indexOf(goal[i])
if (index !== -1) {
goal.splice(index, 1);
}
}
}
}else {
var data = {id: id, content: $("#cont_"+id).text()}
var x = JSON.stringify(data)
goal.push(x)
console.log(goal)
}
}
var storedNames = JSON.parse(localStorage.getItem("goal"))
Is the JS code correct for my requirement?
As you can see after adding indentations, you html code is not valide where do you close the center tag ? Else where / how do you call getGoal and why do you have the content parameter if you don't use it ?
var goal = []
function getGoal(id ){
if (goal.length > 0) {
let index = goal.findIndex(x=>x.id == id)
if(index != -1){
goal.splice(index, 1);
}
else{
var data = {id: id, content: $("#cont_"+id).text()}
goal.push(data)
}
}else {
var data = {id: id, content: $("#cont_"+id).text()}
//var x = JSON.stringify(data)
goal.push(data)
console.log(goal)
}
}
var storedNames = JSON.parse(localStorage.getItem("goal"))
try It

ngInfiniteScroll stops working after ng-click on repeated element

I'm using ngInfiniteScroll in a few different places to show contacts, and missed calls. It loops over every item and adds a ng-click to show user profile. The scrolling works fine in all locations until you actually click on a user/call. Afterwards the scroll never triggers again in either contacts nor phone calls. I've looked at their docs and seen infinite-scroll-listen-for-event which I figured is what I needed for infinite scroll to reset after the click event, but it doesn't appear to be working. I can't tell if I have the $emit in the wrong location, or what?
HTML
<md-list infinite-scroll="recent.moreContacts()" infinite-scroll-disabled="recent.busy" infinite-scroll-listen-for-event="resetInfiniteScrollList" infinite-scroll-distance="1" infinite-scroll-immediate-check="false" infinite-scroll-parent="true">
<md-list-item ng-repeat="client in recent.clients | orderBy:'firstName'" ng-click="recent.viewCustomer(client.id)" class="repeater-list-item recent-session" layout="row" layout-align="start start" aria-label="View {{client.fullName}}'s profile">
<div ng-if="client.avatar" class="md-avatar" style="background-image: url('{{client.avatar}}');"></div>
<div ng-if="!client.avatar" class="md-avatar" ></div>
<div class="md-list-item-text">
<h3>{{client.firstName}} {{client.lastName}} <span ng-if="!client.firstName">Unknown <small class="text-tertiary text-gray">(Customer: {{client.id}})</small></span></h3>
</div>
</md-list-item>
</md-list>
loading contacts
vm.moreContacts = function () {
$timeout(function () {
$rootScope.closeSidenavs();
$rootScope.btnActive = 'contacts';
$mdSidenav('contacts').open();
$sessionStorage.currentTab = 'contacts';
if (vm.busy || vm.foundAllContacts || vm.contactsSearchActive) {
} else {
vm.busy = true;
api.get('/account/' + $rootScope.user.account.id + '/clients?page=' + vm.contactsNextPage, function (success, data) {
if (success) {
for (var i = 0; i < data.clients.length; i++) {
vm.clients.push(data.clients[i]);
}
self.totalFound = data.totalFound;
self.lastPageLoaded = data.page;
if (data.clients.length === 25) {
vm.contactsNextPage = vm.contactsNextPage += 1;
console.log(vm.contactsNextPage);
}
if (vm.clients.length === self.totalFound) {
vm.foundAllContacts = true;
}
} else {
vm.isClientsError = true;
}
vm.busy = false;
});
}
}, 10);
};
ng-click function
vm.viewCustomer = function (clientId) {
if (clientId > 0) {
if ($mdMedia('xs') || $mdMedia('sm')) {
$rootScope.btnActive = '';
$rootScope.closeSidenavs();
}
$location.path(
"/customer/" + clientId + "/feed"
);
$rootScope.$emit('resetInfiniteScrollList');
//vm.contactsSearchActive = false;
}
};

How to dynamically change attributes depending on JSON data?

I have the following miniapp:
[![enter image description here][1]][1]
When clicking on the elements on the left list, the info should change dynamically on the right div in relation to that clicked element.
I could get it work statically, but I don't know how to make it dynamic.
I have a JSON file with the data, and data is loading correctly and being parsed correctly.
data = '[{"name": "Hotel Sunny Palms","imgUrl": "images/sunny.jpg","rating": 5,"price": 108.00},{"name": "Hotel Snowy Mountains","imgUrl": "images/snowy.jpg","rating": 4,"price": 120.00},{"name": "Hotel Windy Sails","imgUrl": "images/windy.jpg","rating": 3,"price": 110.00},{"name": "Hotel Middle of Nowhere","imgUrl": "images/nowhere.jpg","rating": 4,"price": 199.00}]';
And I have the following HTML file:
<section class="container clear">
<div class="header">
<img class="logo" src="images/lmn-logo-white.svg">
</div>
<div class="inner-container clear">
<aside class="hotels-list">
<ul>
<li class="hotel">1</li>
<li class="hotel">2</li>
<li class="hotel">3</li>
<li class="hotel">4</li>
</ul>
</aside>
<article class="hotel-description">
<div class="hotel-description-container clear">
<div class="hotel-pic-container">
<img id="hotel-pic" src="images/sunny.jpg" height="130px">
</div>
<div class="hotel-info">
<h6 id="hotel-name" >Hotel Sunny Plans </h6>
<div id="hotel-rating" class="hotel-rating"></div>
<div id="hotel-price" class="hotel-price">
$180.00
<span>Total hotel stay</span>
</div>
</div>
</div>
</article>
</div>
</section>
My JS file is this: I get the data to change, but in a static way. Basically what it does is find all the li items and change the info on the right div when clicked.
var hotelData = JSON.parse(data);
document.addEventListener('DOMContentLoaded', function() {
var hotels = document.getElementsByClassName("hotel");
for (var i = 0; i < hotels.length; i++) {
hotels[i].addEventListener('click',function()
{
this.style.background = "#ccc";
this.style.color = "#fff";
var hotelName = document.getElementById("hotel-name");
hotelName.innerHTML = hotelData[this].name;
var hotelPrice = document.getElementById("hotel-price");
hotelPrice.innerHTML = "$" + hotelData[this].price + ".00" + "<span>Total hotel stay</span></div>";
var hotelPic = document.getElementById("hotel-pic");
hotelPic.src=hotelData[this].imgUrl;
var hotelRating = document.getElementById("hotel-rating");
if (hotelData[0].rating == 0) {
hotelRating.style.backgroundPosition = "0px 18px";
}
else if (hotelData[0].rating == 1) {
hotelRating.style.backgroundPosition = "0px 36px";
}
else if (hotelData[0].rating == 2) {
hotelRating.style.backgroundPosition = "0px 54px";
}
else if (hotelData[0].rating == 3) {
hotelRating.style.backgroundPosition = "0px 72px";
}
else if (hotelData[0].rating == 4) {
hotelRating.style.backgroundPosition = "0px 90px";
}
else if (hotelData[0].rating == 5) {
hotelRating.style.backgroundPosition = "0px 108px";
}
});
};
});
Any advice? Thanks!!!
If you are okay with jQuery then here is the quick and very simple solution:
$(function () {
var hotel_list = '';
$.each(data, function(index, hotel) {
hotel_list += '<li class="hotel" data-index="'+ index +'">'+ hotel.name +'</li>';
});
$("aside.hotels-list ul").html(hotel_list);
$(document).on("click", "li.hotel", function () {
var index = $(this).attr('data-index');
load_hotel_info(index);
});
function load_hotel_info(index) {
// Assuming the data variable is global...
if(typeof data[index] !== undefined) {
var hotel = data[index];
$("#hotel-pic").attr('src', hotel.imgUrl);
$("#hotel-name").html(hotel.name);
$("#hotel-rating").html(hotel.rating);
$("#hotel-price").html(hotel.price + '<span>Total hotel stay</span>');
}
}
load_hotel_info(0); // When the page loads for the first time it should show the first item info on the right.
// If you are loading data from ajax then this won't be necessary.
});
In this way the hotel list in the side will also load dynamically. And there isn't much to make it work. Just load the jquery by a script tag before the above code.
I hope it helps.

ng-repeat with dynamic array : view not updated

I have some checkboxes inside blocks like this :
<div ng-show="searchIn.IS" class="filterContent">
<div ng-click="toggleFilter('IS')">
<span class="{{filters.IS}}FilterIcon"></span>
Information System :
</div>
<div ng-show="filters.IS">
<md-checkbox ng-repeat="IS in ISList" ng-click="setISSearch(IS)" ng-checked="isInISSearch(IS)">
{IS}}
</md-checkbox>
</div>
</div>
<br />
<div ng-show="searchIn.area" class="filterContent">
<div ng-click="toggleFilter('area')">
<span class="{{filters.area}}FilterIcon"></span>
Area :
</div>
<div ng-show="filters.area">
<md-checkbox ng-repeat="area in filterAreaList" ng-click="setAreaSearch(area)" ng-checked="isInAreaSearch(area)" ng-show="isInCurrentAreas(area)">
{{area}}
</md-checkbox>
</div>
</div>
So the thing is that filterAreaList is changed each time I check or uncheck a checkbox from the ISList block. But the view is not updated, all the area are still displayed.
I also tried ng-if instead of ng-show.
$scope.filterAreaList = [];
$scope.getAreaFilters = function () {
$scope.searchedIS = $scope.ISList.slice();
for (var i = $scope.searchedIS.length; i >= 0; i--) {
if ($scope.searched.IS.indexOf($scope.searchedIS[i]) === -1)
$scope.searchedIS.splice(i, 1);
}
for (var i = 0; i < $scope.areaList.length; i++) {
for (var j = 0; j < $scope.searchedIS.length; j++)
if ($scope.hasArea($scope.searchedIS[j], $scope.areaList[i]))
$scope.filterAreaList.push($scope.areaList[i]);
}
};
$scope.isInCurrentAreas = function (area) {
if ($scope.filterAreaList.indexOf(area) === -1)
return false;
return true;
};
Some other topics pointed to this : http://www.bennadel.com/blog/2443-rendering-dom-elements-with-ngrepeat-in-angularjs.htm
But I don't really see how to apply this to my case.
Well, I actually missed a few things :
In order to make it work, I added : $scope.filterAreaList = []; in my getAreaFilters() function, and I call getAreaFilters() in my setAreaSearch(area)
And that's it.

KnockoutJS calling computed for each element in foreach

I have a problem i cannot figure out..
My example on JSbin: http://jsbin.com/wiwuwepe/1/edit
Basicly, in
<script id="QuestionTemplate" type="text/html">
<div class="well">
<div class="form-group">
<div class="col-md-5">
<p class="form-control-static" data-bind="text: QuestionText"></p>
</div>
</div>
<div class="form-group">
<div class="col-md-5">
<!-- THIS IS WHERE I WANT COMPUTED FOR EACH SURVEYQUESTION -->
<p class="form-control-static" data-bind="text: QuestionTypeTemplate"></p>
</div>
</div>
</div>
QuestionTypeTemplate shows undefinded, although model for this is
function SurveyQuestion(data) {
var self = this;
self.QuestionText = ko.observable(data.QuestionText);
self.QuestionType = ko.observable(data.QuestionType);
self.QuestionAnswers = ko.observableArray(data.QuestionAnswers);
self.QuestionTypeTemplate = ko.computed(function () {
/*
if( self.QuestionType() == 0) {
return "radio";
} else if (self.QuestionType() == 1) {
return "checkbox";
}
*/
return "This is what i want";
}, self);
}
Please, check full code on jsbin. Just uncomment that 1 line in QuestionTemplate script/html.
When I compare my example with http://knockoutjs.com/examples/cartEditor.html , I really cant find big difference, why that works, and why mine does not.
on your Survey function
instead of this
self.SurveyQuestions = ko.observableArray(data.SurveyQuestions);
you need to use this
var questions = [];
for(i = 0 ; i<data.SurveyQuestions.length ; i++) {
questions.push(new SurveyQuestion(data.SurveyQuestions[i]));
}
self.SurveyQuestions = ko.observableArray(questions);

Categories

Resources