AngularJS - custom filter with ngRepeat directive - angularjs

I would like to use my custom filter with ngRepeat directive. Here is what I have
HTML:
<div ng-app="menuApp">
<ul ng-controller="MenuCtrl">
<li ng-repeat="item in menuItems | rootCategories">
{{item.Name}}
</li>
</ul>
</div>
JS:
angular.module('menuApp', [])
.filter('rootCategories', function() {
return function(item) {
return item.Parent == 0;
};
});
function MenuCtrl($scope) {
$scope.menuItems = [{ "Id": 1, "Name": "Sweep", "Parent": 0 }];
/*
$scope.rootCategories = function(item) {
return item.Parent == 0;
};
*/
};
I do not want to use the commented out way to filter my items, because the real filter will be complicated than in the provided example. For some reasons input parameter "item" is not defined, therefore I see nothing. Could you tell me what is wrong? Thank you.

Please have a look at this fiddle. http://jsfiddle.net/bKFXy/.
This uses the syntax of passing a predicate object as the filter expression.
item in menuItems | filter:{Parent:0}
There is another method for filtering and the fiddle for that is here http://jsfiddle.net/kd5dv/

Related

angularjs : Why does the filter not work?

Please help fix the script.
html:
<li ng-repeat="date in dateArr | dateFormatter}">
<span class="date">{{date}}</span>
</li>
js:
angular.module('App', [])
.controller('lsController', function ($scope) {
$scope.dateArr = [
'10.10.2016',
'11.10.2016',
'12.10.2016',
'13.10.2016',
'14.10.2016',
'15.10.2016'
];
/*$scope.dateFormatter = function(date) {
return date.slice(0, 6);
}*/
})
.filter('dateFormatter', function (date) {
return date.slice(0, 6);
});
I use angular 1.4.8
JSFIDDLE
I need use filter, which cut the datestring
Your filter is not constructed properly.
A filter needs to return a function that contains the arguments for the filtering and returns the result
.filter('dateFormatter', function () {
return function(dateString){
return dateString.slice(0, 6);
}
});
Then you have this set to filter in the ng-repeat but putting it there it would need to return a filtered array, not a string input and manipulation. So it needs to be placed where you pass in a string
<li ng-repeat="date in dateArr">
<span class="date">{{date | dateFormatter}}</span>
</li>
DEMO
Your filter is wrong. Check de filter documentation for more details
.filter('dateFormatter', function () {
return function(date){
return date.slice(0, 6)
}
});
Also the way you use your filter is wrong. Take it out of ng-repeat
<span class="date">{{date | dateFormatter }}</span>
FIDDLE

AngularJS remove NULL from ng-repeat

