I have the requirement to integrate a select2 mulitple select that is populated by a remote service with knockout. Of course, only the selected options should be binded, not the available options as they come from remote.
If the binded element would be a select, it would be an easy task (selectedOptions binding), but in case of input based there is no.
I created a change event that tries to manipulate the knockout observable and it does its job more or less, but it is not the same as a binding, as for example when I instanciate the component on another page in my spa, it is treated as a completly new instance and I would have to manually synchronize the selected options, work that usually does knockout...
My code
var CodeItem = function(code) {
this.code = ko.observable(code);
};
self.values = ko.observableArray([]);
self.selectedIPCs = ko.observableArray([]);
$(".ipcMulti").select2({
placeholder: "enter ipc",
minimumInputLength: 2,
multiple: true,
id: function(obj) {
return obj;
},
ajax: {
url: "/assets/Content/suggest_ipcr.json",
dataType: 'json',
data: function (term, page) {
return {
q: term // search term
//page_limit: 10,
};
},
quietMillis:100,
results: function (data, page) {
return {results: data.spellcheck.suggestions[1].suggestion};
}
}
});
$(".ipcMulti").on("change",function(e){
underlyingArray = self.selectedIPCs();
if (e.added !== undefined) {
underlyingArray.push(new CodeItem(e.added));
} else if (e.removed !== undefined) {
var todelete = null;
ko.utils.arrayForEach(self.selectedIPCs(), function(item) {
var o1 = e.removed;
var value = item.code();
if (o1==value) {
todelete = item;
}
});
ko.utils.arrayRemoveItem(underlyingArray, todelete);
}
});