mirror of
https://github.com/Choices-js/Choices.git
synced 2024-05-21 06:56:34 +02:00
Eliminate excessive searches
This commit is contained in:
parent
d9cb983262
commit
1a9622aaff
4
assets/scripts/dist/choices.min.js
vendored
4
assets/scripts/dist/choices.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -86,11 +86,13 @@ export class Choices {
|
||||||
this.initialised = false;
|
this.initialised = false;
|
||||||
this.currentState = {};
|
this.currentState = {};
|
||||||
this.prevState = {};
|
this.prevState = {};
|
||||||
|
this.currentValue = '';
|
||||||
|
|
||||||
// Retrieve triggering element (i.e. element with 'data-choice' trigger)
|
// Retrieve triggering element (i.e. element with 'data-choice' trigger)
|
||||||
this.passedElement = isType('String', element) ? document.querySelector(element) : element;
|
this.passedElement = isType('String', element) ? document.querySelector(element) : element;
|
||||||
|
|
||||||
this.highlightPosition = 0;
|
this.highlightPosition = 0;
|
||||||
|
this.canSearch = this.options.allowSearch;
|
||||||
|
|
||||||
// Assign preset items from passed object first
|
// Assign preset items from passed object first
|
||||||
this.presetItems = this.options.items;
|
this.presetItems = this.options.items;
|
||||||
|
@ -224,10 +226,13 @@ export class Choices {
|
||||||
this.showDropdown();
|
this.showDropdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.canSearch = this.options.allowSearch;
|
||||||
|
|
||||||
switch (e.keyCode) {
|
switch (e.keyCode) {
|
||||||
case aKey:
|
case aKey:
|
||||||
// If CTRL + A or CMD + A have been pressed and there are items to select
|
// If CTRL + A or CMD + A have been pressed and there are items to select
|
||||||
if(ctrlDownKey && hasItems) {
|
if(ctrlDownKey && hasItems) {
|
||||||
|
this.canSearch = false;
|
||||||
if(this.options.removeItems && !this.input.value && this.options.selectAll && this.input === document.activeElement) {
|
if(this.options.removeItems && !this.input.value && this.options.selectAll && this.input === document.activeElement) {
|
||||||
this.selectAll(this.itemList.children);
|
this.selectAll(this.itemList.children);
|
||||||
}
|
}
|
||||||
|
@ -235,7 +240,6 @@ export class Choices {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case enterKey:
|
case enterKey:
|
||||||
|
|
||||||
// If enter key is pressed and the input has a value
|
// If enter key is pressed and the input has a value
|
||||||
if(e.target.value && this.passedElement.type === 'text') {
|
if(e.target.value && this.passedElement.type === 'text') {
|
||||||
const value = this.input.value;
|
const value = this.input.value;
|
||||||
|
@ -275,6 +279,8 @@ export class Choices {
|
||||||
const directionInt = e.keyCode === downKey ? 1 : -1;
|
const directionInt = e.keyCode === downKey ? 1 : -1;
|
||||||
let nextEl;
|
let nextEl;
|
||||||
|
|
||||||
|
this.canSearch = false;
|
||||||
|
|
||||||
if(currentEl) {
|
if(currentEl) {
|
||||||
nextEl = getAdjacentEl(currentEl, '[data-option-selectable]', directionInt);
|
nextEl = getAdjacentEl(currentEl, '[data-option-selectable]', directionInt);
|
||||||
} else {
|
} else {
|
||||||
|
@ -289,6 +295,10 @@ export class Choices {
|
||||||
}
|
}
|
||||||
this.highlightOption(nextEl);
|
this.highlightOption(nextEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prevent default to maintain cursor position whilst
|
||||||
|
// traversing dropdown options
|
||||||
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -313,6 +323,7 @@ export class Choices {
|
||||||
*/
|
*/
|
||||||
onKeyUp(e) {
|
onKeyUp(e) {
|
||||||
if(e.target !== this.input) return;
|
if(e.target !== this.input) return;
|
||||||
|
const keyString = String.fromCharCode(event.keyCode);
|
||||||
|
|
||||||
// We are typing into a text input and have a value, we want to show a dropdown
|
// We are typing into a text input and have a value, we want to show a dropdown
|
||||||
// notice. Otherwise hide the dropdown
|
// notice. Otherwise hide the dropdown
|
||||||
|
@ -320,7 +331,6 @@ export class Choices {
|
||||||
const hasActiveDropdown = this.dropdown.classList.contains(this.options.classNames.activeState);
|
const hasActiveDropdown = this.dropdown.classList.contains(this.options.classNames.activeState);
|
||||||
let dropdownItem;
|
let dropdownItem;
|
||||||
if(this.input.value) {
|
if(this.input.value) {
|
||||||
|
|
||||||
const activeItems = this.store.getItemsFilteredByActive();
|
const activeItems = this.store.getItemsFilteredByActive();
|
||||||
const isUnique = !activeItems.some((item) => item.value === this.input.value);
|
const isUnique = !activeItems.some((item) => item.value === this.input.value);
|
||||||
|
|
||||||
|
@ -344,26 +354,29 @@ export class Choices {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.options.allowSearch) {
|
// If we have enabled text search
|
||||||
|
if(this.canSearch) {
|
||||||
if(this.input === document.activeElement) {
|
if(this.input === document.activeElement) {
|
||||||
const options = this.store.getOptions();
|
const options = this.store.getOptions();
|
||||||
const hasUnactiveOptions = options.some((option) => option.active !== true);
|
const hasUnactiveOptions = options.some((option) => option.active !== true);
|
||||||
|
|
||||||
// Check that have a value to search
|
// Check that we have a value to search and the input was an alphanumeric character
|
||||||
if(this.input.value && options.length) {
|
if(this.input.value && options.length && /[a-zA-Z0-9-_ ]/.test(keyString)) {
|
||||||
const handleFilter = () => {
|
const handleFilter = () => {
|
||||||
if(this.input.value.length >= 1) {
|
const newValue = this.input.value.trim();
|
||||||
const haystack = this.store.getOptionsFiltedBySelectable();
|
const currentValue = this.currentValue.trim();
|
||||||
const needle = this.input.value;
|
|
||||||
|
|
||||||
|
if(newValue.length >= 1 && newValue !== currentValue + ' ') {
|
||||||
|
const haystack = this.store.getOptionsFiltedBySelectable();
|
||||||
|
const needle = newValue;
|
||||||
const fuse = new Fuse(haystack, {
|
const fuse = new Fuse(haystack, {
|
||||||
keys: ['label', 'value'],
|
keys: ['label', 'value'],
|
||||||
shouldSort: true,
|
shouldSort: true,
|
||||||
include: 'score',
|
include: 'score',
|
||||||
});
|
});
|
||||||
|
|
||||||
const results = fuse.search(needle);
|
const results = fuse.search(needle);
|
||||||
|
|
||||||
|
this.currentValue = newValue;
|
||||||
this.highlightPosition = 0;
|
this.highlightPosition = 0;
|
||||||
this.isSearching = true;
|
this.isSearching = true;
|
||||||
this.store.dispatch(filterOptions(results));
|
this.store.dispatch(filterOptions(results));
|
||||||
|
@ -380,6 +393,11 @@ export class Choices {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Input event
|
||||||
|
* @param {Object} e Event
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
onInput(e) {
|
onInput(e) {
|
||||||
if(this.passedElement.type !== 'select-one') {
|
if(this.passedElement.type !== 'select-one') {
|
||||||
this.input.style.width = getWidthOfInput(this.input);
|
this.input.style.width = getWidthOfInput(this.input);
|
||||||
|
@ -890,6 +908,16 @@ export class Choices {
|
||||||
isActive ? this.hideDropdown() : this.showDropdown();
|
isActive ? this.hideDropdown() : this.showDropdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set value of input
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
setValue(values) {
|
||||||
|
if(isType('Array', values)) {
|
||||||
|
console.log(values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable
|
* Disable
|
||||||
* @return {[type]} [description]
|
* @return {[type]} [description]
|
||||||
|
|
|
@ -166,7 +166,7 @@
|
||||||
items: ['josh@joshuajohnson.co.uk', { value: 'joe@bloggs.co.uk', label: 'Joe Bloggs' } ],
|
items: ['josh@joshuajohnson.co.uk', { value: 'joe@bloggs.co.uk', label: 'Joe Bloggs' } ],
|
||||||
});
|
});
|
||||||
|
|
||||||
const choices7 = new Choices('#choices-7', { allowSearch: false });
|
const choices7 = new Choices('#choices-7', { allowSearch: false }).setValue(['Set value 1', 'Set value 2']);
|
||||||
|
|
||||||
const choicesAjax = new Choices('#choices-12').ajax((callback) => {
|
const choicesAjax = new Choices('#choices-12').ajax((callback) => {
|
||||||
fetch('https://api.discogs.com/artists/391170/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW')
|
fetch('https://api.discogs.com/artists/391170/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW')
|
||||||
|
|
Loading…
Reference in a new issue