-
-
Save isDipesh/8001624 to your computer and use it in GitHub Desktop.
| 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) { | |
| 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(); | |
| } |
@stechnique
You are using options binding and not selectize binding?
@xtranophilist
<select data-bind="selectize: $root.Exercises, value: ExerciseID, optionsValue: function(item){return item.ExerciseID()}, optionsText: function(item){return item.ExerciseName();}, opt: {create: $root.CreateExercise}"></select>
The list does not seem to be updated when the associated observable array has items added. However, if I create a new instance of this same binding it has the updated items. I presume it's a problem with the update function, but I'm not exactly sure what needs to happen to get it working properly.
EDIT: I should note that I am simply pushing items into the observable array.
The destroy method does not revert the item properly. For example tabIndex is left at -1. See destroy method here for missing parameters:
https://github.com/brianreavis/selectize.js/blob/master/src/selectize.js
Does tagging work with this script? The first two examples here: http://brianreavis.github.io/selectize.js/
Is this binding only working in Knockout 3.0+? I'm working on an old knockout app that's stuck on 2.2.1 and this is the best option to use, but if I have to update Knockout to 3+ it may not be worth it.
I am having an issue when using webpack 3.10.0 where ko.subscribe is no longer triggered in this binding... any ideas why?
How would this work with option groups?
Hi, I love your binding, but I just noticed a problem I'm having with it in a specific use case. I have this code
This works great if the ratePlan observable is blank at first. As soon as I select something on the selectize input the model is updated. But if ratePlan was set in the beginning, I see the proper option selected in the input, but the KO model observable is updated with "undefined". So when I submit the form I lose the information. I looked at the source and could not find a reason for this. If I remove the value binding on the component then it stays with the value it had (it is not overwritten to undefined). If I replace the selectize binding with a normal options binding, it works well.
Anyone else run into this?