How to add and remove active class dynamically - angularjs

In my webpage I have 2 languages English and Hindi. By default my page will be in English.
When I click on Hindi language I want to add active class to li which has hin id, and want to remove active class, which has eng id.
<li class="lang active" id="eng">
ENG
</li>
<li class="lang" id="hin">
HIN
</li>
Whenever I change language page gets refreshed. I need these changes once page is refreshed
myfunc = function(item) {
$scope.selectedlang = item;
var test = {value: item, displayValue: ''};
c.server.get(test).then(function() {
$window.location.reload();
})
I tried like this.
<li ng-class="{'active':selectedTab === 'eng'}" ng-click="selectedTab = 'eng'">
english
</li>
<li ng-class="{'active':selectedTab === 'hin'}" ng-click="selectedTab = 'hin'">
hindi
</li>
But these changes are not appearing after a page refresh.
How can I toggle classes using AngularJS?

try this
<li ng-class="{'active':location.hash == '#eng'}"><a href="#eng" >english</a>
</li>
<li ng-class="{'active':location.hash == '#hin'}"><a href="#hin" >hindi</a>
</li>
or
<li ng-class="{'active':location.hash == '#eng'}" id="eng">
ENG
</li>
<li ng-class="{'active':location.hash == '#hin'}" id="hin">
HIN
</li>
myfunc = function(item) {
location.hash = item;
$scope.selectedlang = item;
var test = {value: item, displayValue: ''};
c.server.get(test).then(function() {
$window.location.reload();
})

Store selectedTab value in local storage than refresh page. Once the page is reloaded get value from local storage and assign to selectedlang.
myfunc = function (item) {
$scope.selectedlang = item;
$window.localStorage.setItem('lang', item);
var test = {
value: item,
displayValue: ''
};
c.server.get(test).then(function () {
$window.location.reload();
});
}
// On page load
$scope.selectedlang = $window.localStorage.getItem('lang') || 'eng';

Here the problem is,Whenever page is refreshed then language is set to default language 'eng'.So try to store language value in localstorage and then apply ng-class.
<li ng-class="{'active':selectedTab == 'eng'}" ng-click="selectedTab('en')">
english
</li>
<li ng-class="{'active':selectedTab == 'hin'}" ng-click="selectedTab('hin')">
hindi
</li>
selectedTab= function(item) {
localStorage.setItem("selectedTab",item);
})
Then get this locastorage value on page refersh method.
Hope this helps:)

You can Add the class using ng-class, like this.
ng-class="{active: $index == selected}"
Here, .active is added to class list on the condition $index == selected
and to remove the .active from the list, reset the selected by
$scope.selected = -1

Related

Angular - Displaying array as list in frontend

I'm working on my web-app and I am facing a problem.
I have an array with several values, which I'd like to display in the frontend as list or something similar.
app.component.ts
in this function I split the tags from the string into an array
splitTags() {
if (this.data.tags != null) {
var tag = this.data.tags.split(";")
console.log(tag)
}
}
ngOnInit() {
this.splitTags()
}
app.component.html
here I d'like to display the tags in a list
<li *ngFor="let tag in tags">
{{ tag }}
</li>
but nothing appears, also if I see the values in the console.
you need to create a property to hold the split result
tags:any[]; // 1️⃣
splitTags() {
if (this.data.tags != null) {
this.tags = this.data.tags.split(";"); // 2️⃣
console.log(this.tags)
}
}
ngOnInit() {
this.splitTags()
}
template
<li *ngFor="let tag of tags">
{{ tag }}
</li>

Show and Hide a <div> inside an ng-repeat with 'dirPagination' (AngularJS)

