Touchout
Touchout

Reputation: 31

Angularjs filter allow null value using custom comparator not working?

[Revised] I find out a solution to deal with that, just use AngularJs with ver. >= 1.3.6, items with null property will not be dropped after applying a filter and cancel it!!

following is original question

Hi, all. im using AngularJs to display data in a table with ng-repeat directive, and a textbox to filter "Color" property of cats. notice that some cat has null Color property.

Once i type some text in the textbox and clear it, all cat with color property is null are gone.

I set a custom comparator returning true on expected === '', but it doesn't work. actually, all cat with color property === null will never shown once the searching textbox has been placed some text into and been cleared afterward even i let the comparator always return true.

Is there any way to allow null values when using a filter in ng-repeat? thank you inadvance!!

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 comparator following not working, once the searching textbox has been placed some text into and been cleared afterward, all cat with color property === null will never 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;
  };

Upvotes: 3

Views: 2067

Answers (3)

DoctorMick
DoctorMick

Reputation: 6793

A different approach is to use a filter function, compare against the entire object rather than the property and attach the criteria to the controller scope.

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 an updated fiddle: http://jsfiddle.net/gLL7wvcL/3/

Upvotes: 0

dfsq
dfsq

Reputation: 193301

The problem here is that after you clear the input, filter model looks like this:

{"Color": ""}

so empty string will not match colors with color null. What you just need to do is to remove "Color" property if it's null, maybe on change. In this case you will not need myComparator at all:

$scope.clear = function() {
    if ($scope.search.Color === null) {
        delete $scope.search.Color;
    }
};

and you would use just

ng-repeat="cat in cats | filter:search"

Demo: http://plnkr.co/edit/MrvBa09y9SrE3TlTUxP6?p=preview

Upvotes: 1

mersadk
mersadk

Reputation: 337

if (expected === '') will check for empty string, not null.

Try replacing it with

if (!expected) .....

Upvotes: -1

Related Questions