AngularJS ng-repeat filter based on select option

user1159790 picture user1159790 · May 30, 2013 · Viewed 10.3k times · Source

I am new to AngularJS. I am trying to filter the data set shown based on the option selected with a select box.

<div ng-controller="CurrentTrandetailsController">
   <div>
      <div class="pull-right">
         <label for="show-filter" class="show-label">Show </label>
         <select name="show-filter" ng-model="searchText.accruedcard" id="show-filter" ng-options="trandetail.accruedcard as trandetail.accruedcard for trandetail in currentTrandetails.trandetails ">
            <option value="">All</option>
         </select>
      </div>
      <h3>Current trandetails</h3>
   </div>
   <div>
      <table class="table table-striped table-hover">
         <tbody>
            <tr ng-repeat="trandetail in currentTrandetails.trandetails | filter:searchText">
               <td>{{trandetail.dateAccrued}}</td>
               <td>{{trandetail.accruedcard}}</td>
               <td>{{trandetail.placeAccrued}}</td>
               <td>{{trandetail.discountcents}}</td>
               <td>{{trandetail.shortExpiryDate}}</td>
            </tr>
         </tbody>
      </table>
   </div>
</div>

I used the example given in http://docs.angularjs.org/api/ng.filter:filter, which uses an input box to filter. On selecting a given card, it seems to filter fine. However, when I select "All", which has its value set to "", it doesn't display all the entries (clear the filter). However, in the example shown, when the text box is cleared, all the entries are displayed.

What am I doing wrong?

Answer

Dan picture Dan · May 30, 2013

You'll need to change your select to:

<select name="show-filter"  ng-model="searchText" ...

instead of

<select name="show-filter"  ng-model="searchText.accruedcard" ...

Explanation: From what I've seen, it's not common to use a hard-coded option along with ng-options and this is contributing to the problem. The filter uses the select's model, which currently is an object instead of a string as in the Angular example. Object patterns are okay but in this case the object's properties become null when All is selected because it is not wired into the select the same way as the rest of the options.

This is what causes the searchText filter to fail because it expects valid strings (even when using an object for the matching pattern).

By using a string primitive for the select's model, the All 'hack' is preserved because it causes the select's model to become ('') instead of null, which will match everything and all the results are shown.