We have usual problem with optionsCaption binding: it is always showed even when there is only one element. We solved this problem using our custom binding:
ko.bindingHandlers.optionsAutoSelect = {
update: function (element, valueAccessor, allBindingsAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
var allBindings = allBindingsAccessor();
if (value.length == 1) {
allBindings.optionsCaption = null;
}
ko.bindingHandlers.options.update(element, valueAccessor, allBindingsAccessor);
}
};
after updating to knockout 3.0 allBindings become readonly. So any changes are really skipped. Any ideas how it could be solved in ko 3.0? We really have a lot of such auto selects and don't want to copy paste some computed code on all views. So we want some single option/extensibility point. Unfortunately as I could see options binding is rather monolithic.
Probably some different approaches that you could take here. Here is one thought (feel free to use a better name than optionsPlus
):
ko.bindingHandlers.optionsPlus = {
preprocess: function(value, name, addBindingCallback) {
//add optionsCaption to the bindings against a "caption" sub-observable
addBindingCallback("optionsCaption", value + ".caption");
//just return the original value to allow this binding to remain as-is
return value;
},
init: function(element, valueAccessor) {
var options = valueAccessor();
//create an observable to track the caption
if (options && !ko.isObservable(options.caption)) {
options.caption = ko.observable();
}
//call the real options binding, return to control descendant bindings
return ko.bindingHandlers.options.init.apply(this, arguments);
},
update: function(element, valueAccessor, allBindings) {
var options = valueAccessor(),
value = ko.unwrap(options);
//set the caption observable based on the length of data
options.caption(value.length === 1 ? null : allBindings.get("defaultCaption"));
//call the original options update
ko.bindingHandlers.options.update.apply(this, arguments);
}
};
You would use it like:
<select data-bind="optionsPlus: choices, defaultCaption: 'choose one...'"></select>
It creates a caption
observable off of your observableArray/array and updates the caption initially and whenever the options are updated (if using an observableArray).
Sample here: http://jsfiddle.net/rniemeyer/jZ2FC/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With