Skip to content

Knockout.js Integration

drosen0 edited this page Oct 18, 2012 · 2 revisions

Example integration with Knockout.js

Mailing list thread: https://groups.google.com/forum/?fromgroups#!topic/select2/L4Alk72y3KQ

JSFiddle: http://jsfiddle.net/drosen/6XvqX/

Pasted code for posterity:

Markup

<h1>Single input[type=hidden]</h1>
<input type="hidden" data-bind="value: inputSingleState, select2: { allowClear: true, data: { results: states }, placeholder: 'Select a state' }, lookupKey: 'id'" style="width: 300px">
<div>
    Selected: <span data-bind="text: inputSingleState"></span>
</div>

<h1>Single select</h1>
<select data-bind="options: states, optionsValue: 'id', optionsText: 'text', value: selectSingleState" style="width: 150px"></select>
<select data-bind="options: states, optionsValue: 'id', optionsText: 'text', value: selectSingleState, select2: { }" style="width: 150px"></select>
<div>
    Selected: <span data-bind="text: selectSingleState"></span>
</div>

<h1>Multiple select</h1>
<select multiple="true" data-bind="options: states, optionsValue: 'id', optionsText: 'text', selectedOptions: selectMultipleStates, select2: { }" style="width: 300px"></select>
<div>
    Selected: <span data-bind="text: selectMultipleStates"></span>
</div>

<h1>Select within foreach</h1>
<ul data-bind="foreach: arrayOfStates">
    <li>
        <select data-bind="options: $parent.states, optionsValue: 'id', optionsText: 'text', optionsCaption: ' ', value: state, select2: { placeholder: ' ', allowClear: true }" style="width: 220px"></select>
        <button data-bind="click: $parent.removeState">Remove</button>
    </li>
</ul>
<button data-bind="click: addState">Add</button>
<div>
    Selected: <span data-bind="text: ko.toJSON(arrayOfStates())"></span>
</div>

<h1>Select data via ajax</h1>
<input type="hidden" data-bind="value: selectStateAjax, select2: { minimumInputLength: 1, query: stateQuery }" style="width: 300px">
<div>
    Selected: <span data-bind="text: selectStateAjax"></span>
</div>

JavaScript

ko.bindingHandlers.select2 = {
    init: function(element, valueAccessor, allBindingsAccessor) {
        var obj = valueAccessor(),
            allBindings = allBindingsAccessor(),
            lookupKey = allBindings.lookupKey;
        $(element).select2(obj);
        if (lookupKey) {
            var value = ko.utils.unwrapObservable(allBindings.value);
            $(element).select2('data', ko.utils.arrayFirst(obj.data.results, function(item) {
                return item[lookupKey] === value;
            }));
        }

        ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
            $(element).select2('destroy');
        });
    },
    update: function(element) {
        $(element).trigger('change');
    }
};

var StateItem = function(state) {
    this.state = ko.observable(state);
};

var ViewModel = function () {
    var self = this;
    this.states = [
        { id: "AL", text: "Alabama" },
        { id: "AK", text: "Alaska" },
        { id: "AZ", text: "Arizona" },
        { id: "AR", text: "Arkansas" },
        { id: "CA", text: "California" },
        { id: "CO", text: "Colorado" },
        { id: "CT", text: "Connecticut" },
        { id: "DE", text: "Delaware" },
        { id: "FL", text: "Florida" },
        { id: "GA", text: "Georgia" },
        { id: "HI", text: "Hawaii" },
        { id: "ID", text: "Idaho" },
        { id: "IL", text: "Illinois" },
        { id: "IN", text: "Indiana" },
        { id: "IA", text: "Iowa" },
        { id: "KS", text: "Kansas" },
        { id: "KY", text: "Kentucky" },
        { id: "LA", text: "Louisiana" },
        { id: "ME", text: "Maine" },
        { id: "MD", text: "Maryland" },
        { id: "MA", text: "Massachusetts" },
        { id: "MI", text: "Michigan" },
        { id: "MN", text: "Minnesota" },
        { id: "MS", text: "Mississippi" },
        { id: "MO", text: "Missouri" },
        { id: "MT", text: "Montana" },
        { id: "NE", text: "Nebraska" },
        { id: "NV", text: "Nevada" },
        { id: "NH", text: "New Hampshire" },
        { id: "NJ", text: "New Jersey" },
        { id: "NM", text: "New Mexico" },
        { id: "NY", text: "New York" },
        { id: "NC", text: "North Carolina" },
        { id: "ND", text: "North Dakota" },
        { id: "OH", text: "Ohio" },
        { id: "OK", text: "Oklahoma" },
        { id: "OR", text: "Oregon" },
        { id: "PA", text: "Pennsylvania" },
        { id: "RI", text: "Rhode Island" },
        { id: "SC", text: "South Carolina" },
        { id: "SD", text: "South Dakota" },
        { id: "TN", text: "Tennessee" },
        { id: "TX", text: "Texas" },
        { id: "UT", text: "Utah" },
        { id: "VT", text: "Vermont" },
        { id: "VA", text: "Virginia" },
        { id: "WA", text: "Washington" },
        { id: "WV", text: "West Virginia" },
        { id: "WI", text: "Wisconsin" },
        { id: "WY", text: "Wyoming" }
    ];

    this.inputSingleState = ko.observable("NM");

    this.selectSingleState = ko.observable();

    this.selectMultipleStates = ko.observableArray(["AK", "CO"]);

    this.arrayOfStates = ko.observableArray();
    this.addState = function () {
        self.arrayOfStates.push(new StateItem());
    };
    this.removeState = function (item) {
        self.arrayOfStates.remove(item);
    };

    this.selectStateAjax = ko.observable();
    this.stateQuery = function (query) {
        // build response for echoed ajax test
        var states = [];
        ko.utils.arrayForEach(self.states, function (state) {
            if (state.text.search(new RegExp(query.term, 'i')) >= 0) {
                states.push(state);
            }
        });
        $.ajax({
            url: '/echo/json/',
            type: 'POST',
            dataType: 'json',
            data: {
                json: JSON.stringify(states),
                delay: 1
            },
            success: function (data) {
                query.callback({
                    results: data
                });
            }
        });
    };
};

ko.applyBindings(new ViewModel());
Clone this wiki locally