Knockout.JS with bootstrap selectpicker
javascript, knockout.js, twitter-bootstrap
Solution
EDIT See below for alternate solution
the problem is with your selectPicker.init function.
You need to call the options binding, not the value binding. the options.init sets the initial internal state, when this bypassed the options.update function will reset the value.
// regular select and observable so call the default value binding
ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor);
change to
// regular select and observable so call the default value binding
ko.bindingHandlers.options.init(element, valueAccessor, allBindingsAccessor);
EDIT
Ok, I took you sample back to basics to use the standard options bindings to get the normal select working.
Then use the selectpicker binding solely to initialise and refresh. It will synchronize to the select on its own.
Prior to Knockout 3, the selectPicker update function would have been invoked if any of the bindings on the element caused an update ( like updating options, value or selectedOptions ). With Knockout 3 the bindings now fire independently ( good thing ), but you now need to use subscriptions to get notified when either the options or value/selectedOptions changes.
I think you will see this is now a lot simpler and there is no distinct between single and multiple select in your custom binding. This now works if either the teamItems or itemID observable is updated.
HTML
<!-- Multiple Select -->
<select data-bind="selectedOptions: teamIDs,
options: teamItems,
optionsText: 'text',
optionsValue : 'id',
selectPicker: {}" multiple="true"></select>
JAVASCRIPT
ko.bindingHandlers.selectPicker = {
after: ['options'], /* KO 3.0 feature to ensure binding execution order */
init: function (element, valueAccessor, allBindingsAccessor) {
var $element = $(element);
$element.addClass('selectpicker').selectpicker();
var doRefresh = function() {
$element.selectpicker('refresh');
}, subscriptions = [];
// KO 3 requires subscriptions instead of relying on this binding's update
// function firing when any other binding on the element is updated.
// Add them to a subscription array so we can remove them when KO
// tears down the element. Otherwise you will have a resource leak.
var addSubscription = function(bindingKey) {
var targetObs = allBindingsAccessor.get(bindingKey);
if ( targetObs && ko.isObservable(targetObs )) {
subscriptions.push( targetObs.subscribe(doRefresh) );
}
};
addSubscription('options');
addSubscription('value'); // Single
addSubscription('selectedOptions'); // Multiple
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
while( subscriptions.length ) {
subscriptions.pop().dispose();
}
} );
},
update: function (element, valueAccessor, allBindingsAccessor) {
}
};
Problem
I'm attempting to use Bootstrap Selectpicker along with knockout.js. There is already a custom binding out there that works for the multiselect version of the selectpicker (seen here), but I need it to work with the single select version. I thought it was going to be as simple as changing the `ko.observableArray` to a `ko.observable` and removing the `multiple` attribute -- but this doesn't seem to be the case. Any ideas on how to get this working? Fiddle with the binding and my updated code