Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I know how to filter an array with an input text as the filter. Is it possible to use the filter property of angularjs with a combobox as the filter options?

For example, I have an array of years: [2014,2014,2013,1987,1987] I want to filter this array using a combobox with these values : {blank,2014,2013,1987} In this combobox, if I click on blank, the array displays the initial values, otherwise it displays the filtered values.

The code below doesn't allow me to re init the array if I click on the first option of the Select tag :

<select ng-model="search.date" ng-options="year for year in years">
        <option value=""></option>
</select>
<table class="table table-striped">
     <thead>
       <tr>
          <th>Label</th>
          <th>Categorie</th>
          <th>Montant</th>
          <th>Date</th>
       </tr>
     </thead>
     <tbody>
        <tr ng-repeat="budget in filteredBudgets | filter:search:strict">
          <td>{{budget.label}}</td>
          <td>{{budget.category}}</td>
          <td>{{budget.real}}</td>
          <td>{{budget.date}}</td>
        </tr>
     </tbody>
</table>

Thanks in advance.

share|improve this question
    
not clear, why not sharing your html and coded app so far –  Dalorzo May 21 at 16:47
    
my code : <select ng-model="search.date" ng-options="year for year in years"><option value=""></option> </select><br> <tr ng-repeat="budget in filteredBudgets | filter:search:strict">....</tr> sorry, i don't know how to go to next line with the short answer command. –  user1260928 May 21 at 17:02
    
you know you can edit your question and include there? –  Dalorzo May 21 at 17:06
add comment

1 Answer

up vote 1 down vote accepted

The problem is that once you select the empty option, the modelValue becomes null.
Thus, passing the object {date: null} to filter, it will try to much items with date: null.

To satisfy this specific requirement of yours (i.e. treat a null value in search as if it was not defined at all), you could define a function that receives an item and (based on the search object) determines if it should be filtered out or not.

Then you can use that predicate function as an argument to Angular's filter filter.

E.g.:

<tr ng-repeat="budget in filteredBudgets | filter:filterBySearch">

$scope.filterBySearch = function (item) {
    return Object.keys($scope.search || {}).every(function (key) {
        var value = $scope.search[key]; 
        return (value === undefined) || 
               (value === null) ||
               value === item[key];
    });
};

See, also, this short demo.


A slightly more complex demo is available here. It allows a strict parameter to be passed to the predicate function.


UPDATE

An alternative approach would be to implement a custom directive (and add it to the <select> element) with the following functionality:

It will watch for changes in the model-value and convert any null values to undefined.
This solves the problem, because if a property of search has a value of undefined it is as if it is not there at all.

E.g.:

<select ... null-is-undefined>...</select>

app.directive('nullIsUndefined', function () {
    return {
        restrict: 'A',
        require: 'ngModel',   // <-- this is required for accessing the ngModelController
        link: function postLink(scope, elem, attrs, modelCtrl) {
            modelCtrl.$parsers.push(function (newViewValue) {
                if (newViewValue === null) {
                    newViewValue = undefined;
                }
                return newViewValue;
            });
        }
    };
});

See, also, this short demo.

share|improve this answer
    
thanks a lot for your answer. Between your two solutions is there a best(proper) one? or are they equal? –  user1260928 May 22 at 12:18
    
Both are "proper" (they get the job done and are Angularish enough). The second one is more slightly more efficient I think (especially as the items list grows), but you need to make sure you are OK with the fact that there will be no way to set your model to null. –  ExpertSystem May 22 at 15:39
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.