diff --git a/assets/scripts/dist/bundle.js b/assets/scripts/dist/bundle.js index f011a0f..83ce518 100644 --- a/assets/scripts/dist/bundle.js +++ b/assets/scripts/dist/bundle.js @@ -1 +1 @@ -!function(e){function t(i){if(n[i])return n[i].exports;var r=n[i]={exports:{},id:i,loaded:!1};return e[i].call(r.exports,r,r.exports,t),r.loaded=!0,r.exports}var n={};return t.m=e,t.c=n,t.p="/assets/scripts/dist/",t(0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0}),t.Choices=void 0;var o=function(){function e(e,t){for(var n=0;n=0;n--){var i=this.list.children[n];if(i.innerHTML===e.toString()){t=i;break}}if(t){var r=t.getAttribute("data-choice-id"),o=t.innerHTML;this.options.callbackOnRemoveItem&&((0,l.isType)("Function",this.options.callbackOnRemoveItem)?this.options.callbackOnRemoveItem(o):console.error("callbackOnRemoveItem: Callback is not a function")),this.store.dispatch((0,u.removeItemFromStore)(r))}else console.error("Item not found")}},{key:"removeAll",value:function(e){for(var t=0;t'),n=(0,l.strToEl)('
');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"),(0,l.wrap)(this.element,n),(0,l.wrap)(n,t);var i=(0,l.strToEl)('
'),r=(0,l.strToEl)('');r.placeholder&&(r.placeholder=this.element.placeholder),this.options.addItems||(r.disabled=!0),t.appendChild(n),n.appendChild(i),n.appendChild(r),this.containerOuter=t,this.containerInner=n,this.input=r,this.list=i,this.presetItems.forEach(function(t){e.addItem(t)}),this.store.subscribe(this.render),this.render(),this.addEventListeners()}},{key:"addEventListeners",value:function(){document.addEventListener("keydown",this.onKeyDown),this.list.addEventListener("click",this.onClick)}},{key:"removeEventListeners",value:function(){document.removeEventListener("keydown",this.onKeyDown),this.list.removeEventListener("click",this.onClick)}},{key:"render",value:function(){var e=this,t=this.store.getState(),n=t.reduce(function(e,t){return e.push(t.value),e},[]);this.element.value=n.join(this.options.delimiter),this.list.innerHTML="",t.forEach(function(t){if(t.active){var n=(0,l.strToEl)('
'+t.value+"
");e.list.appendChild(n)}}),console.log(t)}},{key:"renderInput",value:function(e){switch(this.options.debug&&console.debug("Render"),e.type){case"text":this.renderTextInput();break;case"select-one":break;case"select-multiple":break;default:this.renderTextInput()}}},{key:"init",value:function(){this.supports||console.error("init: Your browser doesn'nt support shit"),this.initialised=!0,this.renderInput(this.element)}},{key:"destroy",value:function(){this.options=null,this.element=null,this.initialised=null}}]),e}();!function(){var e=document.getElementById(1),t=document.getElementById(2),n=document.getElementById(3),i=document.getElementById(4),r=document.getElementById(5),o=document.getElementById(6),s=(new d({element:e,delimiter:" ",editItems:!0,maxItems:5,callbackOnRemoveItem:function(e){console.log(e)},callbackOnAddItem:function(e,t){console.log(e,t)}}),new d({element:t,allowDuplicates:!1,editItems:!0}),new d({element:n,allowDuplicates:!1,editItems:!0,regexFilter:/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/}),new d({element:i,addItems:!1}),new d({element:r,prependValue:"item-",appendValue:"-"+Date.now()}),new d({element:o,items:["josh@joshuajohnson.co.uk","joe@bloggs.co.uk"]}));s.addItem("josh2@joshuajohnson.co.uk"),s.removeItem("josh@joshuajohnson.co.uk")}()},function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}t.__esModule=!0,t.compose=t.applyMiddleware=t.bindActionCreators=t.combineReducers=t.createStore=void 0;var r=n(3),o=i(r),s=n(7),a=i(s),c=n(9),u=i(c),l=n(10),d=i(l),f=n(11),h=i(f),p=n(8);i(p);t.createStore=o.default,t.combineReducers=a.default,t.bindActionCreators=u.default,t.applyMiddleware=d.default,t.compose=h.default},function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}function r(e,t,n){function i(){p===h&&(p=h.slice())}function o(){return f}function c(e){if("function"!=typeof e)throw new Error("Expected listener to be a function.");var t=!0;return i(),p.push(e),function(){if(t){t=!1,i();var n=p.indexOf(e);p.splice(n,1)}}}function u(e){if(!(0,s.default)(e))throw new Error("Actions must be plain objects. Use custom middleware for async actions.");if("undefined"==typeof e.type)throw new Error('Actions may not have an undefined "type" property. Have you misspelled a constant?');if(m)throw new Error("Reducers may not dispatch actions.");try{m=!0,f=d(f,e)}finally{m=!1}for(var t=h=p,n=0;nn;n++)t[n]=arguments[n];return function(e){return function(n,i,r){var s=e(n,i,r),c=s.dispatch,u=[],l={getState:s.getState,dispatch:function(e){return c(e)}};return u=t.map(function(e){return e(l)}),c=a.default.apply(void 0,u)(s.dispatch),o({},s,{dispatch:c})}}}var o=Object.assign||function(e){for(var t=1;tn;n++)t[n]=arguments[n];return function(){if(0===t.length)return arguments.length<=0?void 0:arguments[0];var e=t[t.length-1],n=t.slice(0,-1);return n.reduceRight(function(e,t){return t(e)},e.apply(void 0,arguments))}}t.__esModule=!0,t.default=n},function(e,t){"use strict";function n(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);tr;r++){var o=arguments[r];n("Object",o)?i(o):console.error("Custom options must be an object")}return e},t.whichTransitionEvent=function(){var e,t=document.createElement("fakeelement"),n={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"};for(e in n)if(void 0!==t.style[e])return n[e]},t.whichAnimationEvent=function(){var e,t=document.createElement("fakeelement"),n={animation:"animationend",OAnimation:"oAnimationEnd",MozAnimation:"animationend",WebkitAnimation:"webkitAnimationEnd"};for(e in n)if(void 0!==t.style[e])return n[e]});t.getParentsUntil=function(e,t,n){for(var i=[];e&&e!==document;e=e.parentNode){if(t){var r=t.charAt(0);if("."===r&&e.classList.contains(t.substr(1)))break;if("#"===r&&e.id===t.substr(1))break;if("["===r&&e.hasAttribute(t.substr(1,t.length-1)))break;if(e.tagName.toLowerCase()===t)break}if(n){var o=n.charAt(0);"."===o&&e.classList.contains(n.substr(1))&&i.push(e),"#"===o&&e.id===n.substr(1)&&i.push(e),"["===o&&e.hasAttribute(n.substr(1,n.length-1))&&i.push(e),e.tagName.toLowerCase()===n&&i.push(e)}else i.push(e)}return 0===i.length?null:i},t.wrap=function(e,t){return t=t||document.createElement("div"),e.nextSibling?e.parentNode.insertBefore(t,e.nextSibling):e.parentNode.appendChild(t),t.appendChild(e)},t.getSiblings=function(e){for(var t=[],n=e.parentNode.firstChild;n;n=n.nextSibling)1===n.nodeType&&n!==e&&t.push(n);return t},t.findAncestor=function(e,t){for(;(e=e.parentElement)&&!e.classList.contains(t););return e},t.debounce=function(e,t,n){var i;return function(){var r=this,o=arguments,s=function(){i=null,n||e.apply(r,o)},a=n&&!i;clearTimeout(i),i=setTimeout(s,t),a&&e.apply(r,o)}},t.getElemDistance=function(e){var t=0;if(e.offsetParent)do t+=e.offsetTop,e=e.offsetParent;while(e);return t>=0?t:0},t.getElementOffset=function(e,t){var n=t;return n>1&&(n=1),n>0&&(n=0),Math.max(e.offsetHeight*n)},t.getScrollPosition=function(e){return"bottom"===e?Math.max((window.scrollY||window.pageYOffset)+(window.innerHeight||document.documentElement.clientHeight)):window.scrollY||window.pageYOffset},t.isInView=function(e,t,n){return this.getScrollPosition(t)>this.getElemDistance(e)+this.getElementOffset(e,n)},t.stripHTML=function(e){var t=document.createElement("DIV");return t.innerHTML=e,t.textContent||t.innerText||""},t.addAnimation=function(e,t){var n=i(),r=function o(){e.classList.remove(t),e.removeEventListener(n,o,!1)};e.classList.add(t),e.addEventListener(n,r,!1)},t.getRandomNumber=function(e,t){return Math.floor(Math.random()*(t-e)+e)},t.strToEl=function(){var e=document.createElement("div");return function(t){var n;for(e.innerHTML=t,n=e.children[0];e.firstChild;)e.removeChild(e.firstChild);return n}}(),t.getWidthOfInput=function(){var e=document.createElement("span");e.className="input-element tmp-element",e.innerHTML=inputEl.value.replace(/&/g,"&").replace(//g,">"),document.body.appendChild(e);var t=e.getBoundingClientRect().width;return document.body.removeChild(e),t}}]); \ No newline at end of file +!function(e){function t(i){if(n[i])return n[i].exports;var o=n[i]={exports:{},id:i,loaded:!1};return e[i].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="/assets/scripts/dist/",t(0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0}),t.Choices=void 0;var r=function(){function e(e,t){for(var n=0;n=0;n--){var i=this.list.children[n];if(i.innerHTML===e.toString()){t=i;break}}if(t){var o=t.getAttribute("data-choice-id"),r=t.innerHTML;this.options.callbackOnRemoveItem&&((0,l.isType)("Function",this.options.callbackOnRemoveItem)?this.options.callbackOnRemoveItem(r):console.error("callbackOnRemoveItem: Callback is not a function")),this.store.dispatch((0,u.removeItemFromStore)(o))}else console.error("Item not found")}},{key:"removeAll",value:function(e){for(var t=0;t'),n=(0,l.strToEl)('
');this.passedInput.classList.add("choices__input","choices__input--hidden"),this.passedInput.tabIndex="-1",this.passedInput.setAttribute("style","display:none;"),this.passedInput.setAttribute("aria-hidden","true"),(0,l.wrap)(this.passedInput,n),(0,l.wrap)(n,t);var i=(0,l.strToEl)('
'),o=(0,l.strToEl)('');this.passedInput.placeholder&&(o.placeholder=this.passedInput.placeholder),this.options.addItems||(o.disabled=!0),t.appendChild(n),n.appendChild(i),n.appendChild(o),this.containerOuter=t,this.containerInner=n,this.input=o,this.list=i,this.presetItems.forEach(function(t){e.addItem(t)}),this.store.subscribe(this.render),this.render(),this.addEventListeners()}},{key:"renderMultipleSelectInput",value:function(){var e=this,t=(0,l.strToEl)('
'),n=(0,l.strToEl)('
');this.passedInput.classList.add("choices__input","choices__input--hidden"),this.passedInput.tabIndex="-1",this.passedInput.setAttribute("style","display:none;"),this.passedInput.setAttribute("aria-hidden","true"),(0,l.wrap)(this.passedInput,n),(0,l.wrap)(n,t);var i=(0,l.strToEl)('
'),o=(0,l.strToEl)(''),r=(0,l.strToEl)('
');o.placeholder&&(o.placeholder=this.passedInput.placeholder),this.options.addItems||(o.disabled=!0),t.appendChild(n),t.appendChild(r),n.appendChild(i),n.appendChild(o),this.containerOuter=t,this.containerInner=n,this.input=o,this.list=i,this.dropdown=r,this.presetItems.forEach(function(t){e.addItem(t)}),this.store.subscribe(this.render),this.render(),this.addEventListeners()}},{key:"addEventListeners",value:function(){document.addEventListener("keydown",this.onKeyDown),this.list.addEventListener("click",this.onClick),this.input.addEventListener("focus",this.onFocus)}},{key:"removeEventListeners",value:function(){document.removeEventListener("keydown",this.onKeyDown),this.list.removeEventListener("click",this.onClick),this.input.removeEventListener("focus",this.onFocus)}},{key:"render",value:function(){var e=this,t=this.store.getState(),n=t.reduce(function(e,t){return e.push(t.value),e},[]);this.passedInput.value=n.join(this.options.delimiter),this.list.innerHTML="",t.forEach(function(t){if(t.active){var n=(0,l.strToEl)('
'+t.value+"
");e.list.appendChild(n)}}),console.log(t)}},{key:"renderInput",value:function(e){switch(this.options.debug&&console.debug("Render"),e.type){case"text":this.renderTextInput();break;case"select-one":break;case"select-multiple":this.renderMultipleSelectInput();break;default:this.renderTextInput()}}},{key:"init",value:function(){this.supports||console.error("init: Your browser doesn'nt support shit"),this.initialised=!0,this.renderInput(this.passedInput)}},{key:"destroy",value:function(){this.options=null,this.passedInput=null,this.initialised=null}}]),e}();document.addEventListener("DOMContentLoaded",function(){var e=document.getElementById(1),t=document.getElementById(2),n=document.getElementById(3),i=document.getElementById(4),o=document.getElementById(5),r=document.getElementById(6),s=document.getElementById(7),a=(new d({element:e,delimiter:" ",editItems:!0,maxItems:5,callbackOnRemoveItem:function(e){console.log(e)},callbackOnAddItem:function(e,t){console.log(e,t)}}),new d({element:t,allowDuplicates:!1,editItems:!0}),new d({element:n,allowDuplicates:!1,editItems:!0,regexFilter:/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/}),new d({element:i,addItems:!1}),new d({element:o,prependValue:"item-",appendValue:"-"+Date.now()}),new d({element:r,items:["josh@joshuajohnson.co.uk","joe@bloggs.co.uk"]}));new d({element:s});a.addItem("josh2@joshuajohnson.co.uk"),a.removeItem("josh@joshuajohnson.co.uk"),console.log(a.getItemByValue("josh2@joshuajohnson.co.uk"))})},function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}t.__esModule=!0,t.compose=t.applyMiddleware=t.bindActionCreators=t.combineReducers=t.createStore=void 0;var o=n(3),r=i(o),s=n(8),a=i(s),c=n(10),u=i(c),l=n(11),d=i(l),p=n(12),h=i(p),f=n(9);i(f);t.createStore=r.default,t.combineReducers=a.default,t.bindActionCreators=u.default,t.applyMiddleware=d.default,t.compose=h.default},function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}function o(e,t,n){function i(){f===h&&(f=h.slice())}function r(){return p}function c(e){if("function"!=typeof e)throw new Error("Expected listener to be a function.");var t=!0;return i(),f.push(e),function(){if(t){t=!1,i();var n=f.indexOf(e);f.splice(n,1)}}}function u(e){if(!(0,s.default)(e))throw new Error("Actions must be plain objects. Use custom middleware for async actions.");if("undefined"==typeof e.type)throw new Error('Actions may not have an undefined "type" property. Have you misspelled a constant?');if(m)throw new Error("Reducers may not dispatch actions.");try{m=!0,p=d(p,e)}finally{m=!1}for(var t=h=f,n=0;nn;n++)t[n]=arguments[n];return function(e){return function(n,i,o){var s=e(n,i,o),c=s.dispatch,u=[],l={getState:s.getState,dispatch:function(e){return c(e)}};return u=t.map(function(e){return e(l)}),c=a.default.apply(void 0,u)(s.dispatch),r({},s,{dispatch:c})}}}var r=Object.assign||function(e){for(var t=1;tn;n++)t[n]=arguments[n];return function(){if(0===t.length)return arguments.length<=0?void 0:arguments[0];var e=t[t.length-1],n=t.slice(0,-1);return n.reduceRight(function(e,t){return t(e)},e.apply(void 0,arguments))}}t.__esModule=!0,t.default=n},function(e,t){"use strict";function n(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);to;o++){var r=arguments[o];n("Object",r)?i(r):console.error("Custom options must be an object")}return e},t.whichTransitionEvent=function(){var e,t=document.createElement("fakeelement"),n={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"};for(e in n)if(void 0!==t.style[e])return n[e]},t.whichAnimationEvent=function(){var e,t=document.createElement("fakeelement"),n={animation:"animationend",OAnimation:"oAnimationEnd",MozAnimation:"animationend",WebkitAnimation:"webkitAnimationEnd"};for(e in n)if(void 0!==t.style[e])return n[e]});t.getParentsUntil=function(e,t,n){for(var i=[];e&&e!==document;e=e.parentNode){if(t){var o=t.charAt(0);if("."===o&&e.classList.contains(t.substr(1)))break;if("#"===o&&e.id===t.substr(1))break;if("["===o&&e.hasAttribute(t.substr(1,t.length-1)))break;if(e.tagName.toLowerCase()===t)break}if(n){var r=n.charAt(0);"."===r&&e.classList.contains(n.substr(1))&&i.push(e),"#"===r&&e.id===n.substr(1)&&i.push(e),"["===r&&e.hasAttribute(n.substr(1,n.length-1))&&i.push(e),e.tagName.toLowerCase()===n&&i.push(e)}else i.push(e)}return 0===i.length?null:i},t.wrap=function(e,t){return t=t||document.createElement("div"),e.nextSibling?e.parentNode.insertBefore(t,e.nextSibling):e.parentNode.appendChild(t),t.appendChild(e)},t.getSiblings=function(e){for(var t=[],n=e.parentNode.firstChild;n;n=n.nextSibling)1===n.nodeType&&n!==e&&t.push(n);return t},t.findAncestor=function(e,t){for(;(e=e.parentElement)&&!e.classList.contains(t););return e},t.debounce=function(e,t,n){var i;return function(){var o=this,r=arguments,s=function(){i=null,n||e.apply(o,r)},a=n&&!i;clearTimeout(i),i=setTimeout(s,t),a&&e.apply(o,r)}},t.getElemDistance=function(e){var t=0;if(e.offsetParent)do t+=e.offsetTop,e=e.offsetParent;while(e);return t>=0?t:0},t.getElementOffset=function(e,t){var n=t;return n>1&&(n=1),n>0&&(n=0),Math.max(e.offsetHeight*n)},t.getScrollPosition=function(e){return"bottom"===e?Math.max((window.scrollY||window.pageYOffset)+(window.innerHeight||document.documentElement.clientHeight)):window.scrollY||window.pageYOffset},t.isInView=function(e,t,n){return this.getScrollPosition(t)>this.getElemDistance(e)+this.getElementOffset(e,n)},t.stripHTML=function(e){var t=document.createElement("DIV");return t.innerHTML=e,t.textContent||t.innerText||""},t.addAnimation=function(e,t){var n=i(),o=function r(){e.classList.remove(t),e.removeEventListener(n,r,!1)};e.classList.add(t),e.addEventListener(n,o,!1)},t.getRandomNumber=function(e,t){return Math.floor(Math.random()*(t-e)+e)},t.strToEl=function(){var e=document.createElement("div");return function(t){var n;for(e.innerHTML=t,n=e.children[0];e.firstChild;)e.removeChild(e.firstChild);return n}}(),t.getWidthOfInput=function(){var e=document.createElement("span");e.className="tmp-element",e.innerHTML=inputEl.value.replace(/&/g,"&").replace(//g,">"),document.body.appendChild(e);var t=e.getBoundingClientRect().width;return document.body.removeChild(e),t}}]); \ No newline at end of file diff --git a/assets/scripts/src/choices.js b/assets/scripts/src/choices.js index 0219814..e1db638 100644 --- a/assets/scripts/src/choices.js +++ b/assets/scripts/src/choices.js @@ -44,14 +44,14 @@ export class Choices { this.supports = 'querySelector' in document && 'addEventListener' in document && 'classList' in fakeEl; // Retrieve triggering element (i.e. element with 'data-choice' trigger) - this.element = this.options.element; + this.passedInput = this.options.element; // Set preset items this.presetItems = []; if(this.options.items.length) { this.presetItems = this.options.items; - } else if(this.element.value !== '') { - this.presetItems = this.element.value.split(this.options.delimiter); + } else if(this.passedInput.value !== '') { + this.presetItems = this.passedInput.value.split(this.options.delimiter); } // Bind methods @@ -60,6 +60,7 @@ export class Choices { this.destroy = this.destroy.bind(this); this.onKeyDown = this.onKeyDown.bind(this); this.onClick = this.onClick.bind(this); + this.onFocus = this.onFocus.bind(this); // Let's have it large this.init(); @@ -103,7 +104,7 @@ export class Choices { // If CTRL + A or CMD + A have been pressed and there are items to select if (ctrlDownKey && e.keyCode === aKey && this.list && this.list.children) { let handleSelectAll = () => { - if(this.options.removeItems && !this.input.value && this.options.selectAll) { + if(this.options.removeItems && !this.input.value && this.options.selectAll && this.input === document.activeElement) { this.selectAll(this.list.children); } }; @@ -126,7 +127,7 @@ export class Choices { // If no duplicates are allowed, and the value already exists // in the array, don't update - if (this.options.allowDuplicates === false && this.element.value) { + if (this.options.allowDuplicates === false && this.passedInput.value) { canUpdate = !storeValues.some((item) => { return item.value === value; }); @@ -134,7 +135,7 @@ export class Choices { // All is good, update if (canUpdate) { - if(this.element.type === 'text') { + if(this.passedInput.type === 'text') { let canAddItem = true; // If a user has supplied a regular expression filter @@ -147,7 +148,7 @@ export class Choices { // All is good, add if(canAddItem) { this.addItem(value); - this.clearInput(this.element); + this.clearInput(this.passedInput); } } } @@ -162,18 +163,20 @@ export class Choices { let handleBackspaceKey = () => { if(this.options.removeItems) { - let currentListItems = this.list.querySelectorAll('.choices__item'); + let currentListItems = this.list.querySelectorAll('[data-choice-item]'); let selectedItems = this.list.querySelectorAll('.is-selected'); let lastItem = currentListItems[currentListItems.length - 1]; + let inputIsFocussed = this.input === document.activeElement; - if(lastItem && !this.options.editItems) { + if(lastItem && !this.options.editItems && inputIsFocussed) { this.selectItem(lastItem); } // 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 === 0) { + + if(this.options.editItems && lastItem && selectedItems.length === 0 && inputIsFocussed) { this.input.value = lastItem.innerHTML; this.removeItem(lastItem); } else { @@ -195,7 +198,8 @@ export class Choices { * @return */ onClick(e) { - if(e.target.tagName === 'LI') { + // I don't like the look of this + if(e.target.hasAttribute('data-choice-item')) { let item = e.target; let handleClick = (item) => { @@ -220,6 +224,12 @@ export class Choices { } } + onFocus(e) { + if(this.passedInput.type === 'select-multiple') { + console.log(e.target); + } + } + /* Methods */ /** @@ -242,6 +252,23 @@ export class Choices { return passesTest; } + /** + * Get Element based on a given value + * @param {String} value Value to search for + * @return {Element} First Element with given value + */ + getItemByValue(value) { + let state = this.store.getState() + + let stateObject = state.find((item) => { + return item.value === value; + }); + + let item = this.list.querySelector(`[data-choice-id='${stateObject.id}']`) + + return item; + } + /** * Select item (a selected item can be deleted) * @param {Element} item Element to select @@ -262,7 +289,6 @@ export class Choices { this.store.dispatch(selectItemFromStore(id, false)); } - /** * Select items within array * @param {Array} items Array of items to select @@ -387,26 +413,26 @@ export class Choices { */ - let containerOuter = strToEl('
'); - let containerInner = strToEl('
'); + let containerOuter = strToEl(`
`); + let containerInner = strToEl(`
`); // 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'); + this.passedInput.classList.add('choices__input', 'choices__input--hidden'); + this.passedInput.tabIndex = '-1'; + this.passedInput.setAttribute('style', 'display:none;'); + this.passedInput.setAttribute('aria-hidden', 'true'); // Wrap input in container preserving DOM ordering - wrap(this.element, containerInner); + wrap(this.passedInput, containerInner); // Wrapper inner container with outer container wrap(containerInner, containerOuter); - let list = strToEl('
'); - let input = strToEl(''); + let list = strToEl(`
`); + let input = strToEl(``); - if (input.placeholder) { - input.placeholder = this.element.placeholder; + if (this.passedInput.placeholder) { + input.placeholder = this.passedInput.placeholder; } if(!this.options.addItems) { @@ -437,14 +463,86 @@ export class Choices { this.addEventListeners(); } + /** + * Create DOM structure around passed select element + * @return + */ + renderMultipleSelectInput() { + /* + Template: + +
+
+ +
    + +
    +
    + */ + + let containerOuter = strToEl('
    '); + let containerInner = strToEl('
    '); + + // Hide passed input + this.passedInput.classList.add('choices__input', 'choices__input--hidden'); + this.passedInput.tabIndex = '-1'; + this.passedInput.setAttribute('style', 'display:none;'); + this.passedInput.setAttribute('aria-hidden', 'true'); + + // Wrap input in container preserving DOM ordering + wrap(this.passedInput, containerInner); + + // Wrapper inner container with outer container + wrap(containerInner, containerOuter); + + let list = strToEl('
    '); + let input = strToEl(''); + let dropdown = strToEl('
    '); + + if (input.placeholder) { + input.placeholder = this.passedInput.placeholder; + } + + if(!this.options.addItems) { + input.disabled = true; + } + + containerOuter.appendChild(containerInner); + containerOuter.appendChild(dropdown); + containerInner.appendChild(list); + containerInner.appendChild(input); + + this.containerOuter = containerOuter; + this.containerInner = containerInner; + this.input = input; + this.list = list; + this.dropdown = dropdown; + + // Add any preset values seperated by delimiter + this.presetItems.forEach((value) => { + this.addItem(value); + }); + + // Subscribe to store + this.store.subscribe(this.render); + + // Render any items + this.render(); + + // Trigger event listeners + this.addEventListeners(); + } + addEventListeners() { document.addEventListener('keydown', this.onKeyDown); this.list.addEventListener('click', this.onClick); + this.input.addEventListener('focus', this.onFocus); } removeEventListeners() { document.removeEventListener('keydown', this.onKeyDown); this.list.removeEventListener('click', this.onClick); + this.input.removeEventListener('focus', this.onFocus); } /** @@ -461,7 +559,7 @@ export class Choices { }, []); // Assign hidden input array of values - this.element.value = valueArray.join(this.options.delimiter); + this.passedInput.value = valueArray.join(this.options.delimiter); // Clear list this.list.innerHTML = ''; @@ -470,7 +568,7 @@ export class Choices { state.forEach((item) => { if(item.active) { // Create new list element - let listItem = strToEl(`
    ${ item.value }
    `); + let listItem = strToEl(`
    ${ item.value }
    `); // Append it to list this.list.appendChild(listItem); @@ -495,7 +593,7 @@ export class Choices { // this.renderSelectInput(); break; case "select-multiple": - // this.renderMultipleSelectInput(); + this.renderMultipleSelectInput(); break; default: this.renderTextInput(); @@ -510,7 +608,7 @@ export class Choices { init() { if (!this.supports) console.error('init: Your browser doesn\'nt support shit'); this.initialised = true; - this.renderInput(this.element); + this.renderInput(this.passedInput); } /** @@ -519,18 +617,19 @@ export class Choices { */ destroy() { this.options = null; - this.element = null; + this.passedInput = null; this.initialised = null; } }; -(function(){ +document.addEventListener('DOMContentLoaded', () => { let input1 = document.getElementById(1); let input2 = document.getElementById(2); let input3 = document.getElementById(3); let input4 = document.getElementById(4); let input5 = document.getElementById(5); let input6 = document.getElementById(6); + let input7 = document.getElementById(7); let choices1 = new Choices({ element : input1, @@ -574,6 +673,11 @@ export class Choices { items: ['josh@joshuajohnson.co.uk', 'joe@bloggs.co.uk'] }); + let choices7 = new Choices({ + element: input7, + }); + choices6.addItem('josh2@joshuajohnson.co.uk'); choices6.removeItem('josh@joshuajohnson.co.uk'); -})(); \ No newline at end of file + console.log(choices6.getItemByValue('josh2@joshuajohnson.co.uk')); +}); \ No newline at end of file diff --git a/assets/scripts/src/lib/utils.js b/assets/scripts/src/lib/utils.js index a65e060..889a365 100644 --- a/assets/scripts/src/lib/utils.js +++ b/assets/scripts/src/lib/utils.js @@ -366,12 +366,12 @@ export const strToEl = (function() { * Calculates the width of a passed input based on its value * @return {Number} Width of input */ -export const getWidthOfInput = function() { - var tmp = document.createElement("span"); - tmp.className = "input-element tmp-element"; +export const getWidthOfInput = () => { + let tmp = document.createElement('span'); + tmp.className = "tmp-element"; tmp.innerHTML = inputEl.value.replace(/&/g,'&').replace(//g,'>'); document.body.appendChild(tmp); - var theWidth = tmp.getBoundingClientRect().width; + let theWidth = tmp.getBoundingClientRect().width; document.body.removeChild(tmp); return theWidth; - } \ No newline at end of file +} \ No newline at end of file diff --git a/assets/styles/css/choices.css b/assets/styles/css/choices.css index 377d558..93be7e2 100644 --- a/assets/styles/css/choices.css +++ b/assets/styles/css/choices.css @@ -56,22 +56,42 @@ h1, h2, h3, h4, h5, h6 { padding-left: 0; list-style-type: none; } +.choices__item--selectable { + cursor: pointer; } + .choices__list--items { display: inline; } .choices__list--items .choices__item { display: inline-block; - border-radius: .8rem; - padding: .4rem .8rem; + border-radius: 2rem; + padding: .4rem 1rem; font-size: 1.2rem; margin-right: .375rem; margin-bottom: .375rem; background-color: #00BCD4; - border: 1px solid #00a5bb; + border: 1px solid #00b1c7; color: #FFFFFF; cursor: pointer; } .choices__list--items .choices__item.is-selected { background-color: #00a5bb; } +.choices__list--dropdown { + position: absolute; + width: 100%; + background-color: #FFFFFF; + border: 1px solid #DDDDDD; + margin-top: -1px; + display: none; + border-bottom-left-radius: .25rem; + border-bottom-right-radius: .25rem; } + .choices__list--dropdown .choices__item { + padding: 1rem; + font-size: 1.4rem; } + .choices__list--dropdown .choices__item:hover { + background-color: #f9f9f9; } + .choices__list--dropdown .is-active { + display: block; } + .choices__input { background-color: #f9f9f9; font-size: 1.4rem; diff --git a/assets/styles/css/choices.min.css b/assets/styles/css/choices.min.css index 79e2740..fea6cb2 100644 --- a/assets/styles/css/choices.min.css +++ b/assets/styles/css/choices.min.css @@ -1 +1 @@ -*,:after,:before{box-sizing:border-box}body,html{margin:0;height:100%;widows:100%}html{font-size:62.5%}body{background-color:#333;font-family:"Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;font-size:1.6rem;color:#fff}label{display:block;margin-bottom:.8rem;font-size:1.4rem;font-weight:500}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:1.2rem;font-weight:500}.container{display:block;margin:auto;max-width:35em;padding:2.4rem}.section{background-color:#fff;padding:2.4rem;color:#333}.choices{margin-bottom:2.4rem;position:relative}.choices__inner{background-color:#f9f9f9;padding:.75rem .75rem .375rem;border:1px solid #ddd;border-radius:.25rem;font-size:1.4rem}.choices__inner:focus{outline:1px solid #00bcd4;outline-offset:-1px}.choices__list{margin:0;padding-left:0;list-style-type:none}.choices__list--items{display:inline}.choices__list--items .choices__item{display:inline-block;border-radius:.8rem;padding:.4rem .8rem;font-size:1.2rem;margin-right:.375rem;margin-bottom:.375rem;background-color:#00bcd4;border:1px solid #00a5bb;color:#fff;cursor:pointer}.choices__list--items .choices__item.is-selected{background-color:#00a5bb}.choices__input{background-color:#f9f9f9;font-size:1.4rem;padding:0;margin-bottom:.5rem;display:inline-block;vertical-align:baseline;border:0;border-radius:0;max-width:100%;padding:.4rem 0 .4rem .2rem}.choices__input:focus{outline:0} \ No newline at end of file +*,:after,:before{box-sizing:border-box}body,html{margin:0;height:100%;widows:100%}html{font-size:62.5%}body{background-color:#333;font-family:"Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;font-size:1.6rem;color:#fff}label{display:block;margin-bottom:.8rem;font-size:1.4rem;font-weight:500}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:1.2rem;font-weight:500}.container{display:block;margin:auto;max-width:35em;padding:2.4rem}.section{background-color:#fff;padding:2.4rem;color:#333}.choices{margin-bottom:2.4rem;position:relative}.choices__inner{background-color:#f9f9f9;padding:.75rem .75rem .375rem;border:1px solid #ddd;border-radius:.25rem;font-size:1.4rem}.choices__inner:focus{outline:1px solid #00bcd4;outline-offset:-1px}.choices__list{margin:0;padding-left:0;list-style-type:none}.choices__item--selectable{cursor:pointer}.choices__list--items{display:inline}.choices__list--items .choices__item{display:inline-block;border-radius:2rem;padding:.4rem 1rem;font-size:1.2rem;margin-right:.375rem;margin-bottom:.375rem;background-color:#00bcd4;border:1px solid #00b1c7;color:#fff;cursor:pointer}.choices__list--items .choices__item.is-selected{background-color:#00a5bb}.choices__list--dropdown{position:absolute;width:100%;background-color:#fff;border:1px solid #ddd;margin-top:-1px;display:none;border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.choices__list--dropdown .choices__item{padding:1rem;font-size:1.4rem}.choices__input,.choices__list--dropdown .choices__item:hover{background-color:#f9f9f9}.choices__list--dropdown .is-active{display:block}.choices__input{font-size:1.4rem;padding:0;margin-bottom:.5rem;display:inline-block;vertical-align:baseline;border:0;border-radius:0;max-width:100%;padding:.4rem 0 .4rem .2rem}.choices__input:focus{outline:0} \ No newline at end of file diff --git a/assets/styles/scss/choices.scss b/assets/styles/scss/choices.scss index 6d16e7c..e5b8d83 100644 --- a/assets/styles/scss/choices.scss +++ b/assets/styles/scss/choices.scss @@ -70,25 +70,47 @@ h1, h2, h3, h4, h5, h6 { list-style-type: none; } +.choices__item {} +.choices__item--selectable { cursor: pointer; } + .choices__list--options {} .choices__list--items { display: inline; .choices__item { display: inline-block; - border-radius: .8rem; - padding: .4rem .8rem; + border-radius: 2rem; + padding: .4rem 1rem; font-size: 1.2rem; margin-right: .375rem; margin-bottom: .375rem; background-color: #00BCD4; - border: 1px solid darken(#00BCD4, 5%); + border: 1px solid darken(#00BCD4, 2.5%); color: #FFFFFF; cursor: pointer; &.is-selected { background-color: darken(#00BCD4, 5%); } } } +.choices__list--dropdown { + position: absolute; + width: 100%; + background-color: #FFFFFF; + border: 1px solid #DDDDDD; + margin-top: -1px; + display: none; + border-bottom-left-radius: .25rem; + border-bottom-right-radius: .25rem; + .choices__item { + padding: 1rem; + font-size: 1.4rem; + &:hover { + background-color: mix(#000000, #FFFFFF, 2.5%); + } + } + .is-active { display: block; } +} + .choices__input { background-color: mix(#000000, #FFFFFF, 2.5%); font-size: 1.4rem; diff --git a/index.html b/index.html index 7223f90..4efcff5 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,7 @@ Choices +
    @@ -26,8 +27,33 @@ + + + + + + +
    +
    + +
    +
    preset-1
    +
    preset-2
    +
    + +
    +
      +
    • Dropdown item 1
    • +
    • Dropdown item 2
    • +
    • Dropdown item 3
    • +
    +
    +
    - \ No newline at end of file