In this very site I've seen this question many times, but none of them works for me because of two things: I need the div to toggle when clicking the "options" button, but also to hide when clicking outside of the div; and I need it to work with dirPagination.
I saw this answer, it works fine but with one problem I just can't solve: it shows ALL the hidden divs at the same time, instead of only showing the one I clicked.
Here's my code:
<body ng-controller="MainCtrl">
<!-- pagination -->
<dir-pagination-controls
max-size="7"
direction-links="true"
boundary-links="true">
</dir-pagination-controls>
<ul>
<li dir-paginate="report in reports | itemsPerPage:4">
Options
<h3>{{report.Title}}</h3>
<div class="options" ng-show="dp">
<p>These are some options</p>
</div>
</li>
</ul>
</body>
And the JS to show the options:
//options div
$scope.showOptions = function(event){
if($scope.dp === false || $scope.dp === undefined) {
$scope.dp = true;
event.stopPropagation();
} else {
$scope.dp = false;
}
};
window.onclick = function(){
if($scope.dp){
$scope.dp = false;
$scope.$apply();
}
};
I've made a Plunker in case you wanna se it in action: my Plunker link
Can somebody help me with this issue? :(
Add a new boolean property on your reports array , for example show
var reports = [
{
"ID":1,
"Title":"Report 1",
"Show":false
},
{
"ID":2,
"Title":"Report 2",
"Show":false
}
]
Apply the property in to ng-show and also pass the current report scope object in to showOptions method to write the logic for hide and show.
<li dir-paginate="report in reports | itemsPerPage:4">
Options
<h3>{{report.Title}}</h3>
<div class="options" ng-show="report.Show">
<p>These are some options</p>
</div>
</li>
$scope.showOptions = function(event,report){
report.Show=!report.Show;
/*you can iterate through each reports and change show to false if the clicked report id not equal to report id , Angular JS will automatically update the scope in to the view*/
reports.forEach(function(item, index) {
if (item.ID !== report.ID) {
item.Show = false;
}
});
if($scope.dp === false || $scope.dp === undefined) {
$scope.dp = true;
event.stopPropagation();
} else {
$scope.dp = false;
}
};
https://next.plnkr.co/edit/hnhWMrgR3GMtVcES
You need to use a separate variable for each div you want to show. You could add the dp attribute to the report. There is no need to loop over the reports to hide them. You can just keep track of the currently visible report and hide it when another one is toggled.
Here is the relevant HTML:
<li dir-paginate="report in reports | itemsPerPage:4">
Options
<h3>{{report.Title}}</h3>
<div class="options" ng-show="report.dp">
<p>These are some options</p>
</div>
</li>
and JavaScript
var visibleReport;
$scope.showOptions = function(event, report){
if (report == visibleReport) {
report.dp = !report.dp;
}
else {
if (visibleReport) visibleReport.dp = false;
report.dp = true;
}
visibleReport = report
event.stopPropagation();
};
window.onclick = function(){
if (visibleReport) visibleReport.dp = false;
visibleReport = null;
$scope.$apply();
};
Here is a working plunker https://next.plnkr.co/edit/sWLxBGlF8D22nvYp?preview

How Do I Move Objects Inside An ng-Repeat on Button Click?

I have a nifty list of items in an ng-repeat with an up and down button on each. I just want the up button to move the list item up one place and the down button should move it down one place.
The problem is that I get an error saying "Cannot read property 'NaN' of undefined."
It seems "position" is undefined on the second line. What can I do to fix that?
Heres the javascript I'm working with (thanks to Rishul Matta):
$scope.moveUp = function(ind, position) {
$scope.temp = $scope.list[position - 1];
$scope.list[position - 1] = $scope.list[position];
$scope.list[position = temp];
};
Here's my HTML:
<ul>
<li class="steps" ng-repeat="step in selectedWorkflow.Steps track by $index" ng-class="{'words' : step.Id != selectedStep.Id, 'selectedWords' : step.Id == selectedStep.Id}" ng-model="selectedWorkflow.Step" ng-click="selectStep(step, $index); toggleShow('showSubStep'); toggleShow('showEditBtn')">
{{step.Name}}
<input class="orderUpBtn" type="button" ng-click="moveUp($index, step)" style="z-index:50" value="U" />
<input class="orderDownBtn" type="button" style="z-index:50" value="D" />
</li>
</ul>
Thanks!
Thanks for posting this question (+1) and the answer jtrussell (+1). I wanted to share what I believe to be a more re-usable/modular answer for other folks (inspired by odetocode.com post).
For the HTML, jtrussell's code is perfect because he fixed/simplified everything. For a better user experience I just added ng-disabled for the first/last elements.
HTML:
<ul ng-controller="DemoCtrl as demo">
<li ng-repeat="item in demo.list">
{{item}}
<button class="move-up"
ng-click="listItemUp($index)"
ng-disabled="$first">
Move Up
</button>
<button class="move-down"
ng-click="listItemDown($index)"
ng-disabled="$last">
Move Down
</button>
</li>
</ul>
For the JS, Notice the moveItem() function which I believe to be more re-usable. You can use this function for other drag+drop swapping functionality as well.
JS within Controller (tested on Angular 1.3.15):
// Move list items up or down or swap
$scope.moveItem = function (origin, destination) {
var temp = $scope.list[destination];
$scope.list[destination] = $scope.list[origin];
$scope.list[origin] = temp;
};
// Move list item Up
$scope.listItemUp = function (itemIndex) {
$scope.moveItem(itemIndex, itemIndex - 1);
};
// Move list item Down
$scope.listItemDown = function (itemIndex) {
$scope.moveItem(itemIndex, itemIndex + 1);
};
I hope it is helpful to someone out there. Thanks SO community!
A simple list with up/down buttons is pretty straightforward, here's some rough generic code. The ngRepeat directive will honor the order of items in your array so moving things around the view is just a matter of moving them in the array itself.
view:
<ul ng-controller="DemoCtrl as demo">
<li ng-repeat="item in demo.list">
{{item}}
<button ng-click="demo.moveUp($index)">up</button>
<button ng-click="demo.moveDown($index)">down</button>
</li>
</ul>
controller:
app.controller('DemoCtrl', function() {
this.list = list = ['one', 'two', 'three', 'four'];
this.moveUp = function(ix) {
if(ix > -1 && ix < list.length - 1) {
var tmp = list[ix+1];
list[ix+1] = list[ix];
list[ix] = tmp;
}
};
this.moveDown = function(ix) {
// similar...
};
});
There were a few strange items in your code (for example did you mean $scope.list[position] = temp; when you wrote ($scope.list[position = temp];), my example isn't perfect but it should get you going on the right path. Here's the full working demo: http://jsbin.com/vatekodeje, note that in my code I use "up" to mean increasing index rather than toward the top of the page.
Also in your controller you use position as an index (it's not clear that it should be) and make reference to, presumably, an array called $scope.list when in your view you use selectedWorkflow.Steps. Maybe your $scope.list and selectedWorkflow.Steps are meant to be the same thing?

AngularJS ng-repeat filter, function over object property

I am looking for a way to check for each movie if the movie has the category which is selected. Movies is an array which contains objects, those objects have some properties, like you can see in the code below. The categories property is a array of categories where the movie is in. Now there is a variable selectedCategories where the current selected category is stored in.
I don't want to use custom filters, because I think it has te be possible with this one, I just can't quite get it. In the javascript function there can't be changed too much either.
If the return of hasSelectedCategory is true, then it has to execute the block, if false not.
Thanks in advance.
//in the javascript file
scope.hasSelectedCategory = function(categories){
var hasCategory = false;
if (categories.indexOf(scope.selectedCategory) !== -1){
hasCategory = true;
}
return hasCategory;
};
//in the html file
<div class="movieListItem {{listItemView}}" ng-repeat="movie in movies | filter:{hasSelectedCategory(categories): true}">
<h4>{{movie.title}}</h4>
<a href="http://www.youtube.com/embed/{{movie.youtubeId}}?rel=0&autoplay=1">
<img ng-src="{{findPosterSource(movie)}}" class="poster"> </a>
<p ng-hide="listItemView === 'grid'">
{{movie.description}}
</p>
<div class="categories" >
<span ng-repeat="category in movie.categories"> <a ng-href="#">{{category}}</a> </span>
</div>
</div>
You have to use the filter like this:
ng-repeat="movie in movies | filter:hasSelectedCategory"
The hasSelectedCategory function will be invoked for each movie in the movies list. In order to filter by selected categories you can use a function like this:
$scope.hasSelectedCategory = function(movie) {
var hasCategory = false;
angular.forEach($scope.selectedCategories, function(selectedCategory) {
if (!hasCategory && movie.categories.indexOf(selectedCategory) !== -1) {
hasCategory = true;
}
});
return hasCategory;
};
Demo (plunker)

target selected list item in backbone

I'm using foundation drop-down
You can have a look at it here:
http://foundation.zurb.com/docs/components/dropdown.html#
I've created a dropdown with the following code
<a href="#" data-dropdown="drop1" >Date Range </a>
<ul id="drop1" class="f-dropdown large date-menu" drop-down-content>
<li id="custom">Custom</li>
<li id="today">Today</li>
<li id="yesterday">Yesterday</li>
<li id="sundaytoToday">This Week(Sun-Today)</li>
<li id="montoToday">This Week(Mon-Today)</li>
</ul>
I want to get the value/id of the selected element
I've tried like below, but it's not working
'click #drop1 li':"changeDateRange",
changeDateRange : function(event)
{
var ss=$(this).attr('id');
console.log(ss);
if(ss=="custom")
{
console.log("custom if");
}
},
Try this:
...
var ss = event.currentTarget.id
...
So in backbone, the "this" for the delegate events are bound to the class itself. So you would have to use "event.currentTarget"
'click #drop1 li':"changeDateRange",
changeDateRange : function(event)
{
var ss=$(event.currentTarget).attr('id');
console.log(ss);
if(ss=="custom")
{
console.log("custom if");
}
},

Resources