-
-
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"] | |
} | |
}); |
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>
@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 the
selectizeOptions` 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?