diff --git a/buildoz.js b/buildoz.js index ba67e5f..4e6d1fc 100644 --- a/buildoz.js +++ b/buildoz.js @@ -29,42 +29,41 @@ class Buildoz extends HTMLElement { } - + attributeChangedCallback(name, oldValue, newValue) { + this.attrs[name] = newValue + } } class BZselect extends Buildoz { constructor(){ super() - this.value = null this.open = false - //defaults, can be changed by corresponding attributes - this.attrs = { + this.defaultAttrs = { label: 'Select...', } } connectedCallback() { super.connectedCallback() - this.button = document.createElement('button') - this.button.textContent = this.attrs.label + this.button.textContent = this.getAttribute('label') || this.defaultAttrs.label this.prepend(this.button) this.button.addEventListener('click', this.toggle.bind(this)) this.options = this.querySelectorAll('option') - for(const opt of this.options){ - opt.addEventListener('click',(evt) => { this.onOption(evt.target.value) }) + for(const opt of this.options){ + opt.addEventListener('click', this.onClick.bind(this)) + if(opt.getAttribute('selected') !== null) this.onOption(opt.value, true) } } - static get observedAttributes(){ - return([...super.observedAttributes, 'label']) - } - - attributeChangedCallback(name, oldValue, newValue) { - this.attrs[name] = newValue - // on the fly changes here - } + // static get observedAttributes(){ // Only if you want actions on attr change + // return([...super.observedAttributes, 'myattr']) + // } + // + // attributeChangedCallback(name, oldValue, newValue) { + // super.attributeChangedCallback(name, oldValue, newValue) + // } toggle(){ for(const opt of this.options){ @@ -74,26 +73,40 @@ class BZselect extends Buildoz { this.open = !this.open } - onOption(value){ - this.value =value - this.toggle() - const opt = Array.from(this.options).find(opt => opt.value==value) - this.button.textContent = opt.textContent + onClick(evt){ + const opt = evt.target.closest('option') + if(opt && opt.value) this.onOption(opt.value) } - fill(opts){ - this.el.innerHTML ='' - if(!Array.isArray(opts)) opts = [opts] - const ul = Object.assign(document.createElement('ul'), - { className: `bz-selector ${this.config.ulClass ? this.config.ulClass :''}`, - }) - for(const opt of opts){ - const li = document.createElement('li') - li.innerHTML = `${opt.markup}` - li.setAttribute('data-value', opt.value) - ul.append(li) - } - this.el.append(ul) + onOption(value, silent=false){ + this.value = value + if(!silent) this.toggle() + const opt = Array.from(this.options).find(opt => opt.value==value) + if(value || (opt && opt.textContent)) this.button.textContent = opt.textContent + else this.button.textContent = this.getAttribute('label') || this.defaultAttrs.label + this.dispatchEvent(new Event('change', { + bubbles: true, + composed: false, + cancelable: false + })) + } + + addOption(value, markup){ + const opt = document.createElement('option') + opt.setAttribute(value, value) + opt.innerHTML = markup + opt.addEventListener('click',this.onClick.bind(this)) + this.append(opt) + this.options = this.querySelectorAll('option') + } + + fillOptions(opts, erase = true){ + if(erase){ + this.options.forEach(node => { node.remove() }) + this.options = this.querySelectorAll('option') + this.onOption('', true) // unselect last + } + for(const opt of opts) this.addOption(opt.value, opt.markup) } }