title: Adding and removing multiple filters in Knockout JS
body: <p>I'd like for my users to not only be able to use multiple filters, but to click an active filter to remove it. Right now, filters only work one at a time and there is no way to remove a filter other than clicking "show all". I'm fairly sure the answer is to use a ko.observableArray to store the filters, add or remove them as appropriate, and loop through them with filteredPeople. Unfortunately, my attempts at this solution did not work as planned, so I'm turning towards SO for help.</p>
  
  <p>Here is a JSFiddle with working code: <a href="http://jsfiddle.net/rrahlf/EZUEF/6/" rel="nofollow">http://jsfiddle.net/rrahlf/EZUEF/6/</a></p>
  
  <p>And this is my Knockout code:</p>
  
  <pre><code>var viewModel = function(){
      var self = this;
      self.people = ko.observableArray([
          {firstName:'James',lastName:'Smith',age:38},
          {firstName:'Susan',lastName:'Smith',age:36},
          {firstName:'Jeremy',lastName:'Smith',age:10},
          {firstName:'Megan',lastName:'Smith',age:7},
          {firstName:'James',lastName:'Jones',age:40},
          {firstName:'Martha',lastName:'Jones',age:36},
          {firstName:'Peggy',lastName:'Jones',age:10}
      ]);
  
      self.headers = [
          {title:'First Name',sortPropertyName:'firstName', asc: true, active: false},
          {title:'Last Name',sortPropertyName:'lastName', asc: true, active: false},
          {title:'Age',sortPropertyName:'age', asc: true, active: false}
      ];
      self.filters = [
          {title:'Show All', filter: null},
          {title:'Only Smith', filter: function(item){return item.lastName == 'Smith';}},
          {title:'Only Jones', filter: function(item){return item.lastName == 'Jones';}},
          {title:'Only Adults', filter: function(item){return item.age &gt;= 18; }}
      ];
  
      self.activeSort = ko.observable(function(){return 0;}); //set the default sort
      self.sort = function(header, event){
          //if this header was just clicked a second time
          if(header.active) {
              header.asc = !header.asc; //toggle the direction of the sort
          }
          //make sure all other headers are set to inactive
          ko.utils.arrayForEach(self.headers, function(item){ item.active = false; } );
          //the header that was just clicked is now active
          header.active = true;//our now-active header
  
          var prop = header.sortPropertyName;
          var ascSort = function(a,b){ return a[prop] &lt; b[prop] ? -1 : a[prop] &gt; b[prop] ? 1 : a[prop] == b[prop] ? 0 : 0; };
          var descSort = function(a,b){ return a[prop] &gt; b[prop] ? -1 : a[prop] &lt; b[prop] ? 1 : a[prop] == b[prop] ? 0 : 0; };
          var sortFunc = header.asc ? ascSort : descSort;
  
          //store the new active sort function
          self.activeSort(sortFunc);
      };
  
      self.activeFilter = ko.observable(self.filters[0].filter);//set a default filter    
      self.setActiveFilter = function(model,event){
          self.activeFilter(model.filter);
      };
  
      self.filteredPeople = ko.computed(function(){
          var result;
          if(self.activeFilter()){
              result = ko.utils.arrayFilter(self.people(), self.activeFilter());
          } else {
              result = self.people();
          }
          return result.sort(self.activeSort());
      });
  }
  
  ko.applyBindings(new viewModel());
  </code></pre>
  
  <p>HTML</p>
  
  <pre><code>&lt;div data-bind="foreach: filters"&gt;
  &lt;input type="button" data-bind="click: $parent.setActiveFilter, value: title"/&gt;
  &lt;/div&gt;
  
  &lt;br/&gt;
  
  &lt;table&gt;
  &lt;thead&gt;
      &lt;tr data-bind="foreach: headers"&gt;
          &lt;th data-bind="click: $parent.sort, text: title"&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
      &lt;tbody data-bind="foreach: filteredPeople"&gt;
          &lt;tr&gt;
              &lt;td data-bind="text: firstName"&gt;&lt;/td&gt;
              &lt;td data-bind="text: lastName"&gt;&lt;/td&gt;
              &lt;td data-bind="text: age"&gt;&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
  &lt;/table&gt;
  </code></pre>