Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular: Reinclude null values when filter parameter is empty

Tags:

angularjs

I have a pretty simple textbox filtering an ng-repeat on some unordered lis. When I add a value to the textbox the items with the null values are removed and do not return even when the textbox is cleared. I have an idea of why this is happening (the search object now has an empty property which doesn't match the nulls), but I cannot figure out how to solve the problem. I've tried to pop() the property off of the search object with no luck.

HTML:

<div ng-controller="ListCtrl">
    <input type="text" ng-model="search.age" placeholder="Age"></input>
    <ul>
        <li ng-repeat="item in items | filter:search">
            {{item.name}} - {{item.age}}
        </li>
    </ul>
</div>

JS:

function ListCtrl($scope) {
  $scope.items = [
    {'name':'Carl', 'age':69},
    {'name':'Neil', 'age':54},
    {'name':'Richard'},
    {'name':'Chris', 'age':58}
  ];
}

Please checkout the JSfiddle to better illustrate the issue.

like image 807
Jesse Avatar asked Dec 25 '22 12:12

Jesse


2 Answers

I figured it out with the help of this answer. If I just add an ng-change to the textbox I can watch for an empty value and delete the property.

HTML:

<input type="text" ng-model="search.age" ng-change="clear()" placeholder="Age"></input>

JS:

$scope.clear = function(){
    if($scope.search.age.length == 0){
        delete $scope.search.age;
    }
}

Updated fiddle. I am aware the current if prevents a user from filtering on a single space, but so far this does not seem to cause a problem for me.

BONUS: ! will return all null values and !! will return all not null values.

like image 55
Jesse Avatar answered Dec 28 '22 06:12

Jesse


The cleanest solution I have found is writing a custom directive to modify the input field behaviour like this:

app.directive('deleteIfEmpty', function () {
    return {
        restrict: 'A',
        scope: {
            ngModel: '='
        },
        link: function (scope, element, attrs) {
            scope.$watch("ngModel", function (newValue, oldValue) {
                if (typeof scope.ngModel !== 'undefined' && scope.ngModel.length === 0) {
                    delete scope.ngModel;
                }
            });
        }
    };
});

And use it as follows:

 <input type="text" ng-model="filter" delete-if-empty>
like image 34
Ben Torfs Avatar answered Dec 28 '22 05:12

Ben Torfs