I'm currently developing an AngularJS web application.
What I'm trying to achieve:
List each item using the ng-repeat method and remove any null values.
Correct - One, Two, Three, Four
Incorrect - One, Two, Three, Four, Null (empty ng-repeat item)
Current Problems:
I've tried several methods todo this, including using the ng-hide function and creating a array filter but I can't seem to get either working correctly.
Any help / advice would be helpful!
Array
[ "One", "Two", "Three", "Four", null ]
HTML:
<md-list>
<md-list-item class="md-3-line" ng-repeat="item in parseQ4P2 track by $index">
<div class="md-list-item-text">
<p>{{item}}</p>
</div>
<md-divider ng-if="!$last"></md-divider>
</md-list-item>
</md-list>
Failed Filter:
dashApp.filter('removeBlackItems', function() {
return function(inputArray) {
var outArray = [];
for (var i = 0; i < inputArray.length; i++) {
if(inputArray[i].length !== 0){
outArray.push(inputArray[i]);
}
}
return outArray;
};
});
You can filter data inside ng-repeat.
Try something like this: http://jsbin.com/sufexe/edit?html,js,output
HTML:
.filter('emptyFilter', function() {
return function(array) {
var filteredArray = [];
angular.forEach(array, function(item) {
if (item) filteredArray.push(item);
});
return filteredArray;
};
}
Controller JS:
.filter('emptyFilter', function() {
return function(array) {
var filteredArray = [];
angular.forEach(array, function(item) {
if (item) filteredArray.push(item);
});
return filteredArray;
};
}
Anwser URL - AngularJS remove empty value
as seen in ng-repeat filter null value not displaying there's no need for a custom filter. Ese angular's existing filter functionality to remove null objects from array in the template/view
<ul ng-repeat="item in items| filter:{item:'!'} track by $index">
<li>{{item.name}}</li>
</ul>

Using ng-repeat in order to iterate over object properties and ordering by value instead of key with ng 1.3

I am in reference to the angular documentation about ngRepeat and iterating over object properties which states:
<div ng-repeat="(key, value) in myObj"> ... </div>
You need to be aware that the JavaScript specification does not define
the order of keys returned for an object. (To mitigate this in Angular
1.3 the ngRepeat directive used to sort the keys alphabetically.)
Say I have the following object:
var myObj = {FOO: 0, BAR: 1};
and want it to be ordered by value (i.e. 0 & 1) instead of keys. How can this be achieved with angular? (I use angular 1.3 by the way).
I have tried:
ng-repeat="(key, value) in myObj | orderBy:value"
But it does not work...
Can anyone please help?
Just as with filter, orderBy works with arrays only. One simple solution is to use a function that returns an array from an object:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="namesCtrl">
<input type="text" ng-model="searchText"/>
<ul ng-init="nameArray=objArray(names)">
<li ng-repeat="x in nameArray | filter:searchText | orderBy: 'value.name'">
{{x.value.name}}
</li>
</ul>
</div>
<script>
angular.module('myApp', []).controller('namesCtrl', function($scope) {
$scope.searchText='';
$scope.names = {
"1": {
"name": "some"
},
"2": {
"name": "values"
},
"3": {
"name": "are"
},
"4": {
"name": "there"
},
"5": {
"name": "here"
}
};
$scope.objArray=function (obj) {
var result=[];
for (var key in obj) {
result.push({
key: key,
value: obj[key]
});
}
return result;
}
});
</script>
</body>
</html>
I believe the best and elegant solution is to make a filter that changes your object into an array. Therefore you can reuse it thought all your project in your template without coding any js.
Here is what the filter would look like:
(function () {
'use strict';
angular.module('app').filter('toArray', toArray);
toArray.$inject = [];
function toArray() {
return toArrayFilter;
function toArrayFilter(input) {
if (angular.isArray(input)) return input;
var list = [];
angular.forEach(input, iterateProperty, list);
return list;
function iterateProperty(elt, key) {
this.push({ key: key, value: elt });
}
}
}
})();
and here is how you would use it in your html template:
<div ng-repeat="element in myObject | toArray | orderBy:value">
{{element.key}}:
<pre>{{element.value | json}}</pre>
</div>

Disabling nesting filter in AngularJS

There is the following code:
tr ng-repeat="order in orders | filter: { restaurant: { id: currentRestaurant.id } } | orderBy:'-id'"
This code works good and filter orders by restaurant.id correctly. But I need to disable this filter in some case in order to show all orders. My controller code:
$scope.setCurrentRestaurant = (restaurant) ->
$scope.currentRestaurant = restaurant
I don't know how I can disable filtering programmatically or using filter directive. Thanks in advance.
If the filter parameter is undefined then it does not filter. If the filter parameter is the filtering expression, then it filters based on that.
So, you could introduce a filter expression like so:
"filter: (enableFilter || undefined) && {restaurant:{id:currentRestaurant.id}}"
plunker
I think that Angular doesn't contain native features for that.
But you can create custom solution for this case.
For example, you can broadcast event, when you want to disable filter. This event can be broadcasted from anywhere (service, directive, controller). For simplicity, here I've broadcasted it from controller.
Also I've created filterByRestaurant in the controller.
View:
<div ng-controller="MyCtrl">
<div ng-repeat="order in orders | filter:filterByRestaurant">
{{order.name}}
</div>
<button ng-if="enableFilter" ng-click="disableOrEnableFilter()">Disable filter</button>
<button ng-if="!enableFilter" ng-click="disableOrEnableFilter()">Enable filter</button>
</div>
Controller:
function MyCtrl($scope, $rootScope) {
$scope.enableFilter = true;
$scope.currentRestaurant = {id: 2, name: "Rest2"};
$scope.orders = [
{id:1, restId: 1, name: "order from Rest1"},
{id:2, restId: 2, name: "order from Rest2"},
{id:3, restId: 3, name: "order from Rest3"}
];
$scope.filterByRestaurant = function(order) {
return $scope.currentRestaurant.id == order.restId || !$scope.enableFilter;
};
$scope.$on('filter:disable', function() {
$scope.enableFilter = !$scope.enableFilter;
});
$scope.disableOrEnableFilter = function(){
$rootScope.$broadcast("filter:disable");
};
}
This is working JSFiddle with example.
Hope it will help.

Angular.js: filter ng-repeat by absence in array

I need to filter items in ng-repeat so that only the items which not appear in alreadyAddedValues() array will be shown:
<ul class="dropdown-menu">
<li ng-repeat="v in values() | filter: { ????? } ">{{value.name}}</li>
</ul>
$scope.values() = function(){
................
}
$scope.alreadyAddedValues() = function()
{
//returns an array
}
The search of an already added value should perform by value.shortName
You can, for example, use a custom function to do the filtering:
<li ng-repeat="v in values() | filter:filterAlreadyAdded ">{{value.name}}</li>
On the controller:
$scope.filterAlreadyAdded = function(item) {
// filter logic here...
// return false if item already added, true otherwise
};
jsfiddle: http://jsfiddle.net/bmleite/5VbCJ/

Resources