Skip to content

Instantly share code, notes, and snippets.

@tejovanthn
Forked from isDipesh/ko_selectize.js
Last active December 20, 2015 06:36
Show Gist options
  • Save tejovanthn/a0671955605251fb610c to your computer and use it in GitHub Desktop.
Save tejovanthn/a0671955605251fb610c to your computer and use it in GitHub Desktop.
ko_selectize.js ; Full details and demo here - http://motorscript.com/selectize-js-binding-knockout-js/
var inject_binding = function (allBindings, key, value) {
//https://github.com/knockout/knockout/pull/932#issuecomment-26547528
return {
has: function (bindingKey) {
return (bindingKey == key) || allBindings.has(bindingKey);
},
get: function (bindingKey) {
var binding = allBindings.get(bindingKey);
if (bindingKey == key) {
binding = binding ? [].concat(binding, value) : value;
}
return binding;
}
};
}
ko.bindingHandlers.selectize = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
if (!allBindingsAccessor.has('optionsText'))
allBindingsAccessor = inject_binding(allBindingsAccessor, 'optionsText', 'name');
if (!allBindingsAccessor.has('optionsValue'))
allBindingsAccessor = inject_binding(allBindingsAccessor, 'optionsValue', 'id');
if (typeof allBindingsAccessor.get('optionsCaption') == 'undefined')
allBindingsAccessor = inject_binding(allBindingsAccessor, 'optionsCaption', 'Choose...');
ko.bindingHandlers.options.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
var options = {
valueField: allBindingsAccessor.get('optionsValue'),
labelField: allBindingsAccessor.get('optionsText'),
searchField: allBindingsAccessor.get('optionsText')
}
if (allBindingsAccessor.has('options')) {
var passed_options = allBindingsAccessor.get('options')
for (var attr_name in passed_options) {
options[attr_name] = passed_options[attr_name];
}
}
var $select = $(element).selectize(options)[0].selectize;
if (typeof allBindingsAccessor.get('value') == 'function') {
$select.addItem(allBindingsAccessor.get('value')());
allBindingsAccessor.get('value').subscribe(function (new_val) {
$select.addItem(new_val);
})
}
if (typeof allBindingsAccessor.get('selectedOptions') == 'function') {
allBindingsAccessor.get('selectedOptions').subscribe(function (new_val) {
// Removing items which are not in new value
var values = $select.getValue();
var items_to_remove = [];
for (var k in values) {
if (new_val.indexOf(values[k]) == -1) {
items_to_remove.push(values[k]);
}
}
for (var k in items_to_remove) {
$select.removeItem(items_to_remove[k]);
}
for (var k in new_val) {
$select.addItem(new_val[k]);
}
});
var selected = allBindingsAccessor.get('selectedOptions')();
for (var k in selected) {
$select.addItem(selected[k]);
}
}
if (typeof init_selectize == 'function') {
init_selectize($select);
}
if (typeof valueAccessor().subscribe == 'function') {
valueAccessor().subscribe(function (changes) {
// To avoid having duplicate keys, all delete operations will go first
var addedItems = new Array();
changes.forEach(function (change) {
switch (change.status) {
case 'added':
addedItems.push(change.value);
break;
case 'deleted':
var itemId = change.value[options.valueField];
if (itemId != null) $select.removeOption(itemId);
}
});
addedItems.forEach(function (item) {
$select.addOption(item);
});
}, null, "arrayChange");
}
},
update: function (element, valueAccessor, allBindingsAccessor) {
var $select = $(element).selectize(valueAccessor())[0].selectize;
var item_id = JSON.parse('['+allBindingsAccessor.get('value')()+']');
if(item_id){
for (k in item_id){
$select.addItem(item_id[k]);
}
}
if (allBindingsAccessor.has('object')) {
var optionsValue = allBindingsAccessor.get('optionsValue') || 'id';
var value_accessor = valueAccessor();
var selected_obj = $.grep(value_accessor(), function (i) {
if (typeof i[optionsValue] == 'function')
var id = i[optionsValue]
else
var id = i[optionsValue]
return id == allBindingsAccessor.get('value')();
})[0];
if (selected_obj) {
allBindingsAccessor.get('object')(selected_obj);
}
}
}
}
<h3>1. Using selectize with plain select tag, with values built in view.</h3>
<select data-bind="selectize: {}">
<option value="1">Val 1</option>
<option value="2">Val 2</option>
</select>
<h3>2. Using values from observable array.</h3>
<select data-bind="selectize: items, value: item_id"></select>
<h3>3. Getting selected item as an object</h3>
<select data-bind="selectize: items, value: my_item_id, object: my_item"></select>
<h3>4. Using with multiselect</h3>
<select data-bind="selectize: items, selectedOptions: selected_items" multiple></select>
<h3>5. Passing additional options</h3>
<select data-bind="selectize: items, selectedOptions: selected_items2, options: {plugins: ['remove_button']}" multiple></select>
$(document).ready(function(){
ko.applyBindings(new TestVM(););
});
function TestVM(){
var self = this;
self.items = ko.observableArray([
{'id': 1, 'name': 'One'},
{'id': 2, 'name': 'Two'}
]);
self.item_id = ko.observable();
self.my_item_id = ko.observable();
self.my_item = ko.observable();
self.selected_items = ko.observableArray([1]);
self.selected_items2 = ko.observableArray();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment