Chitrank Dixit
Chitrank Dixit

Reputation: 4051

Bootstrap-select with Knockout.js custom binding

I am making Add or Invite option on my site , I need to fetch first all the users of the site and show them either in typeahead or something like select picker option and as soon as the user is selected the user should be added to the invite list. That is something like trello invite to the board or organisation. See here trello: https://trello.com/

At the very basic step I am trying to use knockout live tutorial example list and collections example. (http://learn.knockoutjs.com/#/?tutorial=collections)

and Here is my code

HTML

<h2>Your seat reservations (<span data-bind="text: seats().length"></span>)</h2>
<button class="btn btn-deffault" data-bind="click: addSeat, enable: seats().length < 5">Reserve another seat</button>
<table>
    <thead><tr>
        <th>Passenger name</th><th>Meal</th><th>Surcharge</th><th></th>
    </tr></thead>
    <!-- Todo: Generate table body -->
    <tbody data-bind="foreach: seats">
        <tr>
            <td><input data-bind="value: name" /></td>
            <td><select class="selectpicker" data-bind="options: $root.availableMeals, value: meal, optionsText: 'mealName'" data-live-search="true"></select></td>
            <td><input data-bind="value: formattedPrice"></td>
            <td><a href="#" data-bind="click: $root.removeSeat">Remove</a></td>
        </tr>
    </tbody>
</table>
<h3 data-bind="visible: totalSurcharge() > 0">
    Total surcharge: $<span data-bind="text: totalSurcharge().toFixed(2)"></span>
</h3>

and here is knockout code

//custom binding for selectpicker

ko.bindingHandlers.selectPicker = {
        init: function (element, valueAccessor, allBindingsAccessor) {
            if ($(element).is('select')) {
                if (ko.isObservable(valueAccessor())) {
                    ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor);
                }
                $(element).selectpicker();
            }
        },
        update: function (element, valueAccessor, allBindingsAccessor) {
            if ($(element).is('select')) {
                var selectPickerOptions = allBindingsAccessor().selectPickerOptions;
                if (typeof selectPickerOptions !== 'undefined' && selectPickerOptions !== null) {
                    var options = selectPickerOptions.options,
                        optionsText = selectPickerOptions.optionsText,
                        optionsValue = selectPickerOptions.optionsValue,
                        optionsCaption = selectPickerOptions.optionsCaption;
                    if (ko.utils.unwrapObservable(options).length > 0) {
                        ko.bindingHandlers.options.update(element, options, ko.observable({ optionsText: optionsText, optionsValue: optionsValue, optionsCaption: optionsCaption }));
                    }
                }
                if (ko.isObservable(valueAccessor())) {
                    ko.bindingHandlers.value.update(element, valueAccessor);
                }
                $(element).selectpicker('refresh');
            }
        }
    };

function AllUsers(data){
    var self = this;
    self.name = name;
    self.meal = ko.observable(initialMeal);


    self.formattedPrice = ko.computed(function() {
        var price = self.meal().price;
        return price ? "$" + price.toFixed(2) : "None";        
    });

    self.formatPrice = ko.observable(self.formattedPrice());

    self.about_me = ko.observable(data.about_me);
    self.email = ko.observable(data.email);
    self.uname = ko.observable(data.uname);
    self.uuid = ko.observable(data.uuid);
    self.everyuser = [
     {aboutMe: self.about_me(), email: self.email(), name: self.uname, id: self.uuid()}
    ];

}

function PostViewModel() {
    var self = this;

    self.allusers= ko.observableArray([]);

    self.gert = [
        { mealName: "Standard (sandwich)", price: 0 },
        { mealName: "Premium (lobster)", price: 34.95 },
        { mealName: "Ultimate (whole zebra)", price: 290 }
    ];    



    $.getJSON('/users', function (json) {
        var t = $.map(json.users, function(item) {
            console.log("Something",item);

            return new AllUsers(item);
        });
        self.allusers(t);
    });


}

ko.applyBindings(new PostViewModel());

But the code is not working and not showing the options while using class selectpicker in HTML code, and if selectpicker is not used then the simple dropdown comes that should not come.

<td><select class="selectpicker" data-bind="options: $root.availableMeals, value: meal, optionsText: 'mealName'" data-live-search="true"></select></td>

anyone knowing about Knockout.js please help

Upvotes: 2

Views: 5434

Answers (1)

Michael Papworth
Michael Papworth

Reputation: 453

It appears that you are using the name of the custom binding as your CSS class for the <select>. In order to apply the binding to the correctly you'll need to do this within the data-bind attribute.

<select data-bind="selectpicker: meal"></select>

Knockout's documentation on this is also very helpful.

Upvotes: 2

Related Questions