waibu-bootstrap
Version:
Bootstrap suport for Waibu Framework
169 lines (151 loc) • 6.8 kB
JavaScript
import { sizes } from '../method/after-build-tag/_lib.js'
async function getInputAttr (group, formControl = true, ro) {
const { has, omit, isPlainObject, isArray, isString } = this.app.lib._
const { callHandler } = this.app.bajo
const { req } = this.component
const { escape } = this.app.waibu
const buildOptions = (v, prop) => {
if (isString(v)) v = { value: v, text: v }
const { camelCase } = this.app.lib._
const key = camelCase(`${prop.name} ${v.text}`)
if (req.te(key)) v.text = req.t(key)
return v
}
if (formControl) group._.class.push('form-control')
const attr = omit(group._, ['hint', 'label', 'wrapper'])
if (has(attr, 'name') && !has(attr, 'value')) {
if (ro) attr.value = this.formData[attr.name]
else {
const prop = this.getProp(attr.name) ?? {}
attr.dataType = attr.dataType ?? prop.type
attr.dataValue = this.formData[attr.name]
if (prop.values) {
if (this.model) attr.options = await this.model.buildPropValues(prop, { req })
else attr.options = (isString(prop.values) ? await callHandler(prop.values) : [...prop.values]).map(v => buildOptions(v, prop))
attr.options = attr.options.map(v => buildOptions(v, prop))
} else if (isPlainObject(attr.dataValue)) {
attr.dataValue = JSON.stringify(attr.dataValue)
attr.value = attr.dataValue
} else if (isArray(attr.dataValue)) {
attr.options = attr.dataValue.map(v => buildOptions(v, prop))
} else {
attr.value = attr.dataValue
}
attr.dataValue = escape(attr.dataValue)
}
}
if (sizes.includes(attr.size) && formControl) attr.class.push(`form-control-${attr.size}`)
return omit(attr, ['size', 'col'])
}
export async function buildFormHint (group, tag, cls) {
if (!group.hint.id && group._.id) group.hint.id = group._.id + '-hint'
group.hint.class.push(cls ?? 'form-text')
return await this.component.buildTag({ tag: tag ?? 'div', attr: group.hint, html: group._.hint })
}
export async function buildFormLabel (group, tag, cls) {
const { omit } = this.app.lib._
group.label.for = group._.id
if (!group.label.floating) group.label.class.push(cls ?? 'form-label')
group.label = omit(group.label, ['floating'])
return await this.component.buildTag({ tag: tag ?? 'label', attr: group.label, html: group._.label })
}
export async function buildFormInput (group) {
const attr = await getInputAttr.call(this, group)
return await this.component.buildTag({ tag: 'input', attr, selfClosing: true })
}
export async function buildFormCheck (group) {
const { has, get } = this.app.lib._
const attr = await getInputAttr.call(this, group, false)
attr.type = 'checkbox'
attr.class.push('form-check-input')
if (has(attr, 'name') && !has(attr, 'value')) attr.value = 'true'
if (has(attr, 'name') && !has(attr, 'checked') && attr.value === get(this, `component.locals.form.${attr.name}`)) attr.checked = true
return await this.component.buildTag({ tag: 'input', attr, selfClosing: true })
}
export async function buildFormSwitch (group) {
const { has } = this.app.lib._
const attr = await getInputAttr.call(this, group, false)
attr.type = 'checkbox'
attr.class.push('form-check-input')
attr.role = 'switch'
if (has(attr, 'name')) attr.value = 'true'
if (has(attr, 'name') && !has(attr, 'checked') && attr.dataValue) attr.checked = 'true'
return await this.component.buildTag({ tag: 'input', attr, selfClosing: true })
}
export async function buildFormRadio (group) {
const attr = await getInputAttr.call(this, group, false)
attr.type = 'radio'
attr.class.push('form-check-input')
return await this.component.buildTag({ tag: 'input', attr, selfClosing: true })
}
export async function buildFormCheckToggle (group) {
const attr = await getInputAttr.call(this, group, false)
attr.type = 'checkbox'
attr.autocomplete = 'off'
attr.class.push('btn-check')
return await this.component.buildTag({ tag: 'input', attr, selfClosing: true })
}
export async function buildFormRadioToggle (group) {
const attr = await getInputAttr.call(this, group, false)
attr.type = 'radio'
attr.autocomplete = 'off'
attr.class.push('btn-check')
return await this.component.buildTag({ tag: 'input', attr, selfClosing: true })
}
export async function buildFormPlaintext (group) {
const { omit } = this.app.lib._
const attr = await getInputAttr.call(this, group, false, true)
attr.class.push('form-control-plaintext')
attr.readonly = ''
return await this.component.buildTag({ tag: 'div', attr: omit(attr, ['value']), html: attr.value })
}
export async function buildFormColor (group) {
const attr = await getInputAttr.call(this, group)
attr.class.push('form-control-color')
attr.type = 'color'
if (!attr.dim) attr.dim = 'width:100'
return await this.component.buildTag({ tag: 'input', attr, selfClosing: true })
}
export async function buildFormFile (group) {
const attr = await getInputAttr.call(this, group)
attr.type = 'file'
return await this.component.buildTag({ tag: 'input', attr, selfClosing: true })
}
export async function buildFormTextarea (group) {
const attr = await getInputAttr.call(this, group)
this.params.html = attr.value
attr.style.minHeight = '100px'
delete attr.value
return await this.component.buildTag({ tag: 'textarea', attr, html: this.params.html })
}
export async function buildFormSelect (group) {
const { omit, trim } = this.app.lib._
const { isSet } = this.app.lib.aneka
const { $ } = this.component
const { unescape } = this.app.waibu
let attr = await getInputAttr.call(this, group, false)
if (attr.remoteUrl) delete attr.options
try {
attr.dataValue = JSON.parse(unescape(attr.dataValue)).join('|')
} catch (err) {}
attr.value = isSet(attr.value) ? (attr.value + '') : undefined
attr.class.push('form-select')
let html = this.params.html
if (sizes.includes(attr.size)) attr.class.push(`form-select-${attr.size}`)
if (attr.options) html = await this.component.buildOptions({ attr })
else {
const items = []
$(`<div>${trim(html ?? '')}</div>`).find('option').each(function () {
items.push(trim($(this).prop('outerHTML')))
})
html = items.join('\n')
}
attr = omit(attr, ['size', 'type', 'options', 'value'])
return await this.component.buildTag({ tag: attr.tag ?? 'select', attr, html })
}
export async function buildFormRange (group) {
const attr = await getInputAttr.call(this, group, false)
attr.type = 'range'
attr.class.push('form-range')
return await this.component.buildTag({ tag: 'input', attr, selfClosing: true })
}