Last active
May 23, 2018 14:47
-
-
Save jonesy827/49b417536dd5903bbf559006c56f0b8b to your computer and use it in GitHub Desktop.
Knockout Select2 version 3.x binding
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ko.bindingHandlers.select2 = { | |
init: function (el, valueAccessor, allBindingsAccessor, viewModel) { | |
ko.utils.domNodeDisposal.addDisposeCallback(el, function () { | |
$(el).select2('destroy'); | |
}); | |
var allBindings = allBindingsAccessor(); | |
var valueProperty = allBindings.valueProperty || 'value'; | |
var textProperty = allBindings.textProperty || 'text'; | |
var isSelected = function (item) { | |
if (allBindings.selectedValue) { | |
let unwrapped = ko.unwrap(allBindings.selectedValue); | |
if (!unwrapped) return false; | |
return ko.unwrap(item[valueProperty]) == ko.unwrap(unwrapped[valueProperty]); | |
} | |
return ko.utils.arrayFilter(ko.unwrap(allBindings.selectedItems), (i) => ko.unwrap(item[valueProperty]) == ko.unwrap(i[valueProperty])).length > 0; | |
}; | |
var configureSelect = function () { | |
var options = ko.utils.arrayMap(ko.unwrap(allBindings.selectItems), (item) => ({ | |
id: ko.unwrap(item[valueProperty]), | |
text: ko.unwrap(item[textProperty]), | |
selected: isSelected(item) | |
})); | |
var config = ko.unwrap(allBindings.select2); | |
config.data = options; | |
config.width = '100%'; | |
if (allBindings.selectedValue) { | |
$(el).select2(config); | |
} else { | |
config.templateSelection = () => 'Filtered'; | |
let select2 = new Select2(el, config); | |
} | |
}; | |
// Monitor source item list for changes and re-draw component if list changes | |
allBindings.selectItems.subscribe((newValue) => { | |
configureSelect(); | |
}); | |
configureSelect(); | |
$(el).on('change', function (e) { | |
let selectData = $(el).select2('data'); | |
if (allBindings.selectedValue) { | |
let selectedObject = ko.utils.arrayFilter(ko.unwrap(allBindings.selectItems), (item) => { | |
ko.unwrap(item[valueProperty]).toString() == selectData.id; | |
})[0]; | |
allBindings.selectedValue(selectedObject); | |
} else { | |
let selectedObjects = ko.utils.arrayFilter(ko.unwrap(allBindings.selectItems), (item) => { | |
let v = ko.unwrap(item[valueProperty]).toString(); | |
return ko.utils.arrayFilter(selectData, function (selectItem) { | |
return selectItem.id === v; | |
}).length > 0; | |
}); | |
allBindings.selectedItems(selectedObjects); | |
} | |
}); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Multi-select usage:
<select data-bind="selectedItems: selected, valueProperty: 'id', textProperty: 'name', selectItems: items, select2: { placeholder: placeholder, allowClear: true }" multiple></select>
Single select usage:
<select data-bind="selectedValue: selected, valueProperty: 'id', textProperty: 'name', selectItems: items, select2: { placeholder: placeholder, allowClear: true }"></select>