Jack Slingerland
Jack Slingerland

Reputation: 2811

Knockout JS: Filtering a list unable to bind

I'm having a hard time getting a filter working. I'm roughly following the example at http://www.knockmeout.net/2011/06/10-things-to-know-about-knockoutjs-on.html, but I just can't seem to make it work. Any help is greatly appreciated.

HTML:

<h1><b>Medical Product Survey</b></h1>
<div class='facilities available'>
    <div class='bar'>
        <h2>Hospitals / Facilities</h2>
        <a class='button add'>+</a>
    </div>
    <table>
        <thead>
            <tr>
                <th>
                    <input data-bind="value: filter, valueUpdate: 'afterkeydown'" />
                </th>
                <th>Modified</th>
                <th>Status</th>
            </tr>
        </thead>
        <tbody data-bind="template: { name: 'facilitiesAvailableRow', foreach: filteredFacilties }"></tbody>
    </table>

    <!-- Row template for available facilities -->
    <script type="text/html" id="facilitiesAvailableRow">
        <tr>
            <td>${name}</td>
            <td>${modified}</td>
            <td>${status}</td>
        </tr>
    </script>
</div>

<div class='facilities available'>
    <div class='bar'>
        <h2>Archived</h2>
    </div>
    <table>
        <thead>
            <tr>
                <th><input type='search' id='facility_search' /></th>
                <th>Archive Date</th>
                <th>Size</th>
                <th></th>
            </tr>
        </thead>
        <tbody data-bind="template: { name: 'facilitiesArchivedRow', foreach: facilitiesArchived }"></tbody>
    </table>

    <!-- Row template for available facilities -->
    <script type="text/html" id="facilitiesArchivedRow">
        <tr>
            <td>${name}</td>
            <td>${modified}</td>
            <td>${size}mb</td>
            <td><input type='button' value='restore' /></td>
        </tr>
    </script>
</div>

Javascript:

//Model for facilities interaction on the front page.
var viewModel = {
    facilitiesAvailable: ko.observableArray([
        { name: "Test 1", modified: "1/20/1986", status: "Good to go" },
        { name: "Test 2", modified: "1/21/1987", status: "Good to go2" },
        { name: "Test 3", modified: "1/22/1988", status: "Good to go3" },
        { name: "Test 4", modified: "1/23/1989", status: "Good to go4" },
        { name: "Test 5", modified: "1/24/1990", status: "Good to go5" }
    ]),
    facilitiesArchived: ko.observableArray([
        { name: "Archive 1", modified: "1/20/1982", size: 123 },
        { name: "Archive 2", modified: "1/21/1983", size: 198 },
        { name: "Archive 3", modified: "1/22/1984", size: 340 }
    ]),
    filter: ko.observable(""),
};

//Filtering.
viewModel.filteredFacilities = ko.dependentObservable(function() {
    var filter = this.filter().toLowerCase();

    if(!filter) {
        return this.facilitiesAvailable();
    } else {
        return ko.utils.arrayFilter(this.facilitiesAvailable(), function(item) {
            if(item.name.toLowerCase().search(filter) != -1) {
                return true;
            }
        });
    }
}, viewModel);

ko.applyBindings(viewModel);

The error I'm getting is:

Uncaught Error: Unable to parse binding attribute.
Message: ReferenceError: filteredFacilties is not defined;
Attribute value: template: { name: 'facilitiesAvailableRow', foreach: filteredFacilties }

Upvotes: 4

Views: 5228

Answers (1)

Sean Vieira
Sean Vieira

Reputation: 160033

You misspelled filteredFacilties. It should be filteredFacilities in your template binding.

Change:

data-bind="template: { name: 'facilitiesAvailableRow', foreach: filteredFacilties }"

to:

data-bind="template: { name: 'facilitiesAvailableRow', foreach: filteredFacilities }"

Upvotes: 6

Related Questions