I'm working on a project where im using .net web api, knockout and in this example, the jquery plugin select2.
What im trying to do is to set some field values after the change of the selection. The select2 control list is loaded after ajax call and the objects contain more data than just id and text. How can i get the rest of the data, so i can fill the other inputs with it? Shortly, im trying to update a viewmodel after the change of the selection (but i get the data when this plugin makes the ajax call).
Here is a sample data that the selected object should contain:
{
"Customer":{
"ID":13,
"No":"0000012",
"Name":"SomeName",
"Address":"SomeAddress",
"ZipCode":"324231",
"City":"SimCity",
"Region":"SS",
"Phone":"458447478",
"CustomerLocations":[]
}
}
Here is where i am for now:
Sample html:
<input type="hidden" data-bind="select2: { optionsText: 'Name', optionsValue: 'ID', sourceUrl: apiUrls.customer, model: $root.customer() }, value: CustomerID" id="CustomerName" name="CustomerName" />
<input type="text" data-bind="........" />
<input type="text" data-bind="........" />
etc...
and this is the custom binding:
ko.bindingHandlers.select2 = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var obj = valueAccessor(),
allBindings = allBindingsAccessor();
var optionsText = ko.utils.unwrapObservable(obj.optionsText);
var optionsValue = ko.utils.unwrapObservable(obj.optionsValue);
var sourceUrl = ko.utils.unwrapObservable(obj.sourceUrl);
var selectedID = ko.utils.unwrapObservable(allBindings.value);
var model = ko.utils.unwrapObservable(obj.model);//the object that i need to get/set
$(element).select2({
placeholder: "Choose...",
minimumInputLength: 3,
initSelection: function (element, callback) {
if (model && selectedID !== "") {
callback({ id: model[optionsValue](), text: model[optionsText]() });
}
},
ajax: {
quietMillis: 500,
url: sourceUrl,
dataType: 'json',
data: function (search, page) {
return {
page: page,
search: search
};
},
results: function (data) {
var result = [];
$.each( data.list, function( key, value ) {
result.push({ id: value[optionsValue], text: value[optionsText] });
});
var more = data.paging.currentPage < data.paging.pageCount;
return { results: result, more: more };
}
}
});
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).select2('destroy');
});
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var obj = valueAccessor(),
allBindings = allBindingsAccessor();
var model = ko.utils.unwrapObservable(obj.model);//the object that i need to get/set
var selectedID = ko.utils.unwrapObservable(allBindings.value);
$(element).select2('val', selectedID);
$(element).on("change", function (e) {
//...
});
}
};
Getting the selected id or text is not a problem, but how not to loose the rest of the information after the ajax call? Where can i set/get this object so i can have all the data that it contains?
Thank you
When you build a object literal for your results, added the full object as a "data" property.
result.push({ id: value[optionsValue], text: value[optionsText], data: value });
Then handle the select2-selected event thrown by select2. The event object this should contain your object literal as the choice property.
$element.on('select2-selected', function(eventData) {
if ( eventData.choice ) {
// item selected
var dataObj = eventData.choice.data;
var selectedId = eventData.choice.id;
} else {
// item cleared
}
});
For select2 v4, you can use $(elem).select2('data')
to get the selected objects.
$('selected2-enabled-elements').on('change', function(e) {
console.log($(this).select2('data'));
});
Example: https://jsfiddle.net/calvin/p1nzrxuy/
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