51 lines
1.5 KiB
JavaScript
51 lines
1.5 KiB
JavaScript
/* Use data-el or data-field attribute.
|
|
* Element with data-el="hum-ding" is accessible as this.elHumDing and fields with
|
|
* data-field="long-dong" as this.fieldLongDong.
|
|
*
|
|
* All field values can be retrieved with fieldValues() and uses the data-field attribute
|
|
* as LongDong as key.
|
|
*/
|
|
|
|
export class CustomHTMLElement extends HTMLElement {
|
|
constructor(useShadow) {// {{{
|
|
super()
|
|
|
|
this._fields = new Map()
|
|
|
|
const workOn = useShadow ? this.attachShadow({ mode: 'open' }) : this
|
|
workOn.appendChild(this.constructor.tmpl.content.cloneNode(true))
|
|
workOn.querySelectorAll('*').forEach(el => {
|
|
const field = el.dataset.field
|
|
if (field !== undefined) {
|
|
const fieldName = this.toElementName('field', field)
|
|
this[fieldName] = el
|
|
this._fields.set(this.toElementName('', field), el)
|
|
}
|
|
|
|
const name = el.dataset.el
|
|
if (name !== undefined) {
|
|
const elName = this.toElementName('el', name)
|
|
this[elName] = el
|
|
el.classList.add('el-' + name)
|
|
}
|
|
})
|
|
}// }}}
|
|
allFields() {// {{{
|
|
return this._fields
|
|
}// }}}
|
|
fieldValues() {// {{{
|
|
const state = {}
|
|
for (const [name, field] of this._fields) {
|
|
if (field.tagName.toLowerCase() == 'input' && field.getAttribute('type').toLowerCase() == 'checkbox')
|
|
state[name] = field.checked
|
|
else
|
|
state[name] = field.value
|
|
|
|
}
|
|
return state
|
|
}// }}}
|
|
toElementName(prefix, str) {// {{{
|
|
str = prefix + '-' + str
|
|
return str.replace(/-(id|[a-z])/g, match => match.toUpperCase().replace('-', ''))
|
|
}// }}}
|
|
}
|