mirror of
https://github.com/Choices-js/Choices.git
synced 2024-06-20 06:35:34 +02:00
Refactor adding predefined groups/items/choices
This commit is contained in:
parent
c68d1ad610
commit
43c020edd1
|
@ -45,6 +45,8 @@ import {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {import('../../types/index').Choices.Choice} Choice
|
* @typedef {import('../../types/index').Choices.Choice} Choice
|
||||||
|
* @typedef {import('../../types/index').Choices.Item} Item
|
||||||
|
* @typedef {import('../../types/index').Choices.Group} Group
|
||||||
* @typedef {import('../../types/index').Choices.Options} Options
|
* @typedef {import('../../types/index').Choices.Options} Options
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -174,16 +176,31 @@ class Choices {
|
||||||
this._idNames = {
|
this._idNames = {
|
||||||
itemChoice: 'item-choice',
|
itemChoice: 'item-choice',
|
||||||
};
|
};
|
||||||
|
// Assign preset groups from passed element
|
||||||
|
this._presetGroups = this.passedElement.optionGroups;
|
||||||
// Assign preset choices from passed object
|
// Assign preset choices from passed object
|
||||||
this._presetChoices = this.config.choices;
|
this._presetChoices = this.config.choices;
|
||||||
// Assign preset items from passed object first
|
// Assign preset items from passed object first
|
||||||
this._presetItems = this.config.items;
|
this._presetItems = this.config.items;
|
||||||
// Then add any values passed from attribute
|
// Add any values passed from attribute
|
||||||
if (this.passedElement.value) {
|
if (this.passedElement.value) {
|
||||||
this._presetItems = this._presetItems.concat(
|
this._presetItems = this._presetItems.concat(
|
||||||
this.passedElement.value.split(this.config.delimiter),
|
this.passedElement.value.split(this.config.delimiter),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// Create array of choices from option elements
|
||||||
|
if (this.passedElement.options) {
|
||||||
|
this.passedElement.options.forEach(o => {
|
||||||
|
this._presetChoices.push({
|
||||||
|
value: o.value,
|
||||||
|
label: o.innerHTML,
|
||||||
|
selected: o.selected,
|
||||||
|
disabled: o.disabled || o.parentNode.disabled,
|
||||||
|
placeholder: o.value === '' || o.hasAttribute('placeholder'),
|
||||||
|
customProperties: o.getAttribute('data-custom-properties'),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this._render = this._render.bind(this);
|
this._render = this._render.bind(this);
|
||||||
this._onFocus = this._onFocus.bind(this);
|
this._onFocus = this._onFocus.bind(this);
|
||||||
|
@ -2024,7 +2041,7 @@ class Choices {
|
||||||
this.input.placeholder = this.config.searchPlaceholderValue || '';
|
this.input.placeholder = this.config.searchPlaceholderValue || '';
|
||||||
} else if (this._placeholderValue) {
|
} else if (this._placeholderValue) {
|
||||||
this.input.placeholder = this._placeholderValue;
|
this.input.placeholder = this._placeholderValue;
|
||||||
this.input.setWidth(true);
|
this.input.setWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.containerOuter.element.appendChild(this.containerInner.element);
|
this.containerOuter.element.appendChild(this.containerInner.element);
|
||||||
|
@ -2045,116 +2062,105 @@ class Choices {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._isSelectElement) {
|
if (this._isSelectElement) {
|
||||||
this._addPredefinedChoices();
|
this._highlightPosition = 0;
|
||||||
} else if (this._isTextElement) {
|
this._isSearching = false;
|
||||||
this._addPredefinedItems();
|
this._setLoading(true);
|
||||||
|
|
||||||
|
if (this._presetGroups.length) {
|
||||||
|
this._addPredefinedGroups(this._presetGroups);
|
||||||
|
} else {
|
||||||
|
this._addPredefinedChoices(this._presetChoices);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._isTextElement) {
|
||||||
|
this._addPredefinedItems(this._presetItems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_addPredefinedChoices() {
|
_addPredefinedGroups(groups) {
|
||||||
const passedGroups = this.passedElement.optionGroups;
|
// If we have a placeholder option
|
||||||
|
const placeholderChoice = this.passedElement.placeholderOption;
|
||||||
this._highlightPosition = 0;
|
if (
|
||||||
this._isSearching = false;
|
placeholderChoice &&
|
||||||
this._setLoading(true);
|
placeholderChoice.parentNode.tagName === 'SELECT'
|
||||||
|
) {
|
||||||
if (passedGroups && passedGroups.length) {
|
this._addChoice({
|
||||||
// If we have a placeholder option
|
value: placeholderChoice.value,
|
||||||
const placeholderChoice = this.passedElement.placeholderOption;
|
label: placeholderChoice.innerHTML,
|
||||||
if (
|
isSelected: placeholderChoice.selected,
|
||||||
placeholderChoice &&
|
isDisabled: placeholderChoice.disabled,
|
||||||
placeholderChoice.parentNode.tagName === 'SELECT'
|
placeholder: true,
|
||||||
) {
|
|
||||||
this._addChoice({
|
|
||||||
value: placeholderChoice.value,
|
|
||||||
label: placeholderChoice.innerHTML,
|
|
||||||
isSelected: placeholderChoice.selected,
|
|
||||||
isDisabled: placeholderChoice.disabled,
|
|
||||||
placeholder: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
passedGroups.forEach(group =>
|
|
||||||
this._addGroup({
|
|
||||||
group,
|
|
||||||
id: group.id || null,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
const passedOptions = this.passedElement.options;
|
|
||||||
const filter = this.config.sorter;
|
|
||||||
const allChoices = this._presetChoices;
|
|
||||||
|
|
||||||
// Create array of options from option elements
|
|
||||||
passedOptions.forEach(o => {
|
|
||||||
allChoices.push({
|
|
||||||
value: o.value,
|
|
||||||
label: o.innerHTML,
|
|
||||||
selected: o.selected,
|
|
||||||
disabled: o.disabled || o.parentNode.disabled,
|
|
||||||
placeholder: o.value === '' || o.hasAttribute('placeholder'),
|
|
||||||
customProperties: o.getAttribute('data-custom-properties'),
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// If sorting is enabled or the user is searching, filter choices
|
groups.forEach(group =>
|
||||||
if (this.config.shouldSort) {
|
this._addGroup({
|
||||||
allChoices.sort(filter);
|
group,
|
||||||
}
|
id: group.id || null,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Determine whether there is a selected choice
|
_addPredefinedChoices(choices) {
|
||||||
const hasSelectedChoice = allChoices.some(choice => choice.selected);
|
// If sorting is enabled or the user is searching, filter choices
|
||||||
const handleChoice = (choice, index) => {
|
if (this.config.shouldSort) {
|
||||||
const { value, label, customProperties, placeholder } = choice;
|
choices.sort(this.config.sorter);
|
||||||
|
}
|
||||||
|
|
||||||
if (this._isSelectElement) {
|
// Determine whether there is a selected choice
|
||||||
// If the choice is actually a group
|
const hasSelectedChoice = choices.some(choice => choice.selected);
|
||||||
if (choice.choices) {
|
|
||||||
this._addGroup({
|
|
||||||
group: choice,
|
|
||||||
id: choice.id || null,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// If there is a selected choice already or the choice is not
|
|
||||||
// the first in the array, add each choice normally
|
|
||||||
// Otherwise pre-select the first choice in the array if it's a single select
|
|
||||||
const shouldPreselect =
|
|
||||||
this._isSelectOneElement && !hasSelectedChoice && index === 0;
|
|
||||||
const isSelected = shouldPreselect ? true : choice.selected;
|
|
||||||
const isDisabled = shouldPreselect ? false : choice.disabled;
|
|
||||||
|
|
||||||
this._addChoice({
|
// Add each choice
|
||||||
value,
|
choices.forEach((choice, index) => {
|
||||||
label,
|
const { value, label, customProperties, placeholder } = choice;
|
||||||
isSelected,
|
|
||||||
isDisabled,
|
if (this._isSelectElement) {
|
||||||
customProperties,
|
// If the choice is actually a group
|
||||||
placeholder,
|
if (choice.choices) {
|
||||||
});
|
this._addGroup({
|
||||||
}
|
group: choice,
|
||||||
|
id: choice.id || null,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
|
// If there is a selected choice already or the choice is not
|
||||||
|
// the first in the array, add each choice normally
|
||||||
|
// Otherwise pre-select the first choice in the array if it's a single select
|
||||||
|
const shouldPreselect =
|
||||||
|
this._isSelectOneElement && !hasSelectedChoice && index === 0;
|
||||||
|
const isSelected = shouldPreselect ? true : choice.selected;
|
||||||
|
const isDisabled = shouldPreselect ? false : choice.disabled;
|
||||||
|
|
||||||
this._addChoice({
|
this._addChoice({
|
||||||
value,
|
value,
|
||||||
label,
|
label,
|
||||||
isSelected: choice.selected,
|
isSelected,
|
||||||
isDisabled: choice.disabled,
|
isDisabled,
|
||||||
customProperties,
|
customProperties,
|
||||||
placeholder,
|
placeholder,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
} else {
|
||||||
|
this._addChoice({
|
||||||
// Add each choice
|
value,
|
||||||
allChoices.forEach((choice, index) => handleChoice(choice, index));
|
label,
|
||||||
}
|
isSelected: choice.selected,
|
||||||
|
isDisabled: choice.disabled,
|
||||||
this._setLoading(false);
|
customProperties,
|
||||||
|
placeholder,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_addPredefinedItems() {
|
/**
|
||||||
const handlePresetItem = item => {
|
* @param {Item[]} items
|
||||||
const itemType = getType(item);
|
*/
|
||||||
if (itemType === 'Object' && item.value) {
|
_addPredefinedItems(items) {
|
||||||
|
items.forEach(item => {
|
||||||
|
if (typeof item === 'object' && item.value) {
|
||||||
this._addItem({
|
this._addItem({
|
||||||
value: item.value,
|
value: item.value,
|
||||||
label: item.label,
|
label: item.label,
|
||||||
|
@ -2162,14 +2168,14 @@ class Choices {
|
||||||
customProperties: item.customProperties,
|
customProperties: item.customProperties,
|
||||||
placeholder: item.placeholder,
|
placeholder: item.placeholder,
|
||||||
});
|
});
|
||||||
} else if (itemType === 'String') {
|
}
|
||||||
|
|
||||||
|
if (typeof item === 'string') {
|
||||||
this._addItem({
|
this._addItem({
|
||||||
value: item,
|
value: item,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
this._presetItems.forEach(item => handlePresetItem(item));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_setChoiceOrItem(item) {
|
_setChoiceOrItem(item) {
|
||||||
|
|
Loading…
Reference in a new issue