quickstep25
2/13/2015 - 9:22 PM

Bootstrap Select - Knockout 3.2 Custom Binding Example

Bootstrap Select - Knockout 3.2 Custom Binding Example

body {
  padding-top: 100px;
}
var jsonDATA = [{
    "id": "TMID-10",
        "text": "Gisela U. Mcclain"
}, {
    "id": "TMID-102",
        "text": "Mia O. Odom"
}, {
    "id": "TMID-106",
        "text": "Hu H. Johnson"
}, {
    "id": "TMID-110",
        "text": "Simone Lawson"
}, {
    "id": "TMID-114",
        "text": "Jorden Morin"
}, {
    "id": "TMID-118",
        "text": "Oscar Price"
}, {
    "id": "TMID-122",
        "text": "Heidi M. Henderson"
}, {
    "id": "TMID-126",
        "text": "Forrest F. Carter"
}, {
    "id": "TMID-130",
        "text": "Kameko Q. Cohen"
}, {
    "id": "TMID-134",
        "text": "Jade Merritt"
}, {
    "id": "TMID-138",
        "text": "Nichole D. Quinn"
}, {
    "id": "TMID-14",
        "text": "Abra D. Cooley"
}, {
    "id": "TMID-142",
        "text": "Brielle M. Weaver"
}, {
    "id": "TMID-146",
        "text": "Sasha Foster"
}, {
    "id": "TMID-150",
        "text": "Holly Sloan"
}, {
    "id": "TMID-154",
        "text": "Perry Chapman"
}, {
    "id": "TMID-158",
        "text": "Roary Ortiz"
}, {
    "id": "TMID-162",
        "text": "Josiah V. Marsh"
}, {
    "id": "TMID-166",
        "text": "Isabella Y. Romero"
}, {
    "id": "TMID-170",
        "text": "Chadwick X. Stuart"
}, {
    "id": "TMID-174",
        "text": "Wade Cole"
}, {
    "id": "TMID-178",
        "text": "Hyacinth Walters"
}];

ko.bindingHandlers.selectPicker = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        if ($(element).is('select')) {
            if (ko.isObservable(valueAccessor())) {
                if ($(element).prop('multiple') && $.isArray(ko.utils.unwrapObservable(valueAccessor()))) {
                    // in the case of a multiple select where the valueAccessor() is an observableArray, call the default Knockout selectedOptions binding
                    ko.bindingHandlers.selectedOptions.init(element, valueAccessor, allBindingsAccessor);
                } else {
                    // regular select and observable so call the default value binding
                    ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor);
                }
            }
            $(element).addClass('selectpicker').selectpicker();
        }
    },
    update: function (element, valueAccessor, allBindingsAccessor) {
        if ($(element).is('select')) {
            var selectPickerOptions = allBindingsAccessor().selectPickerOptions;
            if (typeof selectPickerOptions !== 'undefined' && selectPickerOptions !== null) {
                var options = selectPickerOptions.optionsArray,
                    optionsText = selectPickerOptions.optionsText,
                    optionsValue = selectPickerOptions.optionsValue,
                    optionsCaption = selectPickerOptions.optionsCaption,
                    isDisabled = selectPickerOptions.disabledCondition || false,
                    resetOnDisabled = selectPickerOptions.resetOnDisabled || false;
                if (ko.utils.unwrapObservable(options).length > 0) {
                    // call the default Knockout options binding
                    ko.bindingHandlers.options.update(element, options, allBindingsAccessor);
                }
                if (isDisabled && resetOnDisabled) {
                    // the dropdown is disabled and we need to reset it to its first option
                    $(element).selectpicker('val', $(element).children('option:first').val());
                }
                $(element).prop('disabled', isDisabled);
            }
            if (ko.isObservable(valueAccessor())) {
                if ($(element).prop('multiple') && $.isArray(ko.utils.unwrapObservable(valueAccessor()))) {
                    // in the case of a multiple select where the valueAccessor() is an observableArray, call the default Knockout selectedOptions binding
                    ko.bindingHandlers.selectedOptions.update(element, valueAccessor);
                } else {
                    // call the default Knockout value binding
                    ko.bindingHandlers.value.update(element, valueAccessor);
                }
            }

            $(element).selectpicker('refresh');
        }
    }
};

function ViewModel() {
    var self = this;
    self.teamItems = ko.observableArray(jsonDATA);
    self.BSteamMemberID = ko.observable(2);
    self.KOteamMemberID = ko.observable();
}

ko.applyBindings(new ViewModel());
<div class="container">
    <div class="row">
        <div class="col-sm-12">
            <div class="panel panel-primary">
                <div class="panel-heading">KnockoutJS 3.2: Bootstrap Select 1.6.3 Example</div>
                <div class="panel-body">
                    <form class="form-horizontal" role="form">
                        <div class="form-group">
                            <label class="col-sm-4 control-label">Select Team Member:</label>
                            <div class="col-sm-8">
                                <select class="form-control show-tick input-sm" data-bind="selectPicker: BSteamMemberID, optionsText: 'text', optionsValue : 'id', value: KOteamMemberID, selectPickerOptions: { optionsArray: teamItems }"></select>
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-sm-4 control-label">Bootstrap Select Observable Value:</label>
                            <div class="col-sm-8">
                                <p class="form-control-static"><span class="label label-primary" data-bind="text: BSteamMemberID"></span>

                                </p>
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-sm-4 control-label">KnockoutJS "Value" Observable Value:</label>
                            <div class="col-sm-8">
                                <p class="form-control-static"><span class="label label-info" data-bind="text: KOteamMemberID"></span>

                                </p>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

Bootstrap Select - Knockout 3.2 Custom Binding Example

Using KnockoutJS, I created a custom binding that enables the use of Bootstrap Select (selectpicker) jQuery plugin within a ViewModel

A Pen by Doug Hill on CodePen.

License.