2016-03-17 16:00:22 +01:00
|
|
|
'use strict';
|
|
|
|
|
2016-03-18 00:10:16 +01:00
|
|
|
import { hasClass, wrap, getSiblings, isType } from './lib/utils.js';
|
2016-03-16 21:24:11 +01:00
|
|
|
|
2016-03-18 12:05:50 +01:00
|
|
|
/**
|
|
|
|
|
|
|
|
TODO:
|
2016-03-21 20:27:52 +01:00
|
|
|
- Dynamically set input width to contents
|
2016-03-18 12:05:50 +01:00
|
|
|
- Handle select input
|
|
|
|
- Handle multiple select input ?
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2016-03-18 13:26:38 +01:00
|
|
|
export class Choices {
|
2016-03-17 16:00:22 +01:00
|
|
|
constructor(options) {
|
2016-03-18 13:26:38 +01:00
|
|
|
const FAKE_EL = document.createElement("FAKE_ELement");
|
2016-03-17 16:00:22 +01:00
|
|
|
const USER_OPTIONS = options || {};
|
|
|
|
const DEFAULT_OPTIONS = {
|
|
|
|
element: document.querySelector('[data-choice]'),
|
|
|
|
disabled: false,
|
2016-03-18 00:10:16 +01:00
|
|
|
create: true,
|
2016-03-22 23:47:29 +01:00
|
|
|
removeItems: true,
|
2016-03-21 19:53:26 +01:00
|
|
|
editItems: false,
|
2016-03-18 12:05:50 +01:00
|
|
|
maxItems: false,
|
|
|
|
delimiter: ',',
|
|
|
|
allowDuplicates: true,
|
2016-03-18 00:10:16 +01:00
|
|
|
debug: false,
|
2016-03-17 16:00:22 +01:00
|
|
|
placeholder: false,
|
2016-03-18 13:26:38 +01:00
|
|
|
callbackOnInit: function() {},
|
|
|
|
callbackOnRender: function() {},
|
|
|
|
callbackOnKeyUp: function() {},
|
|
|
|
callbackOnKeyDown: function() {},
|
|
|
|
callbackOnEntry: function() {},
|
|
|
|
callbackOnRemove: function() {}
|
2016-03-17 16:00:22 +01:00
|
|
|
};
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
// Merge options with user options
|
|
|
|
this.options = this.extend(DEFAULT_OPTIONS, USER_OPTIONS || {});
|
|
|
|
this.initialised = false;
|
2016-03-18 13:26:38 +01:00
|
|
|
this.supports = 'querySelector' in document && 'addEventListener' in document && 'classList' in FAKE_EL;
|
2016-03-17 16:00:22 +01:00
|
|
|
|
|
|
|
// Retrieve elements
|
|
|
|
this.element = this.options.element;
|
|
|
|
// If input already has values, parse the array, otherwise create a blank array
|
2016-03-18 12:13:35 +01:00
|
|
|
this.valueArray = this.element.value !== '' ? this.cleanInputValue(this.element.value) : [];
|
2016-03-18 13:26:38 +01:00
|
|
|
// How many values in array
|
|
|
|
this.valueCount = this.valueArray.length;
|
2016-03-17 16:00:22 +01:00
|
|
|
|
|
|
|
// Bind methods
|
|
|
|
this.onClick = this.onClick.bind(this);
|
|
|
|
this.onKeyDown = this.onKeyDown.bind(this);
|
|
|
|
this.onChange = this.onChange.bind(this);
|
|
|
|
this.onFocus = this.onFocus.bind(this);
|
|
|
|
this.onBlur = this.onChange.bind(this);
|
2016-03-18 13:26:38 +01:00
|
|
|
|
|
|
|
this.init();
|
2016-03-17 16:00:22 +01:00
|
|
|
}
|
2016-03-16 10:03:59 +01:00
|
|
|
|
2016-03-18 12:13:35 +01:00
|
|
|
cleanInputValue(value) {
|
2016-03-18 13:26:38 +01:00
|
|
|
// Remove spaces and split with delimiter
|
2016-03-18 12:13:35 +01:00
|
|
|
return value.replace(/\s/g, '').split(this.options.delimiter);
|
|
|
|
}
|
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
/**
|
|
|
|
* Merges unspecified amount of objects into new object
|
|
|
|
* @private
|
|
|
|
* @return {Object} Merged object of arguments
|
|
|
|
*/
|
|
|
|
extend() {
|
|
|
|
let extended = {};
|
|
|
|
let length = arguments.length;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Merge one object into another
|
|
|
|
* @param {Object} obj Object to merge into extended object
|
|
|
|
*/
|
|
|
|
let merge = function(obj) {
|
2016-03-18 13:26:38 +01:00
|
|
|
for (let prop in obj) {
|
2016-03-17 16:00:22 +01:00
|
|
|
extended[prop] = obj[prop];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Loop through each passed argument
|
2016-03-18 13:26:38 +01:00
|
|
|
for (let i = 0; i < length; i++) {
|
2016-03-17 16:00:22 +01:00
|
|
|
// Store argument at position i
|
|
|
|
let obj = arguments[i];
|
|
|
|
|
|
|
|
// If we are in fact dealing with an object, merge it. Otherwise throw error
|
2016-03-18 13:26:38 +01:00
|
|
|
if (isType('Object', obj)) {
|
2016-03-17 16:00:22 +01:00
|
|
|
merge(obj);
|
|
|
|
} else {
|
|
|
|
console.error('Custom options must be an object');
|
|
|
|
}
|
2016-03-15 23:42:10 +01:00
|
|
|
}
|
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
return extended;
|
|
|
|
};
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
/* State */
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
isOpen() {
|
2016-03-18 13:26:38 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
}
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
isDisabled() {
|
2016-03-18 13:26:38 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
}
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
isEmpty() {
|
2016-03-18 13:26:38 +01:00
|
|
|
return (this.valueCount.length === 0) ? true : false;
|
2016-03-17 16:00:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
clearInput() {
|
2016-03-18 13:26:38 +01:00
|
|
|
if (this.input.value) this.input.value = '';
|
2016-03-17 16:00:22 +01:00
|
|
|
}
|
2016-03-17 00:15:03 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
/* Event handling */
|
|
|
|
|
2016-03-18 00:10:16 +01:00
|
|
|
onKeyUp(e) {
|
|
|
|
}
|
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
onKeyDown(e) {
|
2016-03-18 00:10:16 +01:00
|
|
|
let ctrlDown = e.ctrlKey || e.metaKey;
|
|
|
|
|
2016-03-22 23:47:29 +01:00
|
|
|
// If CTRL + A or CMD + A have been pressed and there are items to select
|
|
|
|
if (ctrlDown && e.keyCode === 65 && this.list && this.list.children) {
|
|
|
|
let handleSelectAll = () => {
|
|
|
|
if(this.options.removeItems) {
|
|
|
|
for (let i = 0; i < this.list.children.length; i++) {
|
|
|
|
let listItem = this.list.children[i];
|
|
|
|
|
|
|
|
// Select any items that have not already been selected
|
|
|
|
if(!listItem.classList.contains('is-selected')) {
|
|
|
|
listItem.classList.add('is-selected');
|
|
|
|
}
|
2016-03-22 15:36:01 +01:00
|
|
|
}
|
2016-03-21 23:45:49 +01:00
|
|
|
}
|
2016-03-22 23:47:29 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
handleSelectAll();
|
2016-03-18 00:10:16 +01:00
|
|
|
}
|
|
|
|
|
2016-03-22 23:47:29 +01:00
|
|
|
// If enter key is pressed and the input has a value
|
2016-03-18 13:26:38 +01:00
|
|
|
if (e.keyCode === 13 && e.target.value) {
|
2016-03-17 16:00:22 +01:00
|
|
|
let value = this.input.value;
|
|
|
|
|
|
|
|
let handleEnterKey = () => {
|
2016-03-18 00:10:16 +01:00
|
|
|
let canUpdate = true;
|
2016-03-17 16:00:22 +01:00
|
|
|
|
2016-03-18 00:10:16 +01:00
|
|
|
// If there is a max entry limit and we have reached that limit
|
|
|
|
// don't update
|
2016-03-18 13:26:38 +01:00
|
|
|
if (this.options.maxItems && this.options.maxItems <= this.list.children.length) {
|
2016-03-18 00:10:16 +01:00
|
|
|
canUpdate = false;
|
2016-03-17 16:00:22 +01:00
|
|
|
}
|
2016-03-18 00:10:16 +01:00
|
|
|
|
|
|
|
// If no duplicates are allowed, and the value already exists
|
|
|
|
// in the array, don't update
|
2016-03-18 13:26:38 +01:00
|
|
|
if (this.options.allowDuplicates === false && this.element.value) {
|
|
|
|
if (this.valueArray.indexOf(value) > -1) {
|
2016-03-18 00:10:16 +01:00
|
|
|
canUpdate = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// All is good, update
|
2016-03-18 13:26:38 +01:00
|
|
|
if (canUpdate) {
|
2016-03-21 20:27:52 +01:00
|
|
|
if(this.element.type === 'text') {
|
|
|
|
this.addItem(this.list, value);
|
|
|
|
this.updateInputValue(value);
|
|
|
|
this.clearInput(this.element);
|
2016-03-22 15:36:01 +01:00
|
|
|
this.unselectAll(this.list.children);
|
2016-03-21 20:27:52 +01:00
|
|
|
} else {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-03-18 00:10:16 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-03-18 13:26:38 +01:00
|
|
|
handleEnterKey();
|
2016-03-15 23:42:10 +01:00
|
|
|
}
|
|
|
|
|
2016-03-22 23:47:29 +01:00
|
|
|
// If backspace or delete key is pressed and the input has no value
|
2016-03-18 13:26:38 +01:00
|
|
|
if ((e.keyCode === 8 || e.keyCode === 46) && !e.target.value) {
|
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
let handleBackspaceKey = () => {
|
2016-03-22 23:47:29 +01:00
|
|
|
if(this.options.removeItems) {
|
|
|
|
let currentListItems = this.list.querySelectorAll('.choices__item');
|
|
|
|
let selectedItems = this.list.querySelectorAll('.is-selected');
|
|
|
|
let lastItem = currentListItems[currentListItems.length - 1];
|
|
|
|
|
|
|
|
if(lastItem) {
|
|
|
|
lastItem.classList.add('is-selected');
|
|
|
|
}
|
|
|
|
|
|
|
|
// If editing the last item is allowed and there is a last item and
|
|
|
|
// there are not other selected items (minus the last item), we can edit
|
|
|
|
// the item value. Otherwise if we can remove items, remove all items
|
|
|
|
if(this.options.editItems && lastItem && selectedItems.length <= 1) {
|
|
|
|
this.input.value = lastItem.innerHTML;
|
|
|
|
this.removeItem(lastItem);
|
|
|
|
} else {
|
|
|
|
this.removeAll(currentListItems);
|
|
|
|
}
|
2016-03-21 19:53:26 +01:00
|
|
|
}
|
2016-03-17 16:00:22 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
handleBackspaceKey();
|
2016-03-17 00:15:03 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
e.preventDefault();
|
2016-03-15 23:42:10 +01:00
|
|
|
}
|
2016-03-17 16:00:22 +01:00
|
|
|
}
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
onFocus(e) {
|
2016-03-17 00:15:03 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
}
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
onClick(e) {
|
2016-03-17 00:15:03 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
}
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
onChange(e) {
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
}
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
/* Event listeners */
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
addEventListeners(el) {
|
|
|
|
el.addEventListener('click', this.onClick);
|
2016-03-18 00:10:16 +01:00
|
|
|
el.addEventListener('keyup', this.onKeyUp);
|
2016-03-17 16:00:22 +01:00
|
|
|
el.addEventListener('keydown', this.onKeyDown);
|
|
|
|
el.addEventListener('change', this.onChange);
|
|
|
|
el.addEventListener('focus', this.onFocus);
|
|
|
|
el.addEventListener('blur', this.onBlur);
|
|
|
|
}
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
removeEventListeners(el) {
|
|
|
|
el.removeEventListener('click', this.onClick);
|
2016-03-18 00:10:16 +01:00
|
|
|
el.removeEventListener('keyup', this.onKeyUp);
|
2016-03-17 16:00:22 +01:00
|
|
|
el.removeEventListener('keydown', this.onKeyDown);
|
|
|
|
el.removeEventListener('change', this.onChange);
|
|
|
|
el.removeEventListener('focus', this.onFocus);
|
|
|
|
el.removeEventListener('blur', this.onBlur);
|
|
|
|
}
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
/* Methods */
|
2016-03-21 23:45:49 +01:00
|
|
|
setValue() {}
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-21 23:45:49 +01:00
|
|
|
getValue() {}
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-21 23:45:49 +01:00
|
|
|
getValues() {}
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-21 23:45:49 +01:00
|
|
|
getPlaceholder() {}
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
updateInputValue(value) {
|
2016-03-18 13:26:38 +01:00
|
|
|
if (this.options.debug) console.debug('Update input value');
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
// Push new value to array
|
2016-03-18 13:26:38 +01:00
|
|
|
this.valueArray.push(value);
|
2016-03-18 12:05:50 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
// Caste array to string and set it as the hidden inputs value
|
2016-03-18 12:13:35 +01:00
|
|
|
this.element.value = this.valueArray.join(this.options.delimiter);
|
2016-03-17 16:00:22 +01:00
|
|
|
}
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-18 00:10:16 +01:00
|
|
|
removeInputValue(value) {
|
2016-03-18 13:26:38 +01:00
|
|
|
if (this.options.debug) console.debug('Remove input value');
|
|
|
|
|
2016-03-18 00:10:16 +01:00
|
|
|
let index = this.valueArray.indexOf(value);
|
|
|
|
this.valueArray.splice(index, 1);
|
|
|
|
|
2016-03-18 12:13:35 +01:00
|
|
|
this.element.value = this.valueArray.join(this.options.delimiter);
|
2016-03-18 00:10:16 +01:00
|
|
|
}
|
|
|
|
|
2016-03-21 20:27:52 +01:00
|
|
|
addItem(parent, value) {
|
2016-03-18 13:26:38 +01:00
|
|
|
if (this.options.debug) console.debug('Add item');
|
|
|
|
|
2016-03-18 12:05:50 +01:00
|
|
|
// // Create new list element
|
2016-03-17 16:00:22 +01:00
|
|
|
let item = document.createElement('li');
|
2016-03-18 00:10:16 +01:00
|
|
|
item.classList.add('choices__item');
|
2016-03-17 16:00:22 +01:00
|
|
|
item.textContent = value;
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
// Append it to list
|
2016-03-21 20:27:52 +01:00
|
|
|
parent.appendChild(item);
|
2016-03-17 16:00:22 +01:00
|
|
|
}
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-22 15:36:01 +01:00
|
|
|
unselectAll(items) {
|
|
|
|
for (let i = 0; i < items.length; i++) {
|
|
|
|
let item = items[i];
|
|
|
|
|
|
|
|
if (item.classList.contains('is-selected')) {
|
|
|
|
item.classList.remove('is-selected');
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-03-21 19:53:26 +01:00
|
|
|
removeAll(items) {
|
|
|
|
for (let i = 0; i < items.length; i++) {
|
|
|
|
let item = items[i];
|
|
|
|
|
|
|
|
if (item.classList.contains('is-selected')) {
|
|
|
|
this.removeItem(item);
|
|
|
|
this.removeInputValue(item.textContent);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-03-18 00:10:16 +01:00
|
|
|
removeItem(item) {
|
2016-03-18 13:26:38 +01:00
|
|
|
if (item) item.parentNode.removeChild(item);
|
2016-03-17 16:00:22 +01:00
|
|
|
}
|
2016-03-18 13:26:38 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
init() {
|
2016-03-18 13:26:38 +01:00
|
|
|
if (!this.supports) console.error('Your browser doesn\'nt support shit');
|
2016-03-17 16:00:22 +01:00
|
|
|
this.initialised = true;
|
|
|
|
this.render(this.element);
|
|
|
|
}
|
2016-03-16 21:24:11 +01:00
|
|
|
|
2016-03-18 12:05:50 +01:00
|
|
|
renderTextInput() {
|
2016-03-21 23:45:49 +01:00
|
|
|
// Template:
|
|
|
|
//
|
|
|
|
// <div class="choices choices--active">
|
|
|
|
// <div class="choices__inner">
|
|
|
|
// <input id="1" type="text" data-choice="" class="choices__input choices__input--hidden" tabindex="-1" style="display:none;" aria-hidden="true">
|
|
|
|
// <ul class="choices__list choices__list--items"></ul>
|
|
|
|
// <input type="text" class="choices__input choices__input--cloned">
|
|
|
|
// </div>
|
|
|
|
// </div>
|
|
|
|
|
2016-03-18 00:10:16 +01:00
|
|
|
let containerOuter = document.createElement('div');
|
2016-03-18 13:26:38 +01:00
|
|
|
containerOuter.className = 'choices choices--active';
|
2016-03-16 15:41:13 +01:00
|
|
|
|
2016-03-18 12:05:50 +01:00
|
|
|
let containerInner = document.createElement('div');
|
2016-03-18 13:26:38 +01:00
|
|
|
containerInner.className = 'choices__inner';
|
2016-03-16 15:41:13 +01:00
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
// Hide passed input
|
2016-03-18 00:10:16 +01:00
|
|
|
this.element.classList.add('choices__input', 'choices__input--hidden');
|
2016-03-17 16:00:22 +01:00
|
|
|
this.element.tabIndex = '-1';
|
|
|
|
this.element.setAttribute('style', 'display:none;');
|
|
|
|
this.element.setAttribute('aria-hidden', 'true');
|
2016-03-16 21:24:11 +01:00
|
|
|
|
2016-03-18 00:10:16 +01:00
|
|
|
// Wrap input in container preserving DOM ordering
|
|
|
|
wrap(this.element, containerInner);
|
2016-03-18 13:26:38 +01:00
|
|
|
|
2016-03-18 12:05:50 +01:00
|
|
|
// Wrapper inner container with outer container
|
2016-03-18 00:10:16 +01:00
|
|
|
wrap(containerInner, containerOuter);
|
|
|
|
|
2016-03-18 12:05:50 +01:00
|
|
|
let list = document.createElement('ul');
|
2016-03-21 20:27:52 +01:00
|
|
|
list.className = 'choices__list choices__list--items';
|
2016-03-16 15:41:13 +01:00
|
|
|
|
2016-03-18 12:05:50 +01:00
|
|
|
let input = document.createElement('input');
|
2016-03-18 13:26:38 +01:00
|
|
|
input.type = 'text';
|
|
|
|
input.className = 'choices__input choices__input--cloned';
|
2016-03-18 12:05:50 +01:00
|
|
|
|
2016-03-18 13:26:38 +01:00
|
|
|
if (input.placeholder) {
|
|
|
|
input.placeholder = this.element.placeholder;
|
2016-03-18 12:05:50 +01:00
|
|
|
}
|
2016-03-18 13:26:38 +01:00
|
|
|
|
2016-03-18 00:10:16 +01:00
|
|
|
containerInner.appendChild(list);
|
|
|
|
containerInner.appendChild(input);
|
|
|
|
containerOuter.appendChild(containerInner);
|
2016-03-17 16:00:22 +01:00
|
|
|
|
2016-03-18 00:10:16 +01:00
|
|
|
this.containerOuter = containerOuter;
|
|
|
|
this.containerInner = containerInner;
|
2016-03-17 16:00:22 +01:00
|
|
|
this.input = input;
|
|
|
|
this.list = list;
|
|
|
|
|
2016-03-18 13:26:38 +01:00
|
|
|
if (this.element.value !== '') {
|
2016-03-18 12:05:50 +01:00
|
|
|
// Add any preset values
|
|
|
|
this.valueArray.forEach((value) => {
|
2016-03-21 20:27:52 +01:00
|
|
|
this.addItem(this.list, value);
|
2016-03-17 16:00:22 +01:00
|
|
|
});
|
2016-03-15 23:42:10 +01:00
|
|
|
}
|
|
|
|
|
2016-03-18 12:05:50 +01:00
|
|
|
// Trigger event listeners
|
2016-03-17 16:00:22 +01:00
|
|
|
this.addEventListeners(this.input);
|
|
|
|
}
|
2016-03-16 15:41:13 +01:00
|
|
|
|
2016-03-18 12:05:50 +01:00
|
|
|
renderSelectInput() {
|
2016-03-21 20:27:52 +01:00
|
|
|
let containerOuter = document.createElement('div');
|
|
|
|
containerOuter.className = 'choices choices--active';
|
|
|
|
|
|
|
|
let containerInner = document.createElement('div');
|
|
|
|
containerInner.className = 'choices__inner';
|
|
|
|
|
|
|
|
// Hide passed input
|
|
|
|
this.element.classList.add('choices__input', 'choices__input--hidden');
|
|
|
|
this.element.tabIndex = '-1';
|
|
|
|
this.element.setAttribute('style', 'display:none;');
|
|
|
|
this.element.setAttribute('aria-hidden', 'true');
|
|
|
|
|
|
|
|
// Wrap input in container preserving DOM ordering
|
|
|
|
wrap(this.element, containerInner);
|
|
|
|
|
|
|
|
// Wrapper inner container with outer container
|
|
|
|
wrap(containerInner, containerOuter);
|
|
|
|
|
|
|
|
let options = document.createElement('ul');
|
|
|
|
options.className = 'choices__list choices__list--options';
|
2016-03-18 12:05:50 +01:00
|
|
|
|
2016-03-21 20:27:52 +01:00
|
|
|
let input = document.createElement('input');
|
|
|
|
input.type = 'text';
|
|
|
|
input.className = 'choices__input choices__input--cloned';
|
|
|
|
|
|
|
|
containerInner.appendChild(input);
|
|
|
|
containerInner.appendChild(options);
|
|
|
|
containerOuter.appendChild(containerInner);
|
|
|
|
|
|
|
|
this.containerOuter = containerOuter;
|
|
|
|
this.containerInner = containerInner;
|
|
|
|
this.input = input;
|
|
|
|
this.list = null;
|
|
|
|
this.options = options;
|
|
|
|
|
2016-03-21 23:45:49 +01:00
|
|
|
let initialOptions = this.element.children;
|
2016-03-21 20:27:52 +01:00
|
|
|
|
|
|
|
if (initialOptions) {
|
|
|
|
for (let i = 0; i < initialOptions.length; i++) {
|
2016-03-21 23:45:49 +01:00
|
|
|
let parentOption = initialOptions[i];
|
|
|
|
|
|
|
|
if(parentOption.tagName === 'OPTGROUP') {
|
|
|
|
this.addItem(this.options, parentOption.label);
|
|
|
|
for (let j = 0; j < parentOption.children.length; j++) {
|
|
|
|
let childOption = parentOption.children[j];
|
|
|
|
this.addItem(this.options, childOption.innerHTML);
|
|
|
|
}
|
|
|
|
} else if(parentOption.tagName === 'OPTION') {
|
|
|
|
this.addItem(this.options, parentOption.innerHTML);
|
|
|
|
}
|
2016-03-21 20:27:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Trigger event listeners
|
|
|
|
this.addEventListeners(this.input);
|
2016-03-18 12:05:50 +01:00
|
|
|
}
|
|
|
|
|
2016-03-21 23:45:49 +01:00
|
|
|
renderMultipleSelectInput() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-03-18 12:05:50 +01:00
|
|
|
render() {
|
2016-03-18 13:26:38 +01:00
|
|
|
if (this.options.debug) console.debug('Render');
|
2016-03-18 12:05:50 +01:00
|
|
|
|
2016-03-18 13:26:38 +01:00
|
|
|
switch (this.element.type) {
|
2016-03-18 12:05:50 +01:00
|
|
|
case "text":
|
|
|
|
this.renderTextInput();
|
|
|
|
break;
|
|
|
|
case "select-one":
|
|
|
|
this.renderSelectInput();
|
|
|
|
break;
|
|
|
|
case "select-multiple":
|
2016-03-21 23:45:49 +01:00
|
|
|
this.renderMultipleSelectInput();
|
2016-03-18 12:05:50 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
rthis.renderTextInput();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-03-17 16:00:22 +01:00
|
|
|
destroy() {
|
|
|
|
this.options = null;
|
|
|
|
this.element = null;
|
2016-03-18 00:10:16 +01:00
|
|
|
this.initialised = null;
|
2016-03-17 16:00:22 +01:00
|
|
|
this.removeEventListeners(this.input);
|
|
|
|
}
|
|
|
|
};
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-18 13:26:38 +01:00
|
|
|
(function(){
|
2016-03-18 12:05:50 +01:00
|
|
|
let input1 = document.getElementById(1);
|
|
|
|
let input2 = document.getElementById(2);
|
|
|
|
let input3 = document.getElementById(3);
|
2016-03-21 23:45:49 +01:00
|
|
|
let input4 = document.getElementById(4);
|
2016-03-17 16:00:22 +01:00
|
|
|
|
2016-03-18 12:05:50 +01:00
|
|
|
let choices1 = new Choices({
|
|
|
|
element : input1,
|
|
|
|
delimiter: ' ',
|
|
|
|
maxItems: 5,
|
|
|
|
});
|
2016-03-15 23:42:10 +01:00
|
|
|
|
2016-03-18 12:05:50 +01:00
|
|
|
let choices2 = new Choices({
|
|
|
|
element : input2,
|
2016-03-21 19:53:26 +01:00
|
|
|
allowDuplicates: false,
|
|
|
|
editItems: true
|
2016-03-18 12:05:50 +01:00
|
|
|
});
|
2016-03-17 16:00:22 +01:00
|
|
|
|
2016-03-18 12:05:50 +01:00
|
|
|
let choices3 = new Choices({
|
|
|
|
element : input3
|
|
|
|
});
|
2016-03-21 23:45:49 +01:00
|
|
|
|
|
|
|
|
|
|
|
let choices4 = new Choices({
|
|
|
|
element : input4
|
|
|
|
});
|
2016-03-18 13:26:38 +01:00
|
|
|
})();
|