You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am using the knockout select binding where an entire object is bound as the value...not just a string.
bootstrap-multiselect did not like this because it uses the "value" to relate its dropdown list items back to the corresponding select option. In order for it to do this you have to have set the "optionsValue" attribute in your knockout binding so that the option has a "value" attribute. However, setting the "optionsValue" attribute then has the expected result of setting only that value in my selectedOptions observableArray...not the entire object.
Its quite possible that I am the only person that uses the functionality within knockout that lets you bind the options to entire objects, but just in case I'm not...here's the hack fix:
Created a two new bootstrap-multiselect options called "optionsKey" and "observableKey" so that it knows where to go for a value that it can relate to:
Now I dive into the bootstrap-multiselect.js file. The first thing I had to do in here is at the top where it is adding the knockout init handler.
init: function(element,valueAccessor,allBindings,viewModel,bindingContext){
...
if(allBindings.has('selectedOptions')){varselectedOptions=allBindings.get('selectedOptions');if(ko.isObservable(selectedOptions)){ko.computed({read: function(){selectedOptions();// Added to handle knockout binding to an object...not just a value// multiselect needs the selected property on the options, else it wont show them on refreshif((config.optionsKey!==undefined)&&(config.optionsKey!==null)&&(config.optionsKey.length>0)&&(config.observableKey!==undefined)&&(config.observableKey!==null)&&(config.observableKey.length>0)){var_optionsKey=config.optionsKey;var_observableKey=config.observableKey;ko.utils.arrayForEach(selectedOptions(),function(selectedOption){$("option["+_optionsKey+"='"+selectedOption[_observableKey]()+"']",$element).prop('selected',true);})}setTimeout(function(){$element.multiselect('refresh');},1);},disposeWhenNodeIsRemoved: element}).extend({rateLimit: 100,notifyWhenChangesStop: true});}}
...
Next I had to modify the createOptionValue function in bootstrap-multiselect.js to first use this key as the value it sets in its list items:
createOptionValue: function(element){
...
varvalue=$element.val();// Added to handle knockout binding to an object...not just a valueif((this.options.optionsKey!==undefined)&&(this.options.optionsKey!==null)&&(this.options.optionsKey.length>0)){varkey=$element.attr(this.options.optionsKey);if((key!==undefined)&&(key!==null)&&(key.length>0)){value=key;}}
...
}
Lastly I had to modify getOptionByValue function in bootstrap-multiselect.js to find option elements based on this attribute instead of value:
getOptionByValue: function(value){varvalueToCompare=value.toString();// Added to handle knockout binding to an object...not just a valueif((this.options.optionsKey!==undefined)&&(this.options.optionsKey!==null)&&(this.options.optionsKey.length>0)){varopt=$("option["+this.options.optionsKey+"='"+valueToCompare+"']",this.$select).first();if((opt!==undefined)&&(opt!==null)){return$(opt);}}varoptions=$('option',this.$select);for(vari=0;i<options.length;i=i+1){varoption=options[i];if(option.value===valueToCompare){return$(option);}}},
The text was updated successfully, but these errors were encountered:
Thank you for this tip - I was trying to accomplish binding to select objects as well and this write up was very helpful. The only thing I had to do in addition to @APM3 's code is also populate the "value" attribute of my options in the SetOptionKey function:
See gist for knockout binding that supported object. Just replace the actual binding from bootstrap-multiselect.js file. In this code you dont need to put into your vm to set option.
//Just like this one
myVM.SetOptionKey = function ( option, item ) {
ko.applyBindingsToNode( option, { attr: { "data-key": item.Key } }, item );
};
I added preprocess to bindings to implicitly addoptionsAfterRender.
I am using the knockout select binding where an entire object is bound as the value...not just a string.
bootstrap-multiselect did not like this because it uses the "value" to relate its dropdown list items back to the corresponding select option. In order for it to do this you have to have set the "optionsValue" attribute in your knockout binding so that the option has a "value" attribute. However, setting the "optionsValue" attribute then has the expected result of setting only that value in my selectedOptions observableArray...not the entire object.
Its quite possible that I am the only person that uses the functionality within knockout that lets you bind the options to entire objects, but just in case I'm not...here's the hack fix:
Created a two new bootstrap-multiselect options called "optionsKey" and "observableKey" so that it knows where to go for a value that it can relate to:
In my knockout view model I set the attribute referenced by "optionsKey" on each option:
Now I dive into the bootstrap-multiselect.js file. The first thing I had to do in here is at the top where it is adding the knockout init handler.
Next I had to modify the createOptionValue function in bootstrap-multiselect.js to first use this key as the value it sets in its list items:
Lastly I had to modify getOptionByValue function in bootstrap-multiselect.js to find option elements based on this attribute instead of value:
The text was updated successfully, but these errors were encountered: