StackOverflow_23983322: angularjs-checkbox-filter

Illustration of answer to http://stackoverflow.com/questions/23983322/angularjs-checkbox-filter.

by ExpertSystem

HTML

<script src="//code.angularjs.org/1.5.7/angular.min.js"></script>
<div ng-controller="WineCtrl as ctrl">
  <h3>Categories</h3>
  <div ng-repeat="category in ctrl.getCategories()">
    <label>
      <input type="checkbox" ng-model="ctrl.filter[category]" />
      {{ category }}
    </label>
  </div>
  <hr />
  <h3>Available Wines</h3>
  <div ng-repeat="wine in (ctrl.wines | filter:ctrl.filterByCategory) as filteredWines">
    {{ wine.name }} <i>({{ wine.category }})</i>
  </div>
  <hr />
  <b>Number of results: {{ filteredWines.length }}</b>
</div>

JavaScript

(function () {'use strict';

angular.
  module('myApp', []).
  controller('WineCtrl', WineCtrl);

// Functions - Definitions
function WineCtrl() {
  // Variables - Private
  var self = this;
  
  // Variables - Public
  self.filter = {};
  self.wines = [
    {name: 'Wine A', category: 'red'},
    {name: 'Wine B', category: 'red'},
    {name: 'Wine C', category: 'white'},
    {name: 'Wine D', category: 'red'},
    {name: 'Wine E', category: 'red'},
    {name: 'Wine F', category: 'white'},
    {name: 'Wine G', category: 'champagne'},
    {name: 'Wine H', category: 'champagne'}    
  ];
  
  // Functions - Public
  self.filterByCategory = filterByCategory;
  self.getCategories = getCategories;
  
  // Functions - Definitions
  function filterByCategory(wine) {
    return self.filter[wine.category] || noFilter(self.filter);
  }
    
  function getCategories() {
    return (self.wines || []).
      map(function (wine) { return wine.category; }).
      filter(function (cat, idx, arr) { return arr.indexOf(cat) === idx; });
  }

  function noFilter(filterObj) {
    return Object.
      keys(filterObj).
      every(function (key) { return !filterObj[key]; });
  }
}

}());