Search code examples
javascripthtmlangularjscheckboxangular-filters

How to use checkbox to filter results with Angular?


I am trying to apply a filter using checkboxes.

The checkboxes are shown correctly:

<div data-ng-repeat="cust in customers">
    <input type="checkbox" data-ng-model="search.city" data-ng-true-value="{{ cust.city }}" data-ng-false-value=""/> {{ cust.city }}
</div>

but when checking any checkbox, nothing happens:

<table>

    <!-- table heading goes here -->

    <tbody>
        <tr data-ng-repeat="customer in customers | filter : search">
            <td >
                {{ customer.firstName }}
            </td>
            <td >
                {{ customer.lastName }}
            </td>
            <td >
                {{ customer.address }}
            </td>
            <td >
                {{ customer.city }}
            </td>
        </tr>
    </tbody>
</table>

The table shows all the customers.

What I want to achieve is: when one or more checkboxes are checked, the table has to show only these rows which match the condition of the checked checkboxes.

What do I have to do to get this working?


Solution

  • It looks like you are providing a list of customers, and when one or more is selected, display a table of customers that are in the same city as those customers that are selected.

    To do this, you will need a custom filter:

    // Define our filter
    app.filter('selectedCustomerCities', function($filter) {
      return function(customers) {
        var i, len;
    
        // get customers that have been checked
        var checkedCustomers = $filter('filter')(customers, {checked: true});
    
        // Add in a check to see if any customers were selected. If none, return 
        // them all without filters
        if(checkedCustomers.length == 0) {
          return customers;
        }
    
        // get all the unique cities that come from these checked customers
        var cities = {};
        for(i = 0, len = checkedCustomers.length; i < len; ++i) {
          // if this checked customers cities isn't already in the cities object 
          // add it
          if(!cities.hasOwnProperty(checkedCustomers[i].city)) {
            cities[checkedCustomers[i].city] = true;
          }
        }
    
        // Now that we have the cities that come from the checked customers, we can
        //get all customers from those cities and return them
        var ret = [];
        for(i = 0, len = customers.length; i < len; ++i) {
          // If this customer's city exists in the cities object, add it to the 
          // return array
          if(cities[customers[i].city]) {
            ret.push(customers[i]);
          } 
        }
    
        // we have our result!
        return ret;
      };
    });
    

    Your markup will then change into something like this:

    <div data-ng-repeat="customer in customers">
      <!-- record that this customer has been selected -->
      <input type="checkbox" ng-checked="customer.checked" ng-model="customer.checked" /> {{ customer.city }}
    </div>
    
    <table>
      <!-- table heading goes here -->
      <tbody>
          <!-- use our custom filter to only display customers from the cities selected -->
          <tr data-ng-repeat="customer in customers | selectedCustomerCities">
              <td>{{ customer.firstName }}</td>
              <td>{{ customer.lastName }}</td>
              <td>{{ customer.address }}</td>
              <td>{{ customer.city }}</td>
          </tr>
      </tbody>
    </table>
    

    You can see it working at this Plunker: http://plnkr.co/edit/GlHRLKECR4jeBS7Vf7TX?p=preview