filter function - computed from function

http://stackoverflow.com/questions/12026287/cache-computed-values-with-knockout

by rniemeyer

HTML

Match First: <input data-bind="value: firstNameContains, valueUpdate: 'afterkeydown'" /><hr/>
<ul data-bind="foreach: firstNameFiltered">
    <li data-bind="text: first"></li>
</ul>

<hr/>

Match Last: <input data-bind="value: lastNameContains, valueUpdate: 'afterkeydown'" /><hr/>
<ul data-bind="foreach: lastNameFiltered">
    <li data-bind="text: last"></li>
</ul>

JavaScript

var Person = function(id, first, last) {
   this.id = id;
   this.first = ko.observable(first);   
   this.last = ko.observable(last);
};

var ViewModel = function() {
    var self = this;
    this.people = ko.observableArray([
        new Person(1, "Bob", "Smith"),
        new Person(2, "Jon", "Johnson"),
        new Person(3, "Sarah", "Greene"),
        new Person(4, "Harold", "Washington"),
        new Person(5, "Jenny", "Samuelson")        
    ]);
    
    this.firstNameContains = ko.observable("o");
    this.lastNameContains = ko.observable("s");
        
    this.createFilter = function(prop, value) {
        return ko.computed(function() {
            var val = ko.utils.unwrapObservable(value).toUpperCase();
            return ko.utils.arrayFilter(self.people(), function(item) {
                return ko.utils.unwrapObservable(item[prop]).toUpperCase().indexOf(val) > -1;
            });        
         });
    }
        
    this.firstNameFiltered = this.createFilter('first', this.firstNameContains);
    this.lastNameFiltered = this.createFilter('last', this.lastNameContains);
};

ko.applyBindings(new ViewModel());