mardi 24 janvier 2017

AngularJS filter items by array of properties (checkbox)

I would like to filter the results by multiple properties. My code:

(function () {
'use strict';
        angular.
        module('myApp', []).
    filter('byFeatures', byFeatures).
        controller('MyCtrl', MyCtrl);
  function byFeatures() {
        return function(items, conditions) {
        if (Object.getOwnPropertyNames(conditions).length === 0) {
        return items;
      }
       var filtered = [];
       for (var i = 0; i < items.length; i++) {
                var item = items[i];
          angular.forEach(item.features, function (feature) {
                if (conditions[feature.name] !== undefined && conditions[feature.name][feature.value] !== undefined) {
              if (conditions[feature.name][feature.value]) {
                //filtered.push(item);
                filtered[item.id] = item;
              }
            }
          });
       }
       //console.log(filtered);
       return filtered;
    };
        };
        function MyCtrl ($scope, $filter) {
                        $scope.allProducts = [
                        {
        id: 0,
        name: "Product A", 
        features: [
                {name: "Brand", value: "Apple"},
          {name: "Memory", value: "16"},
          {name: "Color", value: "Black"}
        ]
      },
                        {
        id: 1,
        name: "Product B", 
        features: [
                {name: "Brand", value: "Apple"},
          {name: "Memory", value: "32"},
          {name: "Color", value: "Black"}
        ]
      },
      {
        id: 2,
        name: "Product C", 
        features: [
                {name: "Brand", value: "Nokia"},
          {name: "Memory", value: "16"},
          {name: "Color", value: "Black"}
        ]
      },
      {
        id: 3,
        name: "Product A", 
        features: [
                {name: "Brand", value: "Samsung"},
          {name: "Memory", value: "16"},
          {name: "Color", value: "Black"}
        ]
      },
    ];
    $scope.filters = [
        {
        name: "Brand",
        values: [
                "Apple",
          "Nokia",
          "Samsung",
        ]
      },
      {
        name: "Memory",
        values: [
                "16",
          "32",
        ]
      },
    ];
    $scope.currentFilter = {};
    $scope.$watch('currentFilter', function (newValue, oldValue, scope) {
        //console.log(newValue);
        
                        $scope.products = $filter('byFeatures')($scope.allProducts, newValue);
        }, true);
    
  };
}());
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta name="robots" content="noindex, nofollow">
  <meta name="googlebot" content="noindex, nofollow">
  <script src="http://ift.tt/1Re4n6G"></script>
  <title></title>
</head>

<body ng-app="myApp" class="ng-scope">
  <div ng-controller="MyCtrl" style="width: 100%;">
    
    <div style="width: 50%; float: left;">
      <h2>Available Phones</h2>
      <div ng-repeat="product in products">
        <h3>
          
        </h3>
        <ul>
          <li ng-repeat="feature in product.features">
             : 
          </li>
        </ul>
       </div>
    </div>
    <div style="width: 50%; float: left;">
      <h2>Filters</h2>
      <pre></pre>
      <div ng-repeat="filter in filters">
        <span></span>
        <ul>
          <li ng-repeat="value in filter.values">
            <input type="checkbox" ng-model="currentFilter[filter.name][value]"> <br>
          </li>
        </ul>
      </div>
    </div>
</div>


</body></html>

If i filter by brand "Apple" are displayed 2 phones with brand "apple" (16 and 32 memory) - its ok. But if i add second filter by memory "16" - will must display only 1 phone apple with memory "16". How to do it? . Link to JSFiddle




Aucun commentaire:

Enregistrer un commentaire