Angularjs filter allow null if custom comparator fails?
[Revised] I'll figure out how to solve this, just use AngularJs with ver. > = 1.3.6, items with a null property will not be removed after applying the filter and cancel it !!
next original question
Hi all. im using AngularJs to display data in a table with ng-repeat directive and a textbox to filter the cats 'Color' property. note that some cat has a Color property.
As soon as I type the text in the textbox and clear it, all the cat with color properties are null.
I've set up an arbitrary comparator returning true on expected === ''
, but it doesn't work. in fact, the whole cat with color property === null
will never show once the search text box is placed in some text and cleared after that, even if I let the comparator always return true.
Is there a way to allow null values ββwhen using a filter in ng-repeat? thanks!
JS Fiddle Demo: http://jsfiddle.net/gLL7wvcL/2/
my data (array of cats)
$scope.cats = [
{'Name': 'John',
'Sex': 'Male',
'Color': 'Black'},
{'Name': 'Rose',
'Sex': 'Female',
'Color': 'White'},
{'Name': 'Cindy',
'Sex': 'Female',
'Color': 'Yellow'},
{'Name': 'David',
'Sex': 'Male',
'Color': 'Black'},
{'Name': 'Garen',
'Sex': 'Male',
'Color': null},
{'Name': 'Jim',
'Sex': 'Male',
'Color': null},
{'Name': 'Charotte',
'Sex': 'Female',
'Color': 'Black'}
];
and both of the following comparators don't work, after the search textbox put some text in and was cleared after that, all cat with color property === null will never be shown.
$scope.myComparator = function (actual, expected)
{
if (expected === '')
return true;
else
{
var text = ('' + actual).toLowerCase();
return text.indexOf(expected) > -1;
}
};
$scope.myComparator = function (actual, expected)
{
return true;
};
source to share
The problem is that after clearing the input, the filter model looks like this:
{"Color": ""}
so an empty string will not match colors with color null
. You just need to remove the "Color" property if it null
is possible when changed. In this case, you do not need myComparator
:
$scope.clear = function() {
if ($scope.search.Color === null) {
delete $scope.search.Color;
}
};
and you just use
ng-repeat="cat in cats | filter:search"
Demo: http://plnkr.co/edit/MrvBa09y9SrE3TlTUxP6?p=preview
source to share
Another approach is to use a filter function, compare to a whole object rather than this property, and attach the criteria to the control area.
Markup:
<tr ng-repeat="cat in cats | filter:myComparator">
Controller:
$scope.myComparator = function (actual)
{
var expected = $scope.filter;
if (expected === '')
{
return true;
}
else
{
var text = ('' + actual.Color).toLowerCase();
return text.indexOf(expected) > -1;
}
};
Full example in updated script: http://jsfiddle.net/gLL7wvcL/3/
source to share