Files

117 lines
4.9 KiB
JavaScript

if(!app.helpers) app.helpers = {}
/**
* Mixing add-in methods to your view instance.
* All of this should not be a helper, but inherited this from WindozDomContent, but not my framework anymore.
* @category MyEic
*/
app.helpers.formBuilder = {
fieldsFromJSON(fieldsObj, fieldsValues, fieldsetLabel=null, changeCB=null){
let allFields = []
for(const propName in fieldsObj){
const fieldRow = ui.create(`<div class="cols-2"><label>${fieldsObj[propName].label}</label></div>`)
let component
switch(fieldsObj[propName].type){
case 'number':
component = document.createElement('input')
component.setAttribute('name',propName)
component.setAttribute('type','number')
if('min' in fieldsObj[propName]) component.setAttribute('min', fieldsObj[propName].min)
if('max' in fieldsObj[propName]) component.setAttribute('max', fieldsObj[propName].max)
if(typeof(changeCB) == 'function') component.addEventListener('input', (evt) => { changeCB(evt, component) })
break
case 'string':
component = document.createElement('input')
component.setAttribute('name',propName)
component.setAttribute('type','text')
if(typeof(changeCB) == 'function') component.addEventListener('input', (evt) => { changeCB(evt, component) })
break
case 'boolean':
component = document.createElement('bz-toggler')
component.setAttribute('name',propName)
component.setAttribute('trueValue','1')
component.setAttribute('falseValue','0')
fieldRow.append(component.el)
if(typeof(changeCB) == 'function') component.addEventListener('change', (evt) => { changeCB(evt, component) })
break
case 'list':
component = document.createElement('bz-select')
component.setAttribute('name', propName)
component.fillOptions( fieldsObj[propName].choices.map(item => {
return({ markup: `${item}`, value: item})
}))
if(typeof(changeCB) == 'function') component.addEventListener('change', (evt) => { changeCB(evt, component) })
break
default:
console.warn(`Unknown field type ${fieldsObj[propName].type}`)
}
if(component){
component.classList.add('formbuilder-field')
const rawValue = this.getPathInObj(fieldsValues, propName) ?? fieldsObj[propName].default
if(fieldsObj[propName].type === 'number') {
const n = Number(rawValue)
component.value = Number.isFinite(n) ? n : 0
} else {
component.value = rawValue
}
fieldRow.append(component)
allFields.push(fieldRow)
}
}
if(fieldsetLabel!==null){
const fieldset = document.createElement('fieldset')
if(fieldsetLabel!=''){
const lgd = document.createElement('legend')
lgd.innerHTML = fieldsetLabel
fieldset.append(lgd)
}
fieldset.append(...allFields)
return([fieldset])
} else {
return(allFields)
}
},
getPathInObj(obj, path){
const parts = path.split('.')
let target = obj
for (let i = 0; i < parts.length - 1; i++) {
const key = parts[i]
if(!target[parts[i]]) return(null)
target = target[parts[i]]
}
return(target[parts[parts.length - 1]] )
},
#fieldValue(el) {
if(el?.type === 'number') {
const n = Number(el.value)
return(Number.isFinite(n) ? n : el.value)
}
return(el.value)
},
getFieldsValues(rootSel){
const result = {}
document.querySelectorAll(`${rootSel} .formbuilder-field`).forEach(el => {
const path = el.name.split('.')
let target = result
for (let i = 0; i < path.length - 1; i++) {
const key = path[i]
if (!target[key] || typeof target[key] !== 'object') {
target[key] = {}
}
target = target[key]
}
target[path[path.length - 1]] = this.#fieldValue(el)
})
return(result)
},
getFieldValue(rootSel, name){
const comp = document.querySelector(`${rootSel} .formbuilder-field[name="${name}"]`)
if(comp) return(this.#fieldValue(comp))
else return(null)
},
}