(function () { window._openVSelect = null; requestAnimationFrame(e => { document.body.addEventListener('click', ev => { if (window._openVSelect && ev.target.closest('v-select') !== window._openVSelect) { window._openVSelect.toggle(false); } }) }) class VSelectElement extends HTMLElement { constructor() { super(); let self = this; self.rawValue = ""; self.setAttribute('tabindex', '0'); requestAnimationFrame(() => { self.update(); }) } get value() { return this._value; } set value(value) { this._value = value; this.dispatchEvent(new Event('input')); } get required() { return this.hasAttribute('required'); } set required(flag) { this.toggleAttribute('required', Boolean(flag)); } get name() { return this.getAttribute('name'); } set name(val) { this.toggleAttribute('name', val); } get form() { return this.closest('form'); } get options() { return $$('v-options v-option', this); } get selected() { return $$('v-options v-option[selected]', this); } connectedCallback() { /* const selected = this.selected; if (selected) return;*/ const options = Array.prototype.slice.call(this.options); const values = this.dataset.value ? this.dataset.value.split(",") : [""]; if (values.length === 1 && values[0].trim() === '') { return; } options .filter(item => values.indexOf(item.getAttribute('value')) !== -1) .forEach(item => item.setAttribute('selected', 'true')); } update() { let selected = [], lbl = $('v-label', this), fd = new FormData(); this.selected.forEach(e => { selected.push(e.innerText); fd.append(this.name, e.value); }) if (lbl.attributeChangedCallback) { lbl.attributeChangedCallback('value', '', selected.join(", ")); } this.isValid = !(this.required && selected.length === 0); this.rawValue = selected.join(", "); this.value = fd; } checkValidity() { return this.isValid; } toggle(open) { if (window._openVSelect && window._openVSelect.toggleSelect && open) { window._openVSelect.toggleSelect(false); } const options = $('v-options', this); if (!open || this.isOpen) { options.style.maxHeight = '0'; window._openVSelect = false; this.isOpen = false; this.update(); } else { options.focus(); let height = 0, children = options.children; for (let i = 0; i < children.length; i++) { height += children[i].offsetHeight; } options.style.maxHeight = height + 'px'; window._openVSelect = this; this.isOpen = true; } let l = $('v-label', this).classList; if (this.isOpen) { l.add('open'); } else { l.remove('open'); } } } class VSelectOptionElement extends HTMLElement { constructor() { super(); this._value = this.getAttribute('value'); this.addEventListener('click', e => { let parent = this.parentNode.parentNode, select = !this.selected; if (!parent.hasAttribute('multiple')) { parent.toggle(false); for (let item of parent.selected) { if (item !== this) { item.removeAttribute('selected'); } } } if (!this.disabled) { this.attributeChangedCallback('selected', false, select, true); this.parentNode.parentNode.update(); } }); this.createNew('div', {classes: ['ripple']}); } static get observedAttributes() { return ['selected', 'disabled', 'value']; } get value() { return this._value; } set value(value) { this._value = value; } attributeChangedCallback(name, oldValue, newValue, force) { if (name === 'selected' && this.hasAttribute('disabled')) { this.removeAttribute(name); return; } if (name === 'disabled' && newValue === true && this.hasAttribute('selected')) { this.attributeChangedCallback('selected', false, false); } if (force) { if (newValue) { this.setAttribute(name, newValue); } else { this.removeAttribute(name); } } this[name] = newValue; } } class VLabel extends HTMLElement { constructor() { super(); this.span = this.createNew('span'); this.createNew('div', {classes: ['ripple']}); this.empty = this.getAttribute('empty') || ""; this.span.innerHTML = this.getAttribute("value") || this.empty; this.addEventListener('click', this.openPopUp.bind(this)); } static get observedAttributes() { return ['empty', 'value']; } openPopUp() { this.parentNode.toggle(true); } attributeChangedCallback(name, oldValue, newValue) { if (name === 'value') { this.span.innerHTML = newValue || this.empty; } this[name] = newValue; } } customElements.define("v-label", VLabel); customElements.define("v-option", VSelectOptionElement); customElements.define("v-select", VSelectElement); })();