简体   繁体   中英

angularjs multiple checkbox filtering

I'm wanting to filter on multiple checkboxes but I'm only able to select one at a time. Not sure how to structure this so I can filter on all values.

I've created a fiddle , any help is appreciated.

<input type="checkbox" id="cb" ng-model="word"  ng-true-value="has kitchen" ng-false-value="">

Jimi

The main issue with not being able to select both checkboxes simultaneously is because they are both bound to the same model property.

As previously stated you had some other declarative issues with the filter, but I think creating a custom filter is probably overkill for your needs anyway.

My approach would be to create an array of options that tracks each selection individually:

  $scope.options = [
  { 
    name: 'has kitchen', 
    selected: false 
  }, { 
    name: 'has bakery', 
    selected: false 
  }];

and iterate over them to build your checkboxes

<label ng-repeat="option in options">
   <input type="checkbox" ng-model="option.selected"/>{{option.name}}
</label>

Then to make things a bit more clear (and avoid some unnecessary nesting), we can simplify the model you're working with to this

  $scope.data = [{
    "name" : "one",
    "services" : ["has bakery", "has dispensary"],
    "address" : "21 regent st chippendale"
  },{
    "name" : "two",
    "services" : ["has bakery", "has dispensary", "has food hall", "has kitchen"],
    "address" : "25 regent st chippendale"
  },{
    "name" : "three",
    "services" : ["has food hall", "has kitchen"],
    "address" : "25 regent st chippendale"
  }];

You can use a simple controller function to provide the filtering

<ul>
  <li ng-repeat="item in data | filter:itemFilter">{{item.name}}</li>
</ul>

The filter function gets called once for each item and returns true if that item has all of the selected options, and false otherwise.

  $scope.itemFilter = function(item) {
    var filters = $scope.options.filter(function(element, idx, array) {
      return element.selected;
    }) || [];

    var matched = true;
    filters.forEach(function(option) {
      matched = matched && item.services.indexOf(option.name) >=0;
    })
    return matched;
  };

Granted this is a simplified version of the matching logic (with the regular exp stuff removed), but it should demonstrate the mechanics and then you can take if from there.

Here's a working example http://plnkr.co/edit/nyBqQAHx8VgbNFICZMou

Edit

Here's another version that should work with your original json model

<ul>
  <li ng-repeat="item in data.list | filter:itemFilter">{{item.name}}</li>
</ul>

and the new filter function (not really elegant, but seems to work for the cases I tried)

  $scope.itemFilter = function(item) {
    var filters = $scope.options.filter(function(element, idx, array) {
      return element.selected;
    }) || [];

    var matched = true;
    filters.forEach(function(option) {
       var matchingService = item.services[0].services.filter(function(element, idx, array) {
         return element.serviceName == option.name;
       }) || [];
       matched = matched && matchingService.length > 0;
    });

    return matched;
  };

Updated example http://plnkr.co/edit/Wlk5wQdXS7OZhSNxhqOA

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM