-
-
Save DrSammyD/3ae055ca1280ccd9a4ae to your computer and use it in GitHub Desktop.
| (function (factory) { | |
| 'use strict'; | |
| if (typeof define === 'function' && define.amd) { | |
| define(['knockout','jquery','selectize'], factory); | |
| } else { | |
| var selConstructor = (typeof selectize != "undefined")?selectize:$('<select>').selectize().data('selectize').constructor; | |
| factory(ko,$,selConstructor); | |
| } | |
| })(function (ko,$,selectize) { | |
| var _key= null; | |
| for(_key in ko.bindingHandlers.options){ | |
| if(typeof ko.bindingHandlers.options[_key] =='string' && ko.bindingHandlers.options[_key].match('__ko__')) | |
| break; | |
| } | |
| var inject_binding = function (allBindings, key, value) { | |
| //https://github.com/knockout/knockout/pull/932#issuecomment-26547528 | |
| var has = allBindings.has; | |
| var get = allBindings.get; | |
| return { | |
| has: function (bindingKey) { | |
| return (bindingKey == key) || has.call(allBindings,bindingKey); | |
| }, | |
| get: function (bindingKey) { | |
| var binding = get.call(allBindings,bindingKey); | |
| if (bindingKey == key) { | |
| binding = binding ? [].concat(binding, value) : value; | |
| } | |
| return binding; | |
| } | |
| }; | |
| } | |
| var setOptionNodeSelectionState =function (optionNode, isSelected) { | |
| optionNode.selected = isSelected; | |
| } | |
| selectize.prototype.updateOriginalInput=function(){ | |
| var i, n, options, self = this; | |
| if (self.$input[0].tagName.toLowerCase() === 'select') { | |
| options = []; | |
| ko.utils.arrayForEach(self.$input.get(0).getElementsByTagName("option"),function(node){ | |
| var isSelected = self.items.indexOf(node[ko.bindingHandlers.options[_key].slice(1)]||node['value']) !=-1 | |
| setOptionNodeSelectionState(node, isSelected); | |
| }) | |
| } else { | |
| self.$input.val(self.getValue()); | |
| } | |
| self.$input.trigger('propertychange'); | |
| if (self.isSetup) { | |
| self.trigger('change', self.$input.val()); | |
| } | |
| } | |
| selectize.prototype.destroy=function(){ | |
| var self = this; | |
| var eventNS = self.eventNS; | |
| self.trigger('destroy'); | |
| self.off(); | |
| self.$wrapper.remove(); | |
| self.$dropdown.remove(); | |
| $(window).off(eventNS); | |
| $(document).off(eventNS); | |
| $(document.body).off(eventNS); | |
| delete self.$input[0].selectize; | |
| } | |
| ko.bindingHandlers.selectizeOptions={ | |
| init:function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { | |
| var $el= $(element); | |
| if(allBindingsAccessor.get('selectizeMultiple')) | |
| $(element).prop('multiple',true); | |
| $.extend(allBindingsAccessor, inject_binding(allBindingsAccessor,'optionsAfterRender',function(el){ | |
| $(el).attr('value', el[ko.bindingHandlers.options[_key].slice(1)]||el['value']) | |
| })); | |
| var ret= ko.bindingHandlers.options.init(element,valueAccessor, allBindingsAccessor, viewModel, bindingContext); | |
| $el.selectize({ | |
| placeholder: ko.unwrap(allBindingsAccessor.get('optionsCaption')) | |
| }); | |
| ko.utils.domNodeDisposal.addDisposeCallback(element, function() { | |
| $el.data('selectize').destroy(); | |
| }); | |
| return ret; | |
| }, | |
| update:function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { | |
| var ret= ko.bindingHandlers.options.update(element,valueAccessor, allBindingsAccessor, viewModel, bindingContext); | |
| var $el= $(element); | |
| $el.data('selectize').destroy(); | |
| var $chi=$el.children(); | |
| $el.selectize({ | |
| placeholder: ko.unwrap(allBindingsAccessor.get('optionsCaption')) | |
| }); | |
| $el.append($chi); | |
| ret= ko.bindingHandlers.options.update(element,valueAccessor, allBindingsAccessor, viewModel, bindingContext); | |
| return ret; | |
| } | |
| } | |
| ko.bindingHandlers.selectizeCaption = { | |
| update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { | |
| ko.bindingHandlers.optionsCaption.update(element,valueAccessor, allBindingsAccessor, viewModel, bindingContext); | |
| $(element).data('selectize').settings.placeholder= ko.unwrap(valueAccessor()); | |
| $(element).data('selectize').updatePlaceholder(); | |
| } | |
| } | |
| ko.bindingHandlers.selectize = { | |
| init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { | |
| ko.bindingHandlers.value.init(element,valueAccessor, allBindingsAccessor, viewModel, bindingContext) | |
| }, | |
| update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { | |
| ko.unwrap(valueAccessor()); | |
| ko.bindingHandlers.value.update(element,valueAccessor, allBindingsAccessor, viewModel, bindingContext); | |
| $el=$(element); | |
| $el.data('selectize').setValue( | |
| $el.find(":selected") | |
| .map(function(i,el){ | |
| return el[ko.bindingHandlers.options[_key].slice(1)]||el['value'] | |
| }).get()[0] | |
| ); | |
| }, | |
| after: ["selectizeOptions"] | |
| } | |
| ko.bindingHandlers.selectizeMultiple = { | |
| init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { | |
| $(element).prop('multiple',true); | |
| ko.bindingHandlers.selectedOptions.init(element,valueAccessor, allBindingsAccessor, viewModel, bindingContext); | |
| }, | |
| update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { | |
| ko.bindingHandlers.selectedOptions.update(element,valueAccessor, allBindingsAccessor, viewModel, bindingContext); | |
| $el=$(element); | |
| $el.data('selectize').setValue( | |
| $el.find(":selected") | |
| .map(function(i,el){ | |
| return el[ko.bindingHandlers.options[_key].slice(1)]||el['value'] | |
| }).get() | |
| ); | |
| }, | |
| after: ["selectizeOptions"] | |
| } | |
| }); |
@DrSammyD
I'm not sure if you are working on this still or not but I ran into an issue which I think would be easy to solve (for you).
The call to $(element).selectize({ ... });' is only made in theselectizeOptions` bindingHandler, which cannot be used if the options are hard-coded into the html. It might be a good idea to check if the element has been initialized and if not, go ahead and do so in each bindingHandler. Thoughts?
Hi @DrSammyD,
I've a simple question: how can I pre-select an option if I use optionValue and OptionText?
In this fiddle I try to get it but without results: http://jsfiddle.net/bqgd81jz/1/ . If you notice the value observable is initialized with 3.
Thanks in advance.
Daniele
@DrSammyD do you see a possibility to hand over selectize constructor options? For example plugins or render: {option: ...} would be very handy and it feels weird to put them in the code directly.
Hey @krnlde looks at my gist https://gist.github.com/lelelic/114a286649438b6ef365. I've added the option "selectizeSettings" where you can specify all the options of selectize constructor.
For example:
<select name="sel1" class="form-control" data-bind='selectize: values, selectizeOptions: myValues, optionsText: "Description", optionsValue: "Id", selectizeSettings: {onDelete: function() { return false }}'></select>
Excellent work Dr Sammy D! This is exactly what I needed!
@ehartford: Take a look at this: http://jsfiddle.net/fm19zxj8/25/