mirror of
https://github.com/Choices-js/Choices.git
synced 2024-05-02 22:03:11 +02:00
Add tags to list proof of concept
This commit is contained in:
parent
d39fcde893
commit
d0d8656ca8
2
assets/scripts/dist/bundle.js
vendored
2
assets/scripts/dist/bundle.js
vendored
File diff suppressed because one or more lines are too long
|
@ -1,3 +1,5 @@
|
|||
import { wrap, getSiblings } from './lib/utils.js';
|
||||
|
||||
(function (root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(function() {
|
||||
|
@ -12,16 +14,6 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
let wrap = function (element, wrapper) {
|
||||
wrapper = wrapper || document.createElement('div');
|
||||
if (element.nextSibling) {
|
||||
element.parentNode.insertBefore(wrapper, element.nextSibling);
|
||||
} else {
|
||||
element.parentNode.appendChild(wrapper);
|
||||
}
|
||||
return wrapper.appendChild(element);
|
||||
};
|
||||
|
||||
class Choices {
|
||||
constructor() {
|
||||
const fakeEl = document.createElement("fakeelement");
|
||||
|
@ -72,23 +64,25 @@
|
|||
/* Event handling */
|
||||
|
||||
onKeyDown(e) {
|
||||
// let input =
|
||||
console.log('Key down')
|
||||
console.log(e.target);
|
||||
|
||||
if(e.keyCode === 13 && e.target.value) {
|
||||
this.addItem(e.target, e.target.value);
|
||||
e.target.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
onFocus(e) {
|
||||
console.log('Focus')
|
||||
console.log(e.target);
|
||||
}
|
||||
|
||||
onClick(e) {
|
||||
console.log('Click')
|
||||
console.log(e.target);
|
||||
}
|
||||
|
||||
onChange(e) {
|
||||
console.log('Change')
|
||||
console.log(e.target);
|
||||
}
|
||||
|
||||
/* Event listeners */
|
||||
|
@ -131,8 +125,16 @@
|
|||
|
||||
}
|
||||
|
||||
addItem() {
|
||||
addItem(el, value) {
|
||||
console.log('Add item');
|
||||
let wrapper = el.parentNode;
|
||||
let list = wrapper.querySelector('.choice__list');
|
||||
|
||||
let item = document.createElement('li');
|
||||
item.classList.add('choice__item');
|
||||
item.textContent = value;
|
||||
|
||||
wrapper.appendChild(item);
|
||||
}
|
||||
|
||||
removeItem() {
|
||||
|
@ -162,7 +164,10 @@
|
|||
console.log('Render');
|
||||
|
||||
let wrapper = document.createElement('div');
|
||||
wrapper.classList.add('choice', 'choice--active')
|
||||
let input = document.createElement('input');
|
||||
let list = document.createElement('ul');
|
||||
|
||||
wrapper.classList.add('choice', 'choice--active');
|
||||
|
||||
el.classList.add('choice__input', 'choice__input--original');
|
||||
el.tabIndex = '-1';
|
||||
|
@ -170,12 +175,15 @@
|
|||
|
||||
wrap(el, wrapper);
|
||||
|
||||
let input = document.createElement('input');
|
||||
list.classList.add('choice__list');
|
||||
|
||||
input.type = 'text';
|
||||
input.classList.add('choice__input', 'choice__input--cloned');
|
||||
|
||||
wrapper.appendChild(list);
|
||||
wrapper.appendChild(input);
|
||||
|
||||
this.addEventListeners(el);
|
||||
this.addEventListeners(input);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
|
|
305
assets/scripts/src/lib/utils.js
Normal file
305
assets/scripts/src/lib/utils.js
Normal file
|
@ -0,0 +1,305 @@
|
|||
/**
|
||||
* Capitalises the first letter of each word in a string
|
||||
* @param {String} str String to capitalise
|
||||
* @return {String} Capitalised string
|
||||
*/
|
||||
export let capitalise = function(str) {
|
||||
return str.replace(/\w\S*/g, function(txt){
|
||||
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Tests the type of an object
|
||||
* @param {String} type Type to test object against
|
||||
* @param {Object} obj Object to be tested
|
||||
* @return {Boolean}
|
||||
*/
|
||||
export let isType = function(type, obj) {
|
||||
var clas = Object.prototype.toString.call(obj).slice(8, -1);
|
||||
return obj !== undefined && obj !== null && clas === type;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* CSS transition end event listener
|
||||
* @return
|
||||
*/
|
||||
export let whichTransitionEvent = function(){
|
||||
var t,
|
||||
el = document.createElement("fakeelement");
|
||||
|
||||
var transitions = {
|
||||
"transition" : "transitionend",
|
||||
"OTransition" : "oTransitionEnd",
|
||||
"MozTransition" : "transitionend",
|
||||
"WebkitTransition": "webkitTransitionEnd"
|
||||
}
|
||||
|
||||
for (t in transitions){
|
||||
if (el.style[t] !== undefined){
|
||||
return transitions[t];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CSS animation end event listener
|
||||
* @return
|
||||
*/
|
||||
export let whichAnimationEvent = function() {
|
||||
var t,
|
||||
el = document.createElement('fakeelement');
|
||||
|
||||
var animations = {
|
||||
'animation': 'animationend',
|
||||
'OAnimation': 'oAnimationEnd',
|
||||
'MozAnimation': 'animationend',
|
||||
'WebkitAnimation': 'webkitAnimationEnd'
|
||||
};
|
||||
|
||||
for (t in animations) {
|
||||
if (el.style[t] !== undefined) {
|
||||
return animations[t];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the ancestors of each element in the current set of matched elements,
|
||||
* up to but not including the element matched by the selector
|
||||
* @param {NodeElement} elem Element to begin search from
|
||||
* @param {NodeElement} parent Parent to find
|
||||
* @param {String} selector Class to find
|
||||
* @return {Array} Array of parent elements
|
||||
*/
|
||||
export let getParentsUntil = function(elem, parent, selector) {
|
||||
var parents = [];
|
||||
// Get matches
|
||||
for (; elem && elem !== document; elem = elem.parentNode) {
|
||||
|
||||
// Check if parent has been reached
|
||||
if (parent) {
|
||||
|
||||
var parentType = parent.charAt(0);
|
||||
|
||||
// If parent is a class
|
||||
if (parentType === '.') {
|
||||
if (elem.classList.contains(parent.substr(1))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If parent is an ID
|
||||
if (parentType === '#') {
|
||||
if (elem.id === parent.substr(1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If parent is a data attribute
|
||||
if (parentType === '[') {
|
||||
if (elem.hasAttribute(parent.substr(1, parent.length - 1))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If parent is a tag
|
||||
if (elem.tagName.toLowerCase() === parent) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (selector) {
|
||||
var selectorType = selector.charAt(0);
|
||||
|
||||
// If selector is a class
|
||||
if (selectorType === '.') {
|
||||
if (elem.classList.contains(selector.substr(1))) {
|
||||
parents.push(elem);
|
||||
}
|
||||
}
|
||||
|
||||
// If selector is an ID
|
||||
if (selectorType === '#') {
|
||||
if (elem.id === selector.substr(1)) {
|
||||
parents.push(elem);
|
||||
}
|
||||
}
|
||||
|
||||
// If selector is a data attribute
|
||||
if (selectorType === '[') {
|
||||
if (elem.hasAttribute(selector.substr(1, selector.length - 1))) {
|
||||
parents.push(elem);
|
||||
}
|
||||
}
|
||||
|
||||
// If selector is a tag
|
||||
if (elem.tagName.toLowerCase() === selector) {
|
||||
parents.push(elem);
|
||||
}
|
||||
|
||||
} else {
|
||||
parents.push(elem);
|
||||
}
|
||||
}
|
||||
|
||||
// Return parents if any exist
|
||||
if (parents.length === 0) {
|
||||
return null;
|
||||
} else {
|
||||
return parents;
|
||||
}
|
||||
};
|
||||
|
||||
export let wrap = function (element, wrapper) {
|
||||
wrapper = wrapper || document.createElement('div');
|
||||
if (element.nextSibling) {
|
||||
element.parentNode.insertBefore(wrapper, element.nextSibling);
|
||||
} else {
|
||||
element.parentNode.appendChild(wrapper);
|
||||
}
|
||||
return wrapper.appendChild(element);
|
||||
};
|
||||
|
||||
export let getSiblings = function (elem) {
|
||||
var siblings = [];
|
||||
var sibling = elem.parentNode.firstChild;
|
||||
for ( ; sibling; sibling = sibling.nextSibling ) {
|
||||
if ( sibling.nodeType === 1 && sibling !== elem ) {
|
||||
siblings.push( sibling );
|
||||
}
|
||||
}
|
||||
return siblings;
|
||||
};
|
||||
|
||||
/**
|
||||
* Find ancestor in DOM tree
|
||||
* @param {NodeElement} el Element to start search from
|
||||
* @param {[type]} cls Class of parent
|
||||
* @return {NodeElement} Found parent element
|
||||
*/
|
||||
export let findAncestor = function(el, cls) {
|
||||
while ((el = el.parentElement) && !el.classList.contains(cls));
|
||||
return el;
|
||||
};
|
||||
|
||||
/**
|
||||
* Debounce an event handler.
|
||||
* @param {Function} func Function to run after wait
|
||||
* @param {Number} wait The delay before the function is executed
|
||||
* @param {Boolean} immediate If passed, trigger the function on the leading edge, instead of the trailing.
|
||||
* @return {Function} A function will be called after it stops being called for a given delay
|
||||
*/
|
||||
export let debounce = function(func, wait, immediate) {
|
||||
var timeout;
|
||||
return function() {
|
||||
var context = this,
|
||||
args = arguments;
|
||||
var later = function() {
|
||||
timeout = null;
|
||||
if (!immediate) func.apply(context, args);
|
||||
};
|
||||
var callNow = immediate && !timeout;
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
if (callNow) func.apply(context, args);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an element's distance from the top of the page
|
||||
* @private
|
||||
* @param {NodeElement} el Element to test for
|
||||
* @return {Number} Elements Distance from top of page
|
||||
*/
|
||||
export let getElemDistance = function(el) {
|
||||
var location = 0;
|
||||
if (el.offsetParent) {
|
||||
do {
|
||||
location += el.offsetTop;
|
||||
el = el.offsetParent;
|
||||
} while (el);
|
||||
}
|
||||
return location >= 0 ? location : 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine element height multiplied by any offsets
|
||||
* @private
|
||||
* @param {Node} el Element to test for
|
||||
* @return {Number} Height of element
|
||||
*/
|
||||
export let getElementOffset = function(el, offset) {
|
||||
var elOffset = offset;
|
||||
if(elOffset > 1) elOffset = 1;
|
||||
if(elOffset > 0) elOffset = 0;
|
||||
|
||||
return Math.max(el.offsetHeight*elOffset);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get scroll position based on top/bottom position
|
||||
* @private
|
||||
* @return {String} Position of scroll
|
||||
*/
|
||||
export let getScrollPosition = function(position) {
|
||||
if(position === 'bottom') {
|
||||
// Scroll position from the bottom of the viewport
|
||||
return Math.max((window.scrollY || window.pageYOffset) + (window.innerHeight || document.documentElement.clientHeight));
|
||||
} else {
|
||||
// Scroll position from the top of the viewport
|
||||
return (window.scrollY || window.pageYOffset);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine whether an element is within the viewport
|
||||
* @param {Node} el Element to test for
|
||||
* @return {String} Position of scroll
|
||||
* @return {Boolean}
|
||||
*/
|
||||
export let isInView = function(el, position, offset) {
|
||||
// If the user has scrolled further than the distance from the element to the top of its parent
|
||||
return this.getScrollPosition(position) > (this.getElemDistance(el) + this.getElementOffset(el, offset)) ? true : false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove html tags from a string
|
||||
* @param {String} Initial string/html
|
||||
* @return {String} Sanitised string
|
||||
*/
|
||||
export let stripHTML = function(html) {
|
||||
let el = document.createElement("DIV");
|
||||
el.innerHTML = html;
|
||||
return el.textContent || el.innerText || "";
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds animation to an element and removes it upon animation completion
|
||||
* @param {Element} el Element to add animation to
|
||||
* @param {String} animation Animation class to add to element
|
||||
* @return
|
||||
*/
|
||||
export let addAnimation = (el, animation) => {
|
||||
let animationEvent = whichAnimationEvent();
|
||||
|
||||
let removeAnimation = () => {
|
||||
el.classList.remove(animation);
|
||||
el.removeEventListener(animationEvent, removeAnimation, false);
|
||||
};
|
||||
|
||||
el.classList.add(animation);
|
||||
el.addEventListener(animationEvent, removeAnimation, false);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get a random number between a range
|
||||
* @param {Number} min Minimum range
|
||||
* @param {Number} max Maximum range
|
||||
* @return {Number} Random number
|
||||
*/
|
||||
export let getRandomNumber = function(min, max) {
|
||||
return Math.floor(Math.random() * (max - min) + min);
|
||||
}
|
Loading…
Reference in a new issue