Ability to disable sorting of choices/groups

This commit is contained in:
Josh Johnson 2016-08-31 19:18:46 +01:00
parent 59977af5d3
commit aff165e4a1
6 changed files with 332 additions and 285 deletions

View file

@ -41,6 +41,7 @@ A vanilla, lightweight (~15kb gzipped 🎉), configurable select box/text input
search: true,
flip: true,
regexFilter: null,
shouldSort: true,
sortFilter: sortByAlpha,
sortFields: ['label', 'value'],
placeholder: true,
@ -225,6 +226,13 @@ Pass an array of objects:
**Usage:** A filter that will need to pass for a user to successfully add an item.
### shouldSort
**Type:** `Boolean` **Default:** `true`
**Input types affected:** `select-one`, `select-multiple`
**Usage:** Whether choices should be sorted. If false, choices will appear in the order they were given.
### sortFilter
**Type:** `Function` **Default:** sortByAlpha

View file

@ -104,6 +104,12 @@
}
}
// Retrieve triggering element (i.e. element with 'data-choice' trigger)
this.passedElement = (0, _utils.isType)('String', element) ? document.querySelector(element) : element;
// If element has already been initalised with Choices, return it silently
if (this.passedElement.getAttribute('data-choice') === 'active') return;
var defaultConfig = {
items: [],
choices: [],
@ -118,6 +124,7 @@
search: true,
flip: true,
regexFilter: null,
shouldSort: true,
sortFilter: _utils.sortByAlpha,
sortFields: ['label', 'value'],
placeholder: true,
@ -172,12 +179,14 @@
this.currentState = {};
this.prevState = {};
this.currentValue = '';
// Retrieve triggering element (i.e. element with 'data-choice' trigger)
this.passedElement = (0, _utils.isType)('String', element) ? document.querySelector(element) : element;
this.highlightPosition = 0;
// Track searching
this.canSearch = this.config.search;
// Track tapping
this.wasTap = true;
// Focus containerOuter but not show dropdown if true
this.focusAndHideDropdown = false;
// Assing preset choices from passed object
this.presetChoices = this.config.choices;
@ -209,25 +218,17 @@
this._onPaste = this._onPaste.bind(this);
this._onInput = this._onInput.bind(this);
// Focus containerOuter but not show dropdown if true
this.focusAndHideDropdown = false;
// Monitor touch taps/scrolls
this.wasTap = true;
// Cutting the mustard
var cuttingTheMustard = 'querySelector' in document && 'addEventListener' in document && 'classList' in document.createElement('div');
if (!cuttingTheMustard) console.error('Choices: Your browser doesn\'t support Choices');
// Input type check
var canInit = this.passedElement && (0, _utils.isElement)(this.passedElement) && ['select-one', 'select-multiple', 'text'].some(function (type) {
var isValidElement = this.passedElement && (0, _utils.isElement)(this.passedElement);
var isValidType = ['select-one', 'select-multiple', 'text'].some(function (type) {
return type === _this.passedElement.type;
});
if (canInit) {
// If element has already been initalised with Choices
if (this.passedElement.getAttribute('data-choice') === 'active') return;
if (isValidElement && isValidType) {
// Let's go
this.init();
} else {
@ -247,31 +248,31 @@
value: function init() {
var callback = arguments.length <= 0 || arguments[0] === undefined ? this.config.callbackOnInit : arguments[0];
if (this.initialised !== true) {
// Set initialise flag
this.initialised = true;
if (this.initialised === true) return;
// Create required elements
this._createTemplates();
// Set initialise flag
this.initialised = true;
// Generate input markup
this._createInput();
// Create required elements
this._createTemplates();
this.store.subscribe(this.render);
// Generate input markup
this._createInput();
// Render any items
this.render();
this.store.subscribe(this.render);
// Trigger event listeners
this._addEventListeners();
// Render any items
this.render();
// Run callback if it is a function
if (callback) {
if ((0, _utils.isType)('Function', callback)) {
callback();
} else {
console.error('callbackOnInit: Callback is not a function');
}
// Trigger event listeners
this._addEventListeners();
// Run callback if it is a function
if (callback) {
if ((0, _utils.isType)('Function', callback)) {
callback();
} else {
console.error('callbackOnInit: Callback is not a function');
}
}
}
@ -285,6 +286,8 @@
}, {
key: 'destroy',
value: function destroy() {
if (this.initialised !== true) return;
this._removeEventListeners();
this.passedElement.classList.remove(this.config.classNames.input, this.config.classNames.hiddenState);
@ -600,29 +603,29 @@
value: function setValue(args) {
var _this8 = this;
if (this.initialised === true) {
// Convert args to an itterable array
var values = [].concat(_toConsumableArray(args));
if (this.initialised !== true) return;
values.forEach(function (item) {
if ((0, _utils.isType)('Object', item)) {
if (!item.value) return;
// If we are dealing with a select input, we need to create an option first
// that is then selected. For text inputs we can just add items normally.
if (_this8.passedElement.type !== 'text') {
_this8._addChoice(true, false, item.value, item.label, -1);
} else {
_this8._addItem(item.value, item.label, item.id);
}
} else if ((0, _utils.isType)('String', item)) {
if (_this8.passedElement.type !== 'text') {
_this8._addChoice(true, false, item, item, -1);
} else {
_this8._addItem(item);
}
// Convert args to an itterable array
var values = [].concat(_toConsumableArray(args));
values.forEach(function (item) {
if ((0, _utils.isType)('Object', item)) {
if (!item.value) return;
// If we are dealing with a select input, we need to create an option first
// that is then selected. For text inputs we can just add items normally.
if (_this8.passedElement.type !== 'text') {
_this8._addChoice(true, false, item.value, item.label, -1);
} else {
_this8._addItem(item.value, item.label, item.id);
}
});
}
} else if ((0, _utils.isType)('String', item)) {
if (_this8.passedElement.type !== 'text') {
_this8._addChoice(true, false, item, item, -1);
} else {
_this8._addItem(item);
}
}
});
return this;
}
@ -639,31 +642,29 @@
value: function setValueByChoice(value) {
var _this9 = this;
if (this.passedElement.type !== 'text') {
(function () {
var choices = _this9.store.getChoices();
// If only one value has been passed, convert to array
var choiceValue = (0, _utils.isType)('Array', value) ? value : [value];
if (this.passedElement.type === 'text') return;
// Loop through each value and
choiceValue.forEach(function (val) {
var foundChoice = choices.find(function (choice) {
// Check 'value' property exists and the choice isn't already selected
return choice.value === val;
});
var choices = this.store.getChoices();
// If only one value has been passed, convert to array
var choiceValue = (0, _utils.isType)('Array', value) ? value : [value];
if (foundChoice) {
if (!foundChoice.selected) {
_this9._addItem(foundChoice.value, foundChoice.label, foundChoice.id);
} else {
console.warn('Attempting to select choice already selected');
}
} else {
console.warn('Attempting to select choice that does not exist');
}
});
})();
}
// Loop through each value and
choiceValue.forEach(function (val) {
var foundChoice = choices.find(function (choice) {
// Check 'value' property exists and the choice isn't already selected
return choice.value === val;
});
if (foundChoice) {
if (!foundChoice.selected) {
_this9._addItem(foundChoice.value, foundChoice.label, foundChoice.id);
} else {
console.warn('Attempting to select choice already selected');
}
} else {
console.warn('Attempting to select choice that does not exist');
}
});
return this;
}
@ -681,20 +682,20 @@
value: function setChoices(choices, value, label) {
var _this10 = this;
if (this.initialised === true) {
if (this.passedElement.type === 'select-one' || this.passedElement.type === 'select-multiple') {
if (!(0, _utils.isType)('Array', choices) || !value) return;
if (this.initialised !== true) return;
if (choices && choices.length) {
this.containerOuter.classList.remove(this.config.classNames.loadingState);
choices.forEach(function (result, index) {
if (result.choices) {
_this10._addGroup(result, index);
} else {
_this10._addChoice(result.selected ? result.selected : false, result.disabled ? result.disabled : false, result[value], result[label]);
}
});
}
if (this.passedElement.type === 'select-one' || this.passedElement.type === 'select-multiple') {
if (!(0, _utils.isType)('Array', choices) || !value) return;
if (choices && choices.length) {
this.containerOuter.classList.remove(this.config.classNames.loadingState);
choices.forEach(function (result, index) {
if (result.choices) {
_this10._addGroup(result, index);
} else {
_this10._addChoice(result.selected ? result.selected : false, result.disabled ? result.disabled : false, result[value], result[label]);
}
});
}
}
return this;
@ -785,43 +786,40 @@
value: function ajax(fn) {
var _this11 = this;
if (this.initialised === true) {
if (this.passedElement.type === 'select-one' || this.passedElement.type === 'select-multiple') {
this.containerOuter.classList.add(this.config.classNames.loadingState);
this.containerOuter.setAttribute('aria-busy', 'true');
if (this.passedElement.type === 'select-one') {
var placeholderItem = this._getTemplate('placeholder', this.config.loadingText);
this.itemList.appendChild(placeholderItem);
} else {
this.input.placeholder = this.config.loadingText;
}
if (this.initialised !== true) return;
var callback = function callback(results, value, label) {
if (!(0, _utils.isType)('Array', results) || !value) return;
if (results && results.length) {
// Remove loading states/text
_this11.containerOuter.classList.remove(_this11.config.classNames.loadingState);
if (_this11.passedElement.type === 'select-multiple') {
var placeholder = _this11.config.placeholder ? _this11.config.placeholderValue || _this11.passedElement.getAttribute('placeholder') : false;
if (placeholder) {
_this11.input.placeholder = placeholder;
}
}
// Add each result as a choice
results.forEach(function (result, index) {
// Select first choice in list if single select input
if (index === 0 && _this11.passedElement.type === 'select-one') {
_this11._addChoice(true, false, result[value], result[label]);
} else {
_this11._addChoice(false, false, result[value], result[label]);
}
});
}
_this11.containerOuter.removeAttribute('aria-busy');
};
fn(callback);
if (this.passedElement.type === 'select-one' || this.passedElement.type === 'select-multiple') {
this.containerOuter.classList.add(this.config.classNames.loadingState);
this.containerOuter.setAttribute('aria-busy', 'true');
if (this.passedElement.type === 'select-one') {
var placeholderItem = this._getTemplate('placeholder', this.config.loadingText);
this.itemList.appendChild(placeholderItem);
} else {
this.input.placeholder = this.config.loadingText;
}
var callback = function callback(results, value, label) {
if (!(0, _utils.isType)('Array', results) || !value) return;
if (results && results.length) {
// Remove loading states/text
_this11.containerOuter.classList.remove(_this11.config.classNames.loadingState);
if (_this11.passedElement.type === 'select-multiple') {
var placeholder = _this11.config.placeholder ? _this11.config.placeholderValue || _this11.passedElement.getAttribute('placeholder') : false;
if (placeholder) {
_this11.input.placeholder = placeholder;
}
}
// Add each result as a choice
results.forEach(function (result, index) {
_this11._addChoice(false, false, result[value], result[label]);
});
}
_this11.containerOuter.removeAttribute('aria-busy');
};
fn(callback);
}
return this;
}
@ -1064,6 +1062,7 @@
var _this14 = this;
if (!value) return;
if (this.input === document.activeElement) {
var choices = this.store.getChoices();
var hasUnactiveChoices = choices.some(function (option) {
@ -1086,7 +1085,6 @@
include: 'score'
});
var results = fuse.search(needle);
_this14.currentValue = newValue;
_this14.highlightPosition = 0;
_this14.isSearching = true;
@ -2157,6 +2155,7 @@
// Join choices with preset choices and add them
allChoices.concat(_this19.presetChoices).forEach(function (o, index) {
// Pre-select first choice if it's a single select
if (index === 0 && _this19.passedElement.type === 'select-one') {
_this19._addChoice(true, o.disabled ? o.disabled : false, o.value, o.label);
} else {
@ -2195,7 +2194,12 @@
var groupFragment = fragment || document.createDocumentFragment();
var filter = this.config.sortFilter;
groups.sort(filter).forEach(function (group) {
// If sorting is enabled, filter groups
if (this.config.shouldSort) {
groups.sort(filter);
}
groups.forEach(function (group) {
// Grab options that are children of this group
var groupChoices = choices.filter(function (choice) {
if (_this20.passedElement.type === 'select-one') {
@ -2233,11 +2237,15 @@
var choicesFragment = fragment || document.createDocumentFragment();
var filter = this.isSearching ? _utils.sortByScore : this.config.sortFilter;
choices.sort(filter).forEach(function (choice) {
// If sorting is enabled or the user is searching, filter choices
if (this.config.shouldSort || this.isSearching) {
choices.sort(filter);
}
choices.forEach(function (choice) {
var dropdownItem = _this21._getTemplate('choice', choice);
if (_this21.passedElement.type === 'select-one') {
choicesFragment.appendChild(dropdownItem);
} else if (!choice.selected) {
var shouldRender = _this21.passedElement.type === 'select-one' || !choice.selected;
if (shouldRender) {
choicesFragment.appendChild(dropdownItem);
}
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -42,6 +42,12 @@ export default class Choices {
}
}
// Retrieve triggering element (i.e. element with 'data-choice' trigger)
this.passedElement = isType('String', element) ? document.querySelector(element) : element;
// If element has already been initalised with Choices, return it silently
if (this.passedElement.getAttribute('data-choice') === 'active') return;
const defaultConfig = {
items: [],
choices: [],
@ -111,12 +117,14 @@ export default class Choices {
this.currentState = {};
this.prevState = {};
this.currentValue = '';
// Retrieve triggering element (i.e. element with 'data-choice' trigger)
this.passedElement = isType('String', element) ? document.querySelector(element) : element;
this.highlightPosition = 0;
// Track searching
this.canSearch = this.config.search;
// Track tapping
this.wasTap = true;
// Focus containerOuter but not show dropdown if true
this.focusAndHideDropdown = false;
// Assing preset choices from passed object
this.presetChoices = this.config.choices;
@ -148,23 +156,15 @@ export default class Choices {
this._onPaste = this._onPaste.bind(this);
this._onInput = this._onInput.bind(this);
// Focus containerOuter but not show dropdown if true
this.focusAndHideDropdown = false;
// Monitor touch taps/scrolls
this.wasTap = true;
// Cutting the mustard
const cuttingTheMustard = 'querySelector' in document && 'addEventListener' in document && 'classList' in document.createElement('div');
if (!cuttingTheMustard) console.error('Choices: Your browser doesn\'t support Choices');
// Input type check
const canInit = this.passedElement && isElement(this.passedElement) && ['select-one', 'select-multiple', 'text'].some(type => type === this.passedElement.type);
if (canInit) {
// If element has already been initalised with Choices
if (this.passedElement.getAttribute('data-choice') === 'active') return;
const isValidElement = this.passedElement && isElement(this.passedElement);
const isValidType = ['select-one', 'select-multiple', 'text'].some(type => type === this.passedElement.type);
if (isValidElement && isValidType) {
// Let's go
this.init();
} else {
@ -178,31 +178,31 @@ export default class Choices {
* @public
*/
init(callback = this.config.callbackOnInit) {
if (this.initialised !== true) {
// Set initialise flag
this.initialised = true;
if (this.initialised === true) return;
// Create required elements
this._createTemplates();
// Set initialise flag
this.initialised = true;
// Generate input markup
this._createInput();
// Create required elements
this._createTemplates();
this.store.subscribe(this.render);
// Generate input markup
this._createInput();
// Render any items
this.render();
this.store.subscribe(this.render);
// Trigger event listeners
this._addEventListeners();
// Render any items
this.render();
// Run callback if it is a function
if (callback) {
if (isType('Function', callback)) {
callback();
} else {
console.error('callbackOnInit: Callback is not a function');
}
// Trigger event listeners
this._addEventListeners();
// Run callback if it is a function
if (callback) {
if (isType('Function', callback)) {
callback();
} else {
console.error('callbackOnInit: Callback is not a function');
}
}
}
@ -213,6 +213,8 @@ export default class Choices {
* @public
*/
destroy() {
if (this.initialised !== true) return;
this._removeEventListeners();
this.passedElement.classList.remove(this.config.classNames.input, this.config.classNames.hiddenState);
@ -472,29 +474,29 @@ export default class Choices {
* @public
*/
setValue(args) {
if (this.initialised === true) {
// Convert args to an itterable array
const values = [...args];
if (this.initialised !== true) return;
values.forEach((item) => {
if (isType('Object', item)) {
if (!item.value) return;
// If we are dealing with a select input, we need to create an option first
// that is then selected. For text inputs we can just add items normally.
if (this.passedElement.type !== 'text') {
this._addChoice(true, false, item.value, item.label, -1);
} else {
this._addItem(item.value, item.label, item.id);
}
} else if (isType('String', item)) {
if (this.passedElement.type !== 'text') {
this._addChoice(true, false, item, item, -1);
} else {
this._addItem(item);
}
// Convert args to an itterable array
const values = [...args];
values.forEach((item) => {
if (isType('Object', item)) {
if (!item.value) return;
// If we are dealing with a select input, we need to create an option first
// that is then selected. For text inputs we can just add items normally.
if (this.passedElement.type !== 'text') {
this._addChoice(true, false, item.value, item.label, -1);
} else {
this._addItem(item.value, item.label, item.id);
}
});
}
} else if (isType('String', item)) {
if (this.passedElement.type !== 'text') {
this._addChoice(true, false, item, item, -1);
} else {
this._addItem(item);
}
}
});
return this;
}
@ -506,29 +508,29 @@ export default class Choices {
* @public
*/
setValueByChoice(value) {
if (this.passedElement.type !== 'text') {
const choices = this.store.getChoices();
// If only one value has been passed, convert to array
const choiceValue = isType('Array', value) ? value : [value];
if (this.passedElement.type === 'text') return;
// Loop through each value and
choiceValue.forEach((val) => {
const foundChoice = choices.find((choice) => {
// Check 'value' property exists and the choice isn't already selected
return choice.value === val;
});
const choices = this.store.getChoices();
// If only one value has been passed, convert to array
const choiceValue = isType('Array', value) ? value : [value];
if (foundChoice) {
if (!foundChoice.selected) {
this._addItem(foundChoice.value, foundChoice.label, foundChoice.id);
} else {
console.warn('Attempting to select choice already selected');
}
} else {
console.warn('Attempting to select choice that does not exist');
}
// Loop through each value and
choiceValue.forEach((val) => {
const foundChoice = choices.find((choice) => {
// Check 'value' property exists and the choice isn't already selected
return choice.value === val;
});
}
if (foundChoice) {
if (!foundChoice.selected) {
this._addItem(foundChoice.value, foundChoice.label, foundChoice.id);
} else {
console.warn('Attempting to select choice already selected');
}
} else {
console.warn('Attempting to select choice that does not exist');
}
});
return this;
}
@ -541,20 +543,20 @@ export default class Choices {
* @public
*/
setChoices(choices, value, label) {
if (this.initialised === true) {
if (this.passedElement.type === 'select-one' || this.passedElement.type === 'select-multiple') {
if (!isType('Array', choices) || !value) return;
if (this.initialised !== true) return;
if (choices && choices.length) {
this.containerOuter.classList.remove(this.config.classNames.loadingState);
choices.forEach((result, index) => {
if (result.choices) {
this._addGroup(result, index);
} else {
this._addChoice(result.selected ? result.selected : false, result.disabled ? result.disabled : false, result[value], result[label]);
}
});
}
if (this.passedElement.type === 'select-one' || this.passedElement.type === 'select-multiple') {
if (!isType('Array', choices) || !value) return;
if (choices && choices.length) {
this.containerOuter.classList.remove(this.config.classNames.loadingState);
choices.forEach((result, index) => {
if (result.choices) {
this._addGroup(result, index);
} else {
this._addChoice(result.selected ? result.selected : false, result.disabled ? result.disabled : false, result[value], result[label]);
}
});
}
}
return this;
@ -628,43 +630,40 @@ export default class Choices {
* @public
*/
ajax(fn) {
if (this.initialised === true) {
if (this.passedElement.type === 'select-one' || this.passedElement.type === 'select-multiple') {
this.containerOuter.classList.add(this.config.classNames.loadingState);
this.containerOuter.setAttribute('aria-busy', 'true');
if (this.passedElement.type === 'select-one') {
const placeholderItem = this._getTemplate('placeholder', this.config.loadingText);
this.itemList.appendChild(placeholderItem);
} else {
this.input.placeholder = this.config.loadingText;
}
if (this.initialised !== true) return;
const callback = (results, value, label) => {
if (!isType('Array', results) || !value) return;
if (results && results.length) {
// Remove loading states/text
this.containerOuter.classList.remove(this.config.classNames.loadingState);
if (this.passedElement.type === 'select-multiple') {
const placeholder = this.config.placeholder ? this.config.placeholderValue || this.passedElement.getAttribute('placeholder') : false;
if (placeholder) {
this.input.placeholder = placeholder;
}
}
// Add each result as a choice
results.forEach((result, index) => {
// Select first choice in list if single select input
if (index === 0 && this.passedElement.type === 'select-one') {
this._addChoice(true, false, result[value], result[label]);
} else {
this._addChoice(false, false, result[value], result[label]);
}
});
}
this.containerOuter.removeAttribute('aria-busy');
};
fn(callback);
if (this.passedElement.type === 'select-one' || this.passedElement.type === 'select-multiple') {
this.containerOuter.classList.add(this.config.classNames.loadingState);
this.containerOuter.setAttribute('aria-busy', 'true');
if (this.passedElement.type === 'select-one') {
const placeholderItem = this._getTemplate('placeholder', this.config.loadingText);
this.itemList.appendChild(placeholderItem);
} else {
this.input.placeholder = this.config.loadingText;
}
const callback = (results, value, label) => {
if (!isType('Array', results) || !value) return;
if (results && results.length) {
// Remove loading states/text
this.containerOuter.classList.remove(this.config.classNames.loadingState);
if (this.passedElement.type === 'select-multiple') {
const placeholder = this.config.placeholder ? this.config.placeholderValue || this.passedElement.getAttribute('placeholder') : false;
if (placeholder) {
this.input.placeholder = placeholder;
}
}
// Add each result as a choice
results.forEach((result, index) => {
this._addChoice(false, false, result[value], result[label]);
});
}
this.containerOuter.removeAttribute('aria-busy');
};
fn(callback);
}
return this;
}
@ -867,6 +866,7 @@ export default class Choices {
*/
_searchChoices(value) {
if (!value) return;
if (this.input === document.activeElement) {
const choices = this.store.getChoices();
const hasUnactiveChoices = choices.some((option) => option.active !== true);
@ -1880,7 +1880,6 @@ export default class Choices {
const passedOptions = Array.from(this.passedElement.options);
const allChoices = [];
// Create array of options from option elements
passedOptions.forEach((o) => {
allChoices.push({
@ -1895,6 +1894,7 @@ export default class Choices {
allChoices
.concat(this.presetChoices)
.forEach((o, index) => {
// Pre-select first choice if it's a single select
if (index === 0 && this.passedElement.type === 'select-one') {
this._addChoice(true, o.disabled ? o.disabled : false, o.value, o.label);
} else {
@ -1927,26 +1927,29 @@ export default class Choices {
const groupFragment = fragment || document.createDocumentFragment();
const filter = this.config.sortFilter;
groups
.sort(filter)
.forEach((group) => {
// Grab options that are children of this group
const groupChoices = choices.filter((choice) => {
if (this.passedElement.type === 'select-one') {
return choice.groupId === group.id;
}
// If sorting is enabled, filter groups
if (this.config.shouldSort) {
groups.sort(filter);
}
return choice.groupId === group.id && !choice.selected;
});
if (groupChoices.length >= 1) {
const dropdownGroup = this._getTemplate('choiceGroup', group);
groupFragment.appendChild(dropdownGroup);
this.renderChoices(groupChoices, groupFragment);
groups.forEach((group) => {
// Grab options that are children of this group
const groupChoices = choices.filter((choice) => {
if (this.passedElement.type === 'select-one') {
return choice.groupId === group.id;
}
return choice.groupId === group.id && !choice.selected;
});
if (groupChoices.length >= 1) {
const dropdownGroup = this._getTemplate('choiceGroup', group);
groupFragment.appendChild(dropdownGroup);
this.renderChoices(groupChoices, groupFragment);
}
});
return groupFragment;
}
@ -1960,20 +1963,20 @@ export default class Choices {
renderChoices(choices, fragment) {
// Create a fragment to store our list items (so we don't have to update the DOM for each item)
const choicesFragment = fragment || document.createDocumentFragment();
const filter = this.isSearching ? sortByScore : this.config.sortFilter;
// If sorting is enabled or the user is searching, filter choices
if (this.config.shouldSort || this.isSearching) {
const filter = this.isSearching ? sortByScore : this.config.sortFilter;
choices.sort(filter);
}
choices
.forEach((choice) => {
const dropdownItem = this._getTemplate('choice', choice);
if (this.passedElement.type === 'select-one') {
choicesFragment.appendChild(dropdownItem);
} else if (!choice.selected) {
choicesFragment.appendChild(dropdownItem);
}
});
choices.forEach((choice) => {
const dropdownItem = this._getTemplate('choice', choice);
const shouldRender = this.passedElement.type === 'select-one' || !choice.selected;
if (shouldRender) {
choicesFragment.appendChild(dropdownItem);
}
});
return choicesFragment;
}

View file

@ -41,7 +41,9 @@
<h1 class="visible-ie">Choices.js</h1>
<p>Choices.js is a lightweight, configurable select box/text input plugin. Similar to Select2 and Selectize but without the jQuery dependency.</p>
<p>For all config options, visit the <a href="https://github.com/jshjohnson/Choices">GitHub repo</a>.</p>
<hr>
<h2>Text inputs</h2>
<label for="choices-1">Limited to 5 values with remove button</label>
<input class="form-control" id="choices-1" type="text" value="preset-1,preset-2" placeholder="Enter something">
@ -170,6 +172,28 @@
<label for="choices-17">Option selected via config</label>
<select class="form-control" name="choices-17" id="choices-17" placeholder="This is a placeholder"></select>
<label for="choices-18">Options without sorting</label>
<select class="form-control" name="choices-18" id="choices-18" placeholder="This is a placeholder">
<option value="Madrid">Madrid</option>
<option value="Toronto">Toronto</option>
<option value="Vancouver">Vancouver</option>
<option value="London">London</option>
<option value="Manchester">Manchester</option>
<option value="Liverpool">Liverpool</option>
<option value="Paris">Paris</option>
<option value="Malaga">Malaga</option>
<option value="Washington" disabled>Washington</option>
<option value="Lyon">Lyon</option>
<option value="Marseille">Marseille</option>
<option value="Hamburg">Hamburg</option>
<option value="Munich">Munich</option>
<option value="Barcelona">Barcelona</option>
<option value="Berlin">Berlin</option>
<option value="Montreal">Montreal</option>
<option value="New York">New York</option>
<option value="Michigan">Michigan</option>
</select>
<p>Below is an example of how you could have two select inputs depend on eachother. 'Boroughs' will only be enabled if the value of 'States' is 'New York'</p>
<label for="cities">States</label>
<select class="form-control" name="cities" id="cities" placeholder="Choose a state">
@ -335,6 +359,10 @@
],
}).setValueByChoice('Two');
var example16 = new Choices('#choices-18', {
shouldSort: false,
});
var cities = new Choices(document.getElementById('cities'), {
callbackOnChange: function(value) {
if(value === 'New York') {