Angular JS filter not equals - javascript

Seems like a very basic question but I can't get the syntax right..
<li class="list-group-item" ng-repeat="question in newSection.Questions | filter:Id != '-1'; " ng-mouseenter="hover = true" ng-mouseleave="hover = false">
<div href="#" editable-text="question.Text">{{question.Text}}</div>
</li>
All I want is to show all the questions where id is NOT -1.
What am I doing wrong. Thanks!

The syntax is just a little off, try:
<li class="list-group-item"
ng-repeat="question in newSection.Questions | filter:{ Id: '!-1'}"
ng-mouseenter="hover = true" ng-mouseleave="hover = false">
<div href="#" editable-text="question.Text">{{question.Text}}</div>
</li>
See a little JSFiddle: http://jsfiddle.net/U3pVM/3845/
Edit:
Example with variables:
<script> var invalidId = '-1'; </script>
<li class="list-group-item"
ng-repeat="question in newSection.Questions | filter:{ Id: '!' + invalidId}"
ng-mouseenter="hover = true" ng-mouseleave="hover = false">
<div href="#" editable-text="question.Text">{{question.Text}}</div>
</li>

Although #Michael Rose answer works for this case, i don't think it will if you try to filter not equal some object/variable
In that case you could use:
JS:
filterId = -1
HTML:
<li ng-repeat="question in newSection.Questions | filter: !{ Id: filterId}">
</li>
An even more nested case:
JS:
someQuestion = {
someObject: {
Id: 1
}
}
newSection.Questions = [someQuestion]
HTML
<li ng-repeat="question in newSection.Questions | filter: !{someObject : {Id: -1} }">
</li>

Related

Delete button "delete" after clicking in ng-repeat

I'm showing data by ng-repeat. There Have button. to delete item.
After delete item, this button must dissapear only for item that I deleted.
<tr ng-repeat="paymentinfo in paymentList | filter:keyword | filter:money | filter:getdate | filter:{state: 'archived'}: archived.state ? true : false">
<td id="outmouse">
<ul style="list-style: none;" class="gt-reset">
<li class="dropdown changecoursename">
<a class="dropdown-toggle" data-toggle="dropdown">
<span class="tableOperation norlmalstate">Open Course</span>
<span class="tableOperation openedstate">more options</span>
<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a class="tableOperation" ng-click="paymentRemarks()">Remarks</a></li>
<li><a class="tableOperation" ng-click="paymentReturn(paymentinfo)">Return</a></li>
<li ng-switch on="paymentinfo.state">
<div ng-switch-when="archived" class="archived__state">{{paymentinfo.state}}</div>
<a ng-switch-default class="tableOperation" ng-click="paymentDelete();">{{deletebtn}}</a>
</li>
</ul>
</li>
</ul>
</td>
</tr>
There place where I need to delete
<li ng-switch on="paymentinfo.state">
<div ng-switch-when="archived" class="archived__state">{{paymentinfo.state}}</div>
<a ng-switch-default class="tableOperation" ng-click="paymentDelete();">{{deletebtn}}</a>
</li>
My JS
$scope.datas = [{
date: '06-12-2016',
name: 'Pinao Class',
state: 'archived',
remark: 'remarled',
amount: 101,
id: 21
}, {
date: '15-04-2016',
name: 'drivers Class',
state: 'notarchived',
remark: 'remarled',
amount: 102,
id: 22
}];
$scope.paymentList = $scope.datas;
$scope.deletebtn = "delete";
$scope.paymentDelete = function() {
$scope.www = true;
$scope.deletebtn = false;
}
My code deleting for All elements need delete just for one I choose
try this
ng-click="paymentDelete(this.paymentinfo);">// pass current object to delete function
$scope.paymentDelete = function (paymentinfo ) {
$scope.www = true;
var index = $scope.paymentList.indexOf(paymentinfo );
if (index > -1) {
$scope.paymentList.splice(index, 1);
}
}

Pagination shown even though there is no data in angular

Here is my code:
Buttons:
<li ><a data-ng-click="Data1 = true;Data2 = false; search.status = ''" href="">ALL PROJECTS</a></li>
<li ><a data-ng-click="Data2 = true;Data1 = false" href="">NOTIFICATIONS</a></li>
Populated data on click of button:
<ul>
<li ng-show="Data1" dir-paginate="wd in workOrdersList | filter: search.status | filter: search.name | itemsPerPage: 10">
<a href="">
<h4>{{wd.name}}</h4>
</a>
<p>Status: {{wd.status}}</p>
</li>
<li ng-show="Data2">
<div ng-show="!notificationDataDashord.length">
<span>No Notifications</span>
</div>
</li>
</ul>
<dir-pagination-controls auto-hide="true"></dir-pagination-controls>
Inside the controller:
$scope.Data1 = true;
$scope.Data2 = false;
I am using pagination directive from this link:
https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination
Its a problem with the dirpagination that it doesnt update the collections after you load the data again.
See
https://github.com/michaelbromley/angularUtils/issues/208
https://github.com/michaelbromley/angularUtils/issues/137
As a work around obviously
<dir-pagination-controls ng-show="Data1" auto-hide="true"></dir-pagination-controls>

