I\'m using both Knockout (version 2.0) and jQuery Mobile (version 1.0.1) in the same project. The problem is with binding data to select lists. jQuery Mobile presents select
I ended up solving myself. I wrote my own jqmValue binding:
ko.bindingHandlers.jqmValue = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
if (typeof ko.bindingHandlers.value.init !== 'undefined') {
ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor, viewModel);
}
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
if (typeof ko.bindingHandlers.value.update !== 'undefined') {
ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor, viewModel);
}
var instance = $.data(element, 'selectmenu');
if (instance) {
$(element).selectmenu('refresh', true);
}
}
};
The select list code is then changed to following:
I already tried implementing this yesterday before asking the question, but apparently I wrote it poorly then because it didn't work. However, now with a fresh pair of eyes I managed to implement it correctly so hopefully this answer solves the problem for other Knockout and jQuery Mobile users too.
using both Knockout 3.3 + jQuery Mobile 1.4.5 and also had the same problem when i had multiple selections which binding one value
<select id="myselect1" data-bind="options: modelsA-Z, value: myModel"></select>
<select id="myselect2" data-bind="options: modelsFamous, value: myModel"></select>
1st/2nd select not shown the init value and 2nd not updated after... I finally use below binding: (replace above value:myModel -> jqmValue: myModel)
ko.bindingHandlers.jqmValue = {
init: function (element, valueAccessor) {
var result = ko.bindingHandlers.value.init.apply(this, arguments);
try {
$(element).selectmenu("refresh");
} catch (x) {}
return result;
},
update: function (element, valueAccessor) {
ko.bindingHandlers.value.update.apply(this, arguments);
var value = valueAccessor();
var valueUnwrapped = ko.utils.unwrapObservable(value);
try {
$(element).selectmenu("refresh");
} catch (x) {}
}
};
Just for clarity, the best solution now for KO 3.x would be:
ko.bindingHandlers.jqmValue = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
if (typeof ko.bindingHandlers.value.init !== 'undefined') {
ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor, viewModel);
}
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
var instance;
if (typeof ko.bindingHandlers.value.update !== 'undefined') {
ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor, viewModel);
}
instance = $.data(element, 'mobile-selectmenu');
if (instance) {
$(element).selectmenu('refresh', true);
}
}
};
And the matching HTML use:
<select data-bind="options: optionsList, optionsValue: 'Id', optionsText: 'Title', jqmValue: knockoutobservable"></select>
For my personal experience (with jquerymobile 1.1.0 and knockoutjs 2.1.0), I've only used jqmoptions (as seen in the first post) binding to have a valid knockout binding to a select. To make 'value' binding works with select, simply declare it as first in the binding
<select name="myname" id="myid" data-bind="value: myvalue, jqmoptions: myvalues, optionsValue: 'id', optionsText: 'desc'"></select>
Looks that the order is mandatory: http://goo.gl/nVbHc