I'm using knockout js and the chosen plugin (https://github.com/harvesthq/chosen) to try and make a good looking multi select.
I've tried various ways but can't get the multiselect to work with the data I'm using. When I click on the multiselect, no values are shown even though the options binding contains the correct data.
HTML:
<select multiple="multiple" data-bind="options: allCustomers,
selectedOptions: event().customers, optionsText: 'name',
optionsValue: 'id', chosen: true " ></select>
Simplified version of the view model:
function Event()
{
this.customers = ko.observableArray();
};
//for chosen plugin
ko.bindingHandlers.chosen = {
update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
$(element).chosen();
}
}
function ViewModel()
{
this.event = ko.observable(new Event());
this.allCustomers = ko.observableArray();
};
var viewModel = new ViewModel();
$.getJSON("/get_json", function(data)
{
for (var c = 0; c < data.customers.length; c++)
{
viewModel.allCustomers.push(data.customers[c]);
}
});
ko.applyBindings(viewModel);
PHP:
function get_json()
{
$eventData = array(
'customers' => array(array('name' => 'Bob', 'id' => 1), array('name' => 'John', 'id' => 2)),
'moreData' => array(),
'evenMoreData' => array()
);
echo json_encode($eventData);
}
This shows the chosen styled select box but when I click in it, no options appear.
When I create a local JS array in the view model for the customers and pass that into allCustomers, the multiselect works correctly (see my jsfiddle) so it's something to do with getting data from the server, but I've been staring at this a while and can't see the problem!
Any help much appreciated
I found the problem after @Tyrsius suggested it might not be updating the data after the initial binding.
I added $(element).trigger("liszt:updated");
to the custom binding like so:
ko.bindingHandlers.chosen = {
update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
$(element).chosen();
$(element).trigger("liszt:updated");
}
}
The code in the accepted version for some reason did not work for me. Probably because the liszt:updated
command does not trigger chosen to be updated. Based on docs here I wrote my own version:
ko.bindingHandlers.chosen = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
$(element).chosen({ width: "95%", placeholder_text_multiple: "Select..." });
var value = ko.unwrap(valueAccessor());
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
var value = ko.unwrap(valueAccessor());
$(element).trigger("chosen:updated");
}
}
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