hufflapuff
hufflapuff

Reputation: 225

Knockout Search / Filter

I'm very new to Knockout JS and I'm having a hell of a time trying to get this project completed.

I've created a map website which displays a series of pins on the page for popular locations around town. The idea is that the search bar to the left of the page will filter out pins on the map with names that do not match the search query. There is also a "master" list on the left of the page that the search bar will filter from too.

I used an example I found on jsfiddle here: http://jsfiddle.net/mythical/XJEzc/ but I'm having troubles applying that same logic to my code.

Here it is:

HTML:

        <li>
            <input class="form-control" placeholder="Search…" type="search" name="filter" data-bind="value: query, valueUpdate: 'keyup'" autocomplete="off">
        </li>
        <ul data-bind="template: {name:'pin', foreach: pins}"></ul> 
    </ul>

<script type="text/html" id="pin">
    <li>
        <strong data-bind="text: name"></strong>
    </li>
</script>

JS:

self.pins = ko.observableArray([
  new self.mapPin("Anchorage Alaska", 61.190491, -149.868937, "test1"),
  new self.mapPin("Anchorage Alaska", 61.190491, -149.868937, "test2")
]);

self.query = ko.observable('');

self.filterPins = ko.dependentObservable(function () {
    var search = self.query().toLowerCase();
    return ko.utils.arrayFilter(name, function (pin) {
        return pin.toLowerCase().indexOf(search) >= 0;
    });
});

With the logic I've setup if the name is removed from the pin constructor it will remove it from the map.

Here is my somewhat working example: http://jamesiv.es/projects/map/

Upvotes: 1

Views: 8264

Answers (2)

Thuy Pham
Thuy Pham

Reputation: 57

Just want to update the code if using Knockout version newer than 3.2

Change from value and valueUpdate to textInput, as reccomended here

HTML:

<input class="form-control" placeholder="Search…" type="search" name="filter" data-bind="textInput: query" autocomplete="off" />

JS:

this.query = ko.observable('');

this.filteredPins = ko.computed(function () {
    if (this.query()) {
        var search = this.query().toLowerCase();
        return ko.utils.arrayFilter(this.pins(), function (pin) {
            return pin.name().toLowerCase().indexOf(search) >= 0;
        });
    } else {
        return pins
    }}, this);  

Upvotes: 1

Dion D.
Dion D.

Reputation: 2596

HTML

<ul data-bind="template: {name:'pin', foreach: pins}"></ul> 

change to

<ul data-bind="template: {name:'pin', foreach: filterPins}"></ul> 

Javascript

self.filterPins = ko.dependentObservable(function () {
    var search = self.query().toLowerCase();
    return ko.utils.arrayFilter(self.name, function (pin) {
        return pin.toLowerCase().indexOf(search) >= 0;
    });
});

change to

self.filterPins = ko.computed(function () {
    var search = this.query().toLowerCase();
    return ko.utils.arrayFilter(self.pins(), function (pin) {
        return pin.name().toLowerCase().indexOf(search) >= 0;
    });
});

Upvotes: 4

Related Questions