Change list item active bg-color with ng-click

I am a little lost with this issue.
When I click on the - a href tag - i want the li active background color to change to a specific color that I have stored in each object - like so obj.color" = #5c6bc0.
<li ng-repeat="obj in tags" ng-class="{active: obj.id == tagStates.activeItemID}">
<a href ng-click="tagStates.activeItemID = obj.id;">
{{obj.name}}
</a>
</li>
How can I do this? I have tried with ng-style - ng-style="{'active':'background-color': obj.color} but that didn't work.
Thanks
You can do something like
<li ng-repeat="obj in tags" ng-class="{active: obj.id == tagStates.activeItemID}" ng-style={backgroundColor: obj.id == tagStates.activeItemID ? obj.color : ''}">
<a href ng-click="tagStates.activeItemID = obj.id;">
{{obj.name}}
</a>
</li>
angular
.module('app', [])
.controller('Ctrl', function() {
this.tags = [
{ name: 'bob' },
{ name: 'rick' },
{ name: 'dave' }
];
})
<body ng-controller="Ctrl as vm">
<ul>
<li ng-repeat="obj in vm.tags" ng-class="{'active': vm.active == obj.name}">
<a ng-click="vm.active = obj.name">{{obj.name}}</a>
</li>
</ul>
{{vm.active}}
</body>
https://plnkr.co/edit/wvKIUtJIb0AE1vpWDtv9?p=preview

angular ng-repeat with some logic

