mirror of
https://github.com/Choices-js/Choices.git
synced 2024-06-05 07:22:23 +02:00
Begin to move passedElement logic into wrapped component
This commit is contained in:
parent
82cb17ec2b
commit
bd77f458b3
|
@ -4,6 +4,8 @@ import Dropdown from './components/dropdown';
|
||||||
import Container from './components/container';
|
import Container from './components/container';
|
||||||
import Input from './components/input';
|
import Input from './components/input';
|
||||||
import List from './components/list';
|
import List from './components/list';
|
||||||
|
import WrappedInput from './components/wrapped-input';
|
||||||
|
import WrappedSelect from './components/wrapped-select';
|
||||||
import { DEFAULT_CONFIG, DEFAULT_CLASSNAMES, EVENTS, KEY_CODES } from './constants';
|
import { DEFAULT_CONFIG, DEFAULT_CLASSNAMES, EVENTS, KEY_CODES } from './constants';
|
||||||
import { TEMPLATES } from './templates';
|
import { TEMPLATES } from './templates';
|
||||||
import { addChoice, filterChoices, activateChoices, clearChoices } from './actions/choices';
|
import { addChoice, filterChoices, activateChoices, clearChoices } from './actions/choices';
|
||||||
|
@ -71,8 +73,19 @@ class Choices {
|
||||||
this.currentValue = '';
|
this.currentValue = '';
|
||||||
|
|
||||||
// Retrieve triggering element (i.e. element with 'data-choice' trigger)
|
// Retrieve triggering element (i.e. element with 'data-choice' trigger)
|
||||||
this.element = element;
|
const passedElement = isType('String', element) ? document.querySelector(element) : element;
|
||||||
this.passedElement = isType('String', element) ? document.querySelector(element) : element;
|
|
||||||
|
this.isTextElement = passedElement.type === 'text';
|
||||||
|
this.isSelectOneElement = passedElement.type === 'select-one';
|
||||||
|
this.isSelectMultipleElement = passedElement.type === 'select-multiple';
|
||||||
|
this.isSelectElement = this.isSelectOneElement || this.isSelectMultipleElement;
|
||||||
|
this.isValidElementType = this.isTextElement || this.isSelectElement;
|
||||||
|
|
||||||
|
if (this.isTextElement) {
|
||||||
|
this.passedElement = new WrappedInput(this, passedElement, this.config.classNames);
|
||||||
|
} else if (this.isSelectElement) {
|
||||||
|
this.passedElement = new WrappedSelect(this, passedElement, this.config.classNames);
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.passedElement) {
|
if (!this.passedElement) {
|
||||||
if (!this.config.silent) {
|
if (!this.config.silent) {
|
||||||
|
@ -81,11 +94,6 @@ class Choices {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isTextElement = this.passedElement.type === 'text';
|
|
||||||
this.isSelectOneElement = this.passedElement.type === 'select-one';
|
|
||||||
this.isSelectMultipleElement = this.passedElement.type === 'select-multiple';
|
|
||||||
this.isSelectElement = this.isSelectOneElement || this.isSelectMultipleElement;
|
|
||||||
this.isValidElementType = this.isTextElement || this.isSelectElement;
|
|
||||||
this.isIe11 = !!(navigator.userAgent.match(/Trident/) && navigator.userAgent.match(/rv[ :]11/));
|
this.isIe11 = !!(navigator.userAgent.match(/Trident/) && navigator.userAgent.match(/rv[ :]11/));
|
||||||
this.isScrollingOnIe = false;
|
this.isScrollingOnIe = false;
|
||||||
|
|
||||||
|
@ -103,7 +111,7 @@ class Choices {
|
||||||
this.placeholder = false;
|
this.placeholder = false;
|
||||||
if (!this.isSelectOneElement) {
|
if (!this.isSelectOneElement) {
|
||||||
this.placeholder = this.config.placeholder ?
|
this.placeholder = this.config.placeholder ?
|
||||||
(this.config.placeholderValue || this.passedElement.getAttribute('placeholder')) :
|
(this.config.placeholderValue || this.passedElement.element.getAttribute('placeholder')) :
|
||||||
false;
|
false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,14 +121,14 @@ class Choices {
|
||||||
this.presetItems = this.config.items;
|
this.presetItems = this.config.items;
|
||||||
|
|
||||||
// Then add any values passed from attribute
|
// Then add any values passed from attribute
|
||||||
if (this.passedElement.value) {
|
if (this.passedElement.element.value) {
|
||||||
this.presetItems = this.presetItems.concat(
|
this.presetItems = this.presetItems.concat(
|
||||||
this.passedElement.value.split(this.config.delimiter),
|
this.passedElement.element.value.split(this.config.delimiter),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set unique base Id
|
// Set unique base Id
|
||||||
this.baseId = generateId(this.passedElement, 'choices-');
|
this.baseId = generateId(this.passedElement.element, 'choices-');
|
||||||
|
|
||||||
this.idNames = {
|
this.idNames = {
|
||||||
itemChoice: 'item-choice',
|
itemChoice: 'item-choice',
|
||||||
|
@ -149,11 +157,11 @@ class Choices {
|
||||||
console.error('Choices: Your browser doesn\'t support Choices');
|
console.error('Choices: Your browser doesn\'t support Choices');
|
||||||
}
|
}
|
||||||
|
|
||||||
const canInit = isElement(this.passedElement) && this.isValidElementType;
|
const canInit = isElement(this.passedElement.element) && this.isValidElementType;
|
||||||
|
|
||||||
if (canInit) {
|
if (canInit) {
|
||||||
// If element has already been initialised with Choices
|
// If element has already been initialised with Choices
|
||||||
if (this.passedElement.getAttribute('data-choice') === 'active') {
|
if (this.passedElement.element.getAttribute('data-choice') === 'active') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,31 +218,11 @@ class Choices {
|
||||||
|
|
||||||
// Remove all event listeners
|
// Remove all event listeners
|
||||||
this._removeEventListeners();
|
this._removeEventListeners();
|
||||||
|
this.passedElement.reveal();
|
||||||
// Reinstate passed element
|
|
||||||
this.passedElement.classList.remove(
|
|
||||||
this.config.classNames.input,
|
|
||||||
this.config.classNames.hiddenState,
|
|
||||||
);
|
|
||||||
this.passedElement.removeAttribute('tabindex');
|
|
||||||
|
|
||||||
// Recover original styles if any
|
|
||||||
const origStyle = this.passedElement.getAttribute('data-choice-orig-style');
|
|
||||||
if (origStyle) {
|
|
||||||
this.passedElement.removeAttribute('data-choice-orig-style');
|
|
||||||
this.passedElement.setAttribute('style', origStyle);
|
|
||||||
} else {
|
|
||||||
this.passedElement.removeAttribute('style');
|
|
||||||
}
|
|
||||||
this.passedElement.removeAttribute('aria-hidden');
|
|
||||||
this.passedElement.removeAttribute('data-choice');
|
|
||||||
|
|
||||||
// Re-assign values - this is weird, I know
|
|
||||||
this.passedElement.value = this.passedElement.value;
|
|
||||||
|
|
||||||
// Move passed element back to original position
|
// Move passed element back to original position
|
||||||
this.containerOuter.element.parentNode.insertBefore(
|
this.containerOuter.element.parentNode.insertBefore(
|
||||||
this.passedElement,
|
this.passedElement.element,
|
||||||
this.containerOuter.element,
|
this.containerOuter.element,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -372,8 +360,8 @@ class Choices {
|
||||||
const itemsFiltered = this.store.getItemsReducedToValues(items);
|
const itemsFiltered = this.store.getItemsReducedToValues(items);
|
||||||
const itemsFilteredString = itemsFiltered.join(this.config.delimiter);
|
const itemsFilteredString = itemsFiltered.join(this.config.delimiter);
|
||||||
// Update the value of the hidden input
|
// Update the value of the hidden input
|
||||||
this.passedElement.setAttribute('value', itemsFilteredString);
|
this.passedElement.element.setAttribute('value', itemsFilteredString);
|
||||||
this.passedElement.value = itemsFilteredString;
|
this.passedElement.element.value = itemsFilteredString;
|
||||||
} else {
|
} else {
|
||||||
const selectedOptionsFragment = document.createDocumentFragment();
|
const selectedOptionsFragment = document.createDocumentFragment();
|
||||||
const addOptionToFragment = (item) => {
|
const addOptionToFragment = (item) => {
|
||||||
|
@ -387,8 +375,8 @@ class Choices {
|
||||||
items.forEach(item => addOptionToFragment(item));
|
items.forEach(item => addOptionToFragment(item));
|
||||||
|
|
||||||
// Update selected choices
|
// Update selected choices
|
||||||
this.passedElement.innerHTML = '';
|
this.passedElement.element.innerHTML = '';
|
||||||
this.passedElement.appendChild(selectedOptionsFragment);
|
this.passedElement.element.appendChild(selectedOptionsFragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
const addItemToFragment = (item) => {
|
const addItemToFragment = (item) => {
|
||||||
|
@ -542,7 +530,7 @@ class Choices {
|
||||||
eventResponse.groupValue = group.value;
|
eventResponse.groupValue = group.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
triggerEvent(this.passedElement, EVENTS.highlightItem, eventResponse);
|
triggerEvent(this.passedElement.element, EVENTS.highlightItem, eventResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
@ -576,7 +564,7 @@ class Choices {
|
||||||
highlightItem(id, false),
|
highlightItem(id, false),
|
||||||
);
|
);
|
||||||
|
|
||||||
triggerEvent(this.passedElement, EVENTS.highlightItem, eventResponse);
|
triggerEvent(this.passedElement.element, EVENTS.highlightItem, eventResponse);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -681,7 +669,7 @@ class Choices {
|
||||||
this.dropdown.show();
|
this.dropdown.show();
|
||||||
this.input.activate(focusInput);
|
this.input.activate(focusInput);
|
||||||
|
|
||||||
triggerEvent(this.passedElement, EVENTS.showDropdown, {});
|
triggerEvent(this.passedElement.element, EVENTS.showDropdown, {});
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -699,7 +687,7 @@ class Choices {
|
||||||
this.dropdown.hide();
|
this.dropdown.hide();
|
||||||
this.input.deactivate(blurInput);
|
this.input.deactivate(blurInput);
|
||||||
|
|
||||||
triggerEvent(this.passedElement, EVENTS.hideDropdown, {});
|
triggerEvent(this.passedElement.element, EVENTS.hideDropdown, {});
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -934,11 +922,11 @@ class Choices {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.passedElement.disabled = false;
|
this.passedElement.element.disabled = false;
|
||||||
|
|
||||||
if (this.containerOuter.isDisabled) {
|
if (this.containerOuter.isDisabled) {
|
||||||
this._addEventListeners();
|
this._addEventListeners();
|
||||||
this.passedElement.removeAttribute('disabled');
|
this.passedElement.element.removeAttribute('disabled');
|
||||||
this.input.enable();
|
this.input.enable();
|
||||||
this.containerOuter.enable();
|
this.containerOuter.enable();
|
||||||
}
|
}
|
||||||
|
@ -956,11 +944,11 @@ class Choices {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.passedElement.disabled = true;
|
this.passedElement.element.disabled = true;
|
||||||
|
|
||||||
if (!this.containerOuter.isDisabled) {
|
if (!this.containerOuter.isDisabled) {
|
||||||
this._removeEventListeners();
|
this._removeEventListeners();
|
||||||
this.passedElement.setAttribute('disabled', '');
|
this.passedElement.element.setAttribute('disabled', '');
|
||||||
this.input.disable();
|
this.input.disable();
|
||||||
this.containerOuter.disable();
|
this.containerOuter.disable();
|
||||||
}
|
}
|
||||||
|
@ -1004,7 +992,7 @@ class Choices {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
triggerEvent(this.passedElement, EVENTS.change, {
|
triggerEvent(this.passedElement.element, EVENTS.change, {
|
||||||
value,
|
value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1113,7 +1101,7 @@ class Choices {
|
||||||
// Update choice keyCode
|
// Update choice keyCode
|
||||||
choice.keyCode = passedKeyCode;
|
choice.keyCode = passedKeyCode;
|
||||||
|
|
||||||
triggerEvent(this.passedElement, EVENTS.choice, {
|
triggerEvent(this.passedElement.element, EVENTS.choice, {
|
||||||
choice,
|
choice,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1362,7 +1350,7 @@ class Choices {
|
||||||
if (value && value.length >= this.config.searchFloor) {
|
if (value && value.length >= this.config.searchFloor) {
|
||||||
const resultCount = this.config.searchChoices ? this._searchChoices(value) : 0;
|
const resultCount = this.config.searchChoices ? this._searchChoices(value) : 0;
|
||||||
// Trigger search event
|
// Trigger search event
|
||||||
triggerEvent(this.passedElement, EVENTS.search, {
|
triggerEvent(this.passedElement.element, EVENTS.search, {
|
||||||
value,
|
value,
|
||||||
resultCount,
|
resultCount,
|
||||||
});
|
});
|
||||||
|
@ -1819,7 +1807,7 @@ class Choices {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
focusActions[this.passedElement.type]();
|
focusActions[this.passedElement.element.type]();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1873,7 +1861,7 @@ class Choices {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
blurActions[this.passedElement.type]();
|
blurActions[this.passedElement.element.type]();
|
||||||
} else {
|
} else {
|
||||||
// On IE11, clicking the scollbar blurs our input and thus
|
// On IE11, clicking the scollbar blurs our input and thus
|
||||||
// closes the dropdown. To stop this, we refocus our input
|
// closes the dropdown. To stop this, we refocus our input
|
||||||
|
@ -2056,7 +2044,7 @@ class Choices {
|
||||||
|
|
||||||
// Trigger change event
|
// Trigger change event
|
||||||
if (group && group.value) {
|
if (group && group.value) {
|
||||||
triggerEvent(this.passedElement, EVENTS.addItem, {
|
triggerEvent(this.passedElement.element, EVENTS.addItem, {
|
||||||
id,
|
id,
|
||||||
value: passedValue,
|
value: passedValue,
|
||||||
label: passedLabel,
|
label: passedLabel,
|
||||||
|
@ -2064,7 +2052,7 @@ class Choices {
|
||||||
keyCode: passedKeyCode,
|
keyCode: passedKeyCode,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
triggerEvent(this.passedElement, EVENTS.addItem, {
|
triggerEvent(this.passedElement.element, EVENTS.addItem, {
|
||||||
id,
|
id,
|
||||||
value: passedValue,
|
value: passedValue,
|
||||||
label: passedLabel,
|
label: passedLabel,
|
||||||
|
@ -2098,14 +2086,14 @@ class Choices {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (group && group.value) {
|
if (group && group.value) {
|
||||||
triggerEvent(this.passedElement, EVENTS.removeItem, {
|
triggerEvent(this.passedElement.element, EVENTS.removeItem, {
|
||||||
id,
|
id,
|
||||||
value,
|
value,
|
||||||
label,
|
label,
|
||||||
groupValue: group.value,
|
groupValue: group.value,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
triggerEvent(this.passedElement, EVENTS.removeItem, {
|
triggerEvent(this.passedElement.element, EVENTS.removeItem, {
|
||||||
id,
|
id,
|
||||||
value,
|
value,
|
||||||
label,
|
label,
|
||||||
|
@ -2272,7 +2260,7 @@ class Choices {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_createInput() {
|
_createInput() {
|
||||||
const direction = this.passedElement.getAttribute('dir') || 'ltr';
|
const direction = this.passedElement.element.getAttribute('dir') || 'ltr';
|
||||||
const containerOuter = this._getTemplate('containerOuter', direction);
|
const containerOuter = this._getTemplate('containerOuter', direction);
|
||||||
const containerInner = this._getTemplate('containerInner');
|
const containerInner = this._getTemplate('containerInner');
|
||||||
const itemList = this._getTemplate('itemList');
|
const itemList = this._getTemplate('itemList');
|
||||||
|
@ -2287,28 +2275,10 @@ class Choices {
|
||||||
this.itemList = new List(this, itemList, this.config.classNames);
|
this.itemList = new List(this, itemList, this.config.classNames);
|
||||||
this.dropdown = new Dropdown(this, dropdown, this.config.classNames);
|
this.dropdown = new Dropdown(this, dropdown, this.config.classNames);
|
||||||
|
|
||||||
// Hide passed input
|
this.passedElement.conceal();
|
||||||
this.passedElement.classList.add(
|
|
||||||
this.config.classNames.input,
|
|
||||||
this.config.classNames.hiddenState,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Remove element from tab index
|
|
||||||
this.passedElement.tabIndex = '-1';
|
|
||||||
|
|
||||||
// Backup original styles if any
|
|
||||||
const origStyle = this.passedElement.getAttribute('style');
|
|
||||||
|
|
||||||
if (origStyle) {
|
|
||||||
this.passedElement.setAttribute('data-choice-orig-style', origStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.passedElement.setAttribute('style', 'display:none;');
|
|
||||||
this.passedElement.setAttribute('aria-hidden', 'true');
|
|
||||||
this.passedElement.setAttribute('data-choice', 'active');
|
|
||||||
|
|
||||||
// Wrap input in container preserving DOM ordering
|
// Wrap input in container preserving DOM ordering
|
||||||
wrap(this.passedElement, this.containerInner.element);
|
wrap(this.passedElement.element, this.containerInner.element);
|
||||||
|
|
||||||
// Wrapper inner container with outer container
|
// Wrapper inner container with outer container
|
||||||
wrap(this.containerInner.element, this.containerOuter.element);
|
wrap(this.containerInner.element, this.containerOuter.element);
|
||||||
|
@ -2339,14 +2309,14 @@ class Choices {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isSelectElement) {
|
if (this.isSelectElement) {
|
||||||
const passedGroups = Array.from(this.passedElement.getElementsByTagName('OPTGROUP'));
|
const passedGroups = Array.from(this.passedElement.element.getElementsByTagName('OPTGROUP'));
|
||||||
|
|
||||||
this.highlightPosition = 0;
|
this.highlightPosition = 0;
|
||||||
this.isSearching = false;
|
this.isSearching = false;
|
||||||
|
|
||||||
if (passedGroups && passedGroups.length) {
|
if (passedGroups && passedGroups.length) {
|
||||||
// If we have a placeholder option
|
// If we have a placeholder option
|
||||||
const placeholderChoice = this.passedElement.querySelector('option[placeholder]');
|
const placeholderChoice = this.passedElement.element.querySelector('option[placeholder]');
|
||||||
if (placeholderChoice && placeholderChoice.parentNode.tagName === 'SELECT') {
|
if (placeholderChoice && placeholderChoice.parentNode.tagName === 'SELECT') {
|
||||||
this._addChoice(
|
this._addChoice(
|
||||||
placeholderChoice.value,
|
placeholderChoice.value,
|
||||||
|
@ -2363,7 +2333,7 @@ class Choices {
|
||||||
this._addGroup(group, (group.id || null));
|
this._addGroup(group, (group.id || null));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const passedOptions = Array.from(this.passedElement.options);
|
const passedOptions = Array.from(this.passedElement.element.options);
|
||||||
const filter = this.config.sortFilter;
|
const filter = this.config.sortFilter;
|
||||||
const allChoices = this.presetChoices;
|
const allChoices = this.presetChoices;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import 'whatwg-fetch';
|
||||||
import 'es6-promise';
|
import 'es6-promise';
|
||||||
import 'core-js/fn/object/assign';
|
import 'core-js/fn/object/assign';
|
||||||
import 'custom-event-autopolyfill';
|
import 'custom-event-autopolyfill';
|
||||||
import { expect, assert } from 'chai';
|
import { expect } from 'chai';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
|
||||||
import Choices from './choices';
|
import Choices from './choices';
|
||||||
|
@ -11,9 +11,11 @@ import Dropdown from './components/dropdown';
|
||||||
import Container from './components/container';
|
import Container from './components/container';
|
||||||
import Input from './components/input';
|
import Input from './components/input';
|
||||||
import List from './components/list';
|
import List from './components/list';
|
||||||
|
import WrappedInput from './components/wrapped-input';
|
||||||
|
import WrappedSelect from './components/wrapped-select';
|
||||||
|
|
||||||
describe('Choices', () => {
|
describe('Choices', () => {
|
||||||
describe('should initialize Choices', () => {
|
describe('initialize Choices', () => {
|
||||||
let input;
|
let input;
|
||||||
let instance;
|
let instance;
|
||||||
|
|
||||||
|
@ -39,7 +41,7 @@ describe('Choices', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not re-initialise if passed element again', () => {
|
it('should not re-initialise if passed element again', () => {
|
||||||
const reinitialise = new Choices(instance.passedElement);
|
const reinitialise = new Choices(instance.passedElement.element);
|
||||||
sinon.spy(reinitialise, '_createTemplates');
|
sinon.spy(reinitialise, '_createTemplates');
|
||||||
expect(reinitialise._createTemplates.callCount).to.equal(0);
|
expect(reinitialise._createTemplates.callCount).to.equal(0);
|
||||||
});
|
});
|
||||||
|
@ -117,7 +119,7 @@ describe('Choices', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should hide passed input', () => {
|
it('should hide passed input', () => {
|
||||||
expect(instance.passedElement.style.display).to.equal('none');
|
expect(instance.passedElement.element.style.display).to.equal('none');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create an outer container', () => {
|
it('should create an outer container', () => {
|
||||||
|
@ -180,6 +182,11 @@ describe('Choices', () => {
|
||||||
instance.destroy();
|
instance.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should wrap passed input', () => {
|
||||||
|
instance = new Choices(input);
|
||||||
|
expect(instance.passedElement).to.be.an.instanceof(WrappedInput);
|
||||||
|
});
|
||||||
|
|
||||||
it('should accept a user inputted value', () => {
|
it('should accept a user inputted value', () => {
|
||||||
instance = new Choices(input);
|
instance = new Choices(input);
|
||||||
|
|
||||||
|
@ -295,6 +302,11 @@ describe('Choices', () => {
|
||||||
instance.destroy();
|
instance.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should wrap passed input', () => {
|
||||||
|
instance = new Choices(input);
|
||||||
|
expect(instance.passedElement).to.be.an.instanceof(WrappedSelect);
|
||||||
|
});
|
||||||
|
|
||||||
it('should open the choice list on focusing', () => {
|
it('should open the choice list on focusing', () => {
|
||||||
instance = new Choices(input);
|
instance = new Choices(input);
|
||||||
instance.input.element.focus();
|
instance.input.element.focus();
|
||||||
|
@ -355,8 +367,8 @@ describe('Choices', () => {
|
||||||
const addSpyStub = sinon.stub();
|
const addSpyStub = sinon.stub();
|
||||||
const passedElement = instance.passedElement;
|
const passedElement = instance.passedElement;
|
||||||
|
|
||||||
passedElement.addEventListener('change', onChangeStub);
|
passedElement.element.addEventListener('change', onChangeStub);
|
||||||
passedElement.addEventListener('addItem', addSpyStub);
|
passedElement.element.addEventListener('addItem', addSpyStub);
|
||||||
|
|
||||||
instance.input.element.focus();
|
instance.input.element.focus();
|
||||||
|
|
||||||
|
@ -421,7 +433,7 @@ describe('Choices', () => {
|
||||||
const showDropdownStub = sinon.spy();
|
const showDropdownStub = sinon.spy();
|
||||||
const passedElement = instance.passedElement;
|
const passedElement = instance.passedElement;
|
||||||
|
|
||||||
passedElement.addEventListener('showDropdown', showDropdownStub);
|
passedElement.element.addEventListener('showDropdown', showDropdownStub);
|
||||||
|
|
||||||
instance.input.focus();
|
instance.input.focus();
|
||||||
|
|
||||||
|
@ -441,7 +453,7 @@ describe('Choices', () => {
|
||||||
const hideDropdownStub = sinon.stub();
|
const hideDropdownStub = sinon.stub();
|
||||||
const passedElement = instance.passedElement;
|
const passedElement = instance.passedElement;
|
||||||
|
|
||||||
passedElement.addEventListener('hideDropdown', hideDropdownStub);
|
passedElement.element.addEventListener('hideDropdown', hideDropdownStub);
|
||||||
|
|
||||||
instance.input.element.focus();
|
instance.input.element.focus();
|
||||||
|
|
||||||
|
@ -466,7 +478,7 @@ describe('Choices', () => {
|
||||||
const onSearchStub = sinon.spy();
|
const onSearchStub = sinon.spy();
|
||||||
const passedElement = instance.passedElement;
|
const passedElement = instance.passedElement;
|
||||||
|
|
||||||
passedElement.addEventListener('search', onSearchStub);
|
passedElement.element.addEventListener('search', onSearchStub);
|
||||||
|
|
||||||
instance.input.element.focus();
|
instance.input.element.focus();
|
||||||
instance.input.element.value = '3 ';
|
instance.input.element.value = '3 ';
|
||||||
|
@ -494,7 +506,7 @@ describe('Choices', () => {
|
||||||
const onSearchStub = sinon.spy();
|
const onSearchStub = sinon.spy();
|
||||||
const passedElement = instance.passedElement;
|
const passedElement = instance.passedElement;
|
||||||
|
|
||||||
passedElement.addEventListener('search', onSearchStub);
|
passedElement.element.addEventListener('search', onSearchStub);
|
||||||
|
|
||||||
instance.input.element.focus();
|
instance.input.element.focus();
|
||||||
instance.input.element.value = 'Javascript';
|
instance.input.element.value = 'Javascript';
|
||||||
|
@ -601,6 +613,10 @@ describe('Choices', () => {
|
||||||
instance.destroy();
|
instance.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should wrap passed input', () => {
|
||||||
|
expect(instance.passedElement).to.be.an.instanceof(WrappedSelect);
|
||||||
|
});
|
||||||
|
|
||||||
it('should add any pre-defined values', () => {
|
it('should add any pre-defined values', () => {
|
||||||
expect(instance.currentState.items.length).to.be.above(1);
|
expect(instance.currentState.items.length).to.be.above(1);
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,7 +8,6 @@ describe('Container', () => {
|
||||||
let choicesInstance;
|
let choicesInstance;
|
||||||
let choicesElement;
|
let choicesElement;
|
||||||
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
choicesInstance = {
|
choicesInstance = {
|
||||||
config: {
|
config: {
|
||||||
|
|
|
@ -8,7 +8,6 @@ describe('Input', () => {
|
||||||
let choicesInstance;
|
let choicesInstance;
|
||||||
let choicesElement;
|
let choicesElement;
|
||||||
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
choicesInstance = {
|
choicesInstance = {
|
||||||
config: {
|
config: {
|
||||||
|
|
|
@ -7,7 +7,6 @@ describe('List', () => {
|
||||||
let choicesInstance;
|
let choicesInstance;
|
||||||
let choicesElement;
|
let choicesElement;
|
||||||
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
choicesInstance = {
|
choicesInstance = {
|
||||||
config: {
|
config: {
|
||||||
|
|
53
src/scripts/src/components/wrapped-element.js
Normal file
53
src/scripts/src/components/wrapped-element.js
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
export default class WrappedElement {
|
||||||
|
constructor(instance, element, classNames) {
|
||||||
|
this.parentInstance = instance;
|
||||||
|
this.element = element;
|
||||||
|
this.classNames = classNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
conceal() {
|
||||||
|
// Hide passed input
|
||||||
|
this.element.classList.add(
|
||||||
|
this.classNames.input,
|
||||||
|
this.classNames.hiddenState,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Remove element from tab index
|
||||||
|
this.element.tabIndex = '-1';
|
||||||
|
|
||||||
|
// Backup original styles if any
|
||||||
|
const origStyle = this.element.getAttribute('style');
|
||||||
|
|
||||||
|
if (origStyle) {
|
||||||
|
this.element.setAttribute('data-choice-orig-style', origStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.element.setAttribute('style', 'display:none;');
|
||||||
|
this.element.setAttribute('aria-hidden', 'true');
|
||||||
|
this.element.setAttribute('data-choice', 'active');
|
||||||
|
}
|
||||||
|
|
||||||
|
reveal() {
|
||||||
|
// Reinstate passed element
|
||||||
|
this.element.classList.remove(
|
||||||
|
this.classNames.input,
|
||||||
|
this.classNames.hiddenState,
|
||||||
|
);
|
||||||
|
this.element.removeAttribute('tabindex');
|
||||||
|
|
||||||
|
// Recover original styles if any
|
||||||
|
const origStyle = this.element.getAttribute('data-choice-orig-style');
|
||||||
|
|
||||||
|
if (origStyle) {
|
||||||
|
this.element.removeAttribute('data-choice-orig-style');
|
||||||
|
this.element.setAttribute('style', origStyle);
|
||||||
|
} else {
|
||||||
|
this.element.removeAttribute('style');
|
||||||
|
}
|
||||||
|
this.element.removeAttribute('aria-hidden');
|
||||||
|
this.element.removeAttribute('data-choice');
|
||||||
|
|
||||||
|
// Re-assign values - this is weird, I know
|
||||||
|
this.element.value = this.element.value;
|
||||||
|
}
|
||||||
|
}
|
19
src/scripts/src/components/wrapped-element.test.js
Normal file
19
src/scripts/src/components/wrapped-element.test.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { expect } from 'chai';
|
||||||
|
import WrappedElement from './wrapped-element';
|
||||||
|
import { DEFAULT_CLASSNAMES, DEFAULT_CONFIG } from '../constants';
|
||||||
|
|
||||||
|
describe('WrappedElement', () => {
|
||||||
|
let instance;
|
||||||
|
let choicesInstance;
|
||||||
|
let choicesElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
choicesInstance = {
|
||||||
|
config: {
|
||||||
|
...DEFAULT_CONFIG,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
choicesElement = document.createElement('select');
|
||||||
|
instance = new WrappedElement(choicesInstance, choicesElement, DEFAULT_CLASSNAMES);
|
||||||
|
});
|
||||||
|
});
|
18
src/scripts/src/components/wrapped-input.js
Normal file
18
src/scripts/src/components/wrapped-input.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import WrappedElement from './wrapped-element';
|
||||||
|
|
||||||
|
export default class WrappedInput extends WrappedElement {
|
||||||
|
constructor(instance, element, classNames) {
|
||||||
|
super(instance, element, classNames);
|
||||||
|
this.parentInstance = instance;
|
||||||
|
this.element = element;
|
||||||
|
this.classNames = classNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
conceal() {
|
||||||
|
super.conceal();
|
||||||
|
}
|
||||||
|
|
||||||
|
reveal() {
|
||||||
|
super.reveal();
|
||||||
|
}
|
||||||
|
}
|
19
src/scripts/src/components/wrapped-input.test.js
Normal file
19
src/scripts/src/components/wrapped-input.test.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { expect } from 'chai';
|
||||||
|
import WrappedInput from './wrapped-input';
|
||||||
|
import { DEFAULT_CLASSNAMES, DEFAULT_CONFIG } from '../constants';
|
||||||
|
|
||||||
|
describe('WrappedInput', () => {
|
||||||
|
let instance;
|
||||||
|
let choicesInstance;
|
||||||
|
let choicesElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
choicesInstance = {
|
||||||
|
config: {
|
||||||
|
...DEFAULT_CONFIG,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
choicesElement = document.createElement('input');
|
||||||
|
instance = new WrappedInput(choicesInstance, choicesElement, DEFAULT_CLASSNAMES);
|
||||||
|
});
|
||||||
|
});
|
18
src/scripts/src/components/wrapped-select.js
Normal file
18
src/scripts/src/components/wrapped-select.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import WrappedElement from './wrapped-element';
|
||||||
|
|
||||||
|
export default class WrappedSelect extends WrappedElement {
|
||||||
|
constructor(instance, element, classNames) {
|
||||||
|
super(instance, element, classNames);
|
||||||
|
this.parentInstance = instance;
|
||||||
|
this.element = element;
|
||||||
|
this.classNames = classNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
conceal() {
|
||||||
|
super.conceal();
|
||||||
|
}
|
||||||
|
|
||||||
|
reveal() {
|
||||||
|
super.reveal();
|
||||||
|
}
|
||||||
|
}
|
19
src/scripts/src/components/wrapped-select.test.js
Normal file
19
src/scripts/src/components/wrapped-select.test.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { expect } from 'chai';
|
||||||
|
import WrappedSelect from './wrapped-select';
|
||||||
|
import { DEFAULT_CLASSNAMES, DEFAULT_CONFIG } from '../constants';
|
||||||
|
|
||||||
|
describe('WrappedSelect', () => {
|
||||||
|
let instance;
|
||||||
|
let choicesInstance;
|
||||||
|
let choicesElement;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
choicesInstance = {
|
||||||
|
config: {
|
||||||
|
...DEFAULT_CONFIG,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
choicesElement = document.createElement('select');
|
||||||
|
instance = new WrappedSelect(choicesInstance, choicesElement, DEFAULT_CLASSNAMES);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue