diff --git a/assets/scripts/src/choices.js b/assets/scripts/src/choices.js index edb7321..a470163 100644 --- a/assets/scripts/src/choices.js +++ b/assets/scripts/src/choices.js @@ -117,6 +117,9 @@ export class Choices { this._onMouseOver = this._onMouseOver.bind(this); this._onPaste = this._onPaste.bind(this); this._onInput = this._onInput.bind(this); + + // Focus containerOuter but not show dropdown if true + this._focusAndHideDropdown = false; // Cutting the mustard const cuttingTheMustard = 'querySelector' in document && 'addEventListener' in document && 'classList' in document.createElement("div"); @@ -580,6 +583,12 @@ export class Choices { console.error('callbackOnChange: Callback is not a function'); } } + + // Keep focus on select-one element + if(this.passedElement.type === 'select-one'){ + this._focusAndHideDropdown = true; + this.containerOuter.focus(); + } } /** @@ -655,7 +664,7 @@ export class Choices { * @return */ _onKeyDown(e) { - if(e.target !== this.input) return; + if(e.target !== this.input && e.target !== this.containerOuter) return; const ctrlDownKey = e.ctrlKey || e.metaKey; const backKey = 46; @@ -700,9 +709,18 @@ export class Choices { this._handleEnter(activeItems, value); } + // Show dropdown if focus + if(!hasActiveDropdown && this.passedElement.type === 'select-one'){ + e.preventDefault(); + this.showDropdown(); + if(this.canSearch) { + this.input.focus(); + } + } + if(hasActiveDropdown) { const highlighted = this.dropdown.querySelector(`.${this.config.classNames.highlightedState}`); - + if(highlighted) { const value = highlighted.getAttribute('data-value'); const label = highlighted.innerHTML; @@ -728,7 +746,16 @@ export class Choices { case downKey: case upKey: // If up or down key is pressed, traverse through options - if(hasActiveDropdown) { + if(hasActiveDropdown || this.passedElement.type === 'select-one') { + + // Show dropdown if focus + if(!hasActiveDropdown){ + this.showDropdown(); + if(this.canSearch) { + this.input.focus(); + } + } + const currentEl = this.dropdown.querySelector(`.${this.config.classNames.highlightedState}`); const directionInt = e.keyCode === downKey ? 1 : -1; let nextEl; @@ -886,12 +913,16 @@ export class Choices { if(this.passedElement.type !== 'text') { // For select inputs we always want to show the dropdown if it isn't already showing this.showDropdown(); + if(this.canSearch) { + this.input.focus(); + } + }else{ + // If input is not in focus, it ought to be + if(this.input !== document.activeElement) { + this.input.focus(); + } } - - // If input is not in focus, it ought to be - if(this.input !== document.activeElement) { - this.input.focus(); - } + } else if(this.passedElement.type === 'select-one' && this.dropdown.classList.contains(this.config.classNames.activeState) && e.target === this.containerInner) { this.hideDropdown(); } @@ -1004,9 +1035,12 @@ export class Choices { } else if(this.passedElement.type === 'select-one' && e.target === this.containerOuter && !hasActiveDropdown) { this.containerOuter.classList.add(this.config.classNames.focusState); this.showDropdown(); - if(this.canSearch) { + + if(!this._focusAndHideDropdown){ this.input.focus(); } + + this._focusAndHideDropdown = false; } } @@ -1040,7 +1074,8 @@ export class Choices { */ _regexFilter(value) { if(!value) return; - const expression = new RegExp(this.config.regexFilter, 'i'); + const regex = this.config.regexFilter; + const expression = new RegExp(regex.source, 'i'); return expression.test(value); } @@ -1631,6 +1666,10 @@ export class Choices { if(this.passedElement.type && this.passedElement.type === 'select-one') { this.containerOuter.addEventListener('focus', this._onFocus); + + if(!this.canSearch) { + this.containerOuter.addEventListener('blur', this._onBlur); + } } this.input.addEventListener('input', this._onInput); @@ -1652,6 +1691,10 @@ export class Choices { if(this.passedElement.type && this.passedElement.type === 'select-one') { this.containerOuter.removeEventListener('focus', this._onFocus); + + if(!this.canSearch) { + this.containerOuter.removeEventListener('blur', this._onBlur); + } } this.input.removeEventListener('input', this._onInput); diff --git a/assets/styles/css/choices.css b/assets/styles/css/choices.css index 2b97224..384f4e7 100644 --- a/assets/styles/css/choices.css +++ b/assets/styles/css/choices.css @@ -15,6 +15,8 @@ user-select: none; } .choices.is-disabled .choices__item { cursor: not-allowed; } + .choices:focus { + outline: none; } .choices[data-type*="select-one"] .choices__inner { cursor: pointer; diff --git a/assets/styles/scss/choices.scss b/assets/styles/scss/choices.scss index d42c20b..72a84c4 100644 --- a/assets/styles/scss/choices.scss +++ b/assets/styles/scss/choices.scss @@ -24,6 +24,9 @@ $choices-button-icon-path: '../../icons/cross.svg'; } .choices__item { cursor: not-allowed; } } + &:focus{ + outline: none; + } } .choices[data-type*="select-one"] {