I have this object
recipe = {
name : $scope.name,
ingredients : $scope.ingredients
}
I save ingredients in two different ways, that are
ingredients1 = [{ingredient : 'berry'}, {ingredient : 'honey'}]
ingredients2 = ['berry', 'honey'];
In ng-repeat I need to past ingredient depending on the condition;
//ingredients1
<li ng-repeat="ingr in recipe.ingredients track by $index">
<b>{{ingr}}</b>
</li>
//ingredients2
<li ng-repeat="ingr in recipe.ingredients track by $index">
<b>{{ingr.ingredients}}</b>
</li>
Can I make 1 ng-repeat for this two situations, with some conditional statements like if or else?
If ingr.ingredient is defined then bind it, else bind ingr, i.e.:
{{!!ingr.ingredient ? ingr.ingredient : ingr}}
Try with this code:
angular.module('myApp', [])
.controller('MyCtrl', function($scope, $http) {
var myScope = this;
myScope.ingredients = [{
ingredient: 'berry'
}, {
ingredient: 'honey'
}, 'berry', 'honey'];
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<ul ng-app="myApp" ng-controller="MyCtrl as c">
<li ng-repeat="ingr in c.ingredients track by $index">
<b>{{!!ingr.ingredient ? ingr.ingredient : ingr}}</b>
</li>
</ul>
If you know that you'll never have a third variation you could do
<li ng-repeat="ingr in recipe.ingredients track by $index">
{{ingr.ingredient || ingr}}
</li>
However, this is not that maintainable. I think it might be cleaner to delegate this logic to a helper function.
<li ng-repeat="ingr in getIngredients(recipe.ingredients)">
{{ingr}}
</li>
function getIngredients(ingredients) {
// Logic to flatten your mix of objects and strings
}
This would allow you to add/change the model of recipe ingredients while also creating logic that can be separately unit tested
There are couple of ways, all are worked listed down here.
Here is a Plunkr
angular.module('myApp',[])
.controller('myCtrl', function($scope){
$scope.array1 = [{ingredient : 'berry'}, {ingredient : 'honey'}]
$scope.array2 = ['berry', 'honey'];
$scope.array3 = [{ingredient : 'berry'}, {ingredient : 'honey'}, 'berry', 'honey'];
});
<h1>array 1</h1>
<li ng-repeat="ingr in array1">
<b>{{ ingr.ingredient || ingr }}</b>
</li>
<h1>array 2</h1>
<li ng-repeat="ingr in array2">
<b>{{ ingr.ingredient ? ingr.ingredient : ingr }}</b>
</li>
<h1>array 3</h1>
<li ng-repeat="ingr in array3">
<b>{{ ingr.ingredient || ingr }}</b>
</li>
<li ng-repeat="ingr in array3">
<b>{{ ingr.ingredient ? ingr.ingredient : ingr }}</b>
</li>

Filter matched elements by class name in Angular js.

Problem:
I have an unordered list of items which are returned from a json call and are output using ng-repeat. Each one of these items has a class name (there are about 9 categories).
I have a second unordered list which is simply a list of available categories.
Aim:
I want to be able to select one of the categories in the right hand list, which will apply a filter to the actual list of returned elements. This should be activated via a toggle (so click once: filtered, click again: filter removed). So it is simply looking to match the classname in the clicked element, to the elements that share the same classname in the list of json data.
I cannot use ng-model (as this is reserved for certain form elements).
For my jsfiddle I am simply using static html.
Here is my angular code:
/* angular custom filter on returned ajax api data */
var app = angular.module('app', []);
app.controller('main', function($scope) {
$scope.chFilters = {};
$scope.links = [
{name: 'atm'},
{name: 'internet'},
{name: 'mobile'},
{name: 'sms'},
{name: 'postal'}
];
$scope.channels = ["ATM", "INTERNET", "SMS", "POSTAL","MOBILE"];
});
(this is based on another question I found on SO). Unfortunately the fiddle is a bit messy and has some extraneous code in it.
HTML:
<div ng-app="app">
<div ng-controller="main">
<ul>
<li class="atm">Some stuff ATM</li>
<li class="internet">Some stuff INTERNET</li>
<li class="sms">Some stuff ATM</li>
<li class="atm">Some stuff ATM</li>
<li class="postal">Some stuff POSTAL</li>
<li class="atm">Some stuff ATM</li>
<li class="internet">Some stuff INTERNET</li>
<li class="postal">Some stuff POSTAL</li>
<li class="postal">Some stuff POSTAL</li>
<li class="atm">Some stuff ATM</li>
<li class="sms">Some stuff SMS</li>
<li class="mobile">Some stuff MOBILE</li>
<li class="internet">Some stuff INTERNET</li>
<li class="mobile">Some stuff MOBILE</li>
</ul>
<ul class="channel-filters">
<li ng-repeat="link in links | filter:chFilters" class="{{link.name | lowercase}}"><a ng-click="chFilters.name = link.name">{{link.name | uppercase}}</a></li>
<li class="last" ng-click="chFilters.name = ''">CLEAR FILTER</li>
</ul>
<ul>
<li ng-repeat="channel in channels | filter:chFilters">
<strong>{{channel}}</strong>
<a ng-click="chFilters = channel">{{channel}}</a>
</li>
</ul>
<!-- original -->
<ul>
<li ng-repeat="link in links | filter:chFilters">
<strong>{{link.name}}</strong>
<a ng-click="chFilters.name = link.name">{{link.name}}</a>
</li>
</ul>
</div>
</div>
This is the actual HTML from the application (with the call to the api).
<ul class="accordion">
<li class="search-text-channel">
<input type="textarea" ng-model="searchTextChannel.$" placeholder="Search"/>
</li>
<li ng-repeat="day in interactions.model.byDay | filter:searchTextChannel" ng-click="hidden = !hidden" ng-init="hidden = false" class="{{day.channel | removeSpace | lowercase}}" ng-class="{'closed': !hidden, 'open': hidden}">
<span class="date">{{day.date}}</span>
<span class="subheading">{{day.channel}}</span>
<ul ng-show="hidden">
<li ng-repeat="interaction in day.interactions">
{{interaction.time}} {{interaction.description | removeUnderscore}}
</li>
</ul>
</li>
<li class="load-more">
<i class="fa fa-plus"></i>LOAD MORE
</li>
</ul>
I have managed to recreate this functionality in jquery, but I think it would be better to implement an angular solution in an angular application.
I've tried researching and also attempted to implement show/hide as well as a custom filter, but so far no joy.
Here is my (messy) jsfiddle
<ul>
<li ng-repeat="channel in channels | filter:chFilters.name">
<strong>{{channel}}</strong>
<a ng-click="chFilters = channel">{{channel}}</a>
</li>
</ul>
<!-- original -->
<ul>
<li ng-repeat="link in links | filter:chFilters.name">
<strong>{{link.name}}</strong>
<a ng-click="chFilters.name = link.name">{{link.name}}</a>
</li>
</ul>
Update Plunker
Let me know if you have any question on this.
Here is part of the solution:
Suppose your items look like this:
$scope.items = [
{ class: "atm", label: "Some stuff ATM" },
{ class: "internet", label: "Some stuff INTERNET" },
{ class: "sms", label: "Some stuff SMS" },
{ class: "postal", label: "Some stuff POSTAL" },
...
];
To show a filtered list (only filtering by a single channel for now): create a separate list in the scope, with the filters applied:
$scope.click = function(name) {
$scope.chFilters.name = name;
$scope.filteredItems = $scope.items.filter(function(item) {
return item.class === $scope.chFilters.name;
});
};
Call this click handler from the bottom list:
...<a ng-click="click(link.name)">{{link.name | uppercase}}</a>....
And show filteredItems in the top list:
<ul>
<li ng-repeat="item in filteredItems" ng-class="item.class">{{item.label}}</li>
</ul>
So this is really just a starting point, it should be extended to handle multiple filters, etc...

Categories