UNPKG

waibu-db

Version:
89 lines (82 loc) 4.26 kB
import wdbBase from '../wdb-base.js' async function form () { const WdbBase = await wdbBase.call(this) return class WdbForm extends WdbBase { static async handleRo ({ attr = {}, prop = {}, widget = {} } = {}) { return await this.component.buildTag({ tag: 'formPlaintext', attr, addons: widget.addons, selfCosing: true, noEscape: true }, { prop, widget }) } static async handleRw ({ attr = {}, prop = {}, widget = {} } = {}) { const { get, has, camelCase } = this.app.lib._ // const { stringifyAttribs } = this.app.waibuMpa attr.dataType = prop.type if (has(attr, 'name') && !has(attr, 'value') && widget.component === 'form-plaintext') { attr.value = get(this, `oldData.${attr.name}`, attr.dataValue) } return await this.component.buildTag({ tag: camelCase(widget.component), attr, addons: widget.addons, selfCosing: true, noEscape: true }, { prop, widget }) // return `<c:${widget.component} ${stringifyAttribs(attr)} />` } build = async () => { const { get, find, filter, forOwn, isEmpty, omit, isArray } = this.app.lib._ const { base64JsonEncode } = this.app.waibu const { req } = this.component const body = [] const xModels = get(this.schema, 'view.x.model', []) const xOns = get(this.schema, 'view.x.on', []) for (const l of this.schema.view.layout) { const fields = filter(l.fields, f => this.schema.view.fields.includes(f)) if (fields.length === 0) continue body.push(`<c:fieldset ${this.schema.view.card === false ? '' : 'card'} ${l.name[0] !== '_' ? ('t:legend="' + l.name + '"') : ''} grid-gutter="2">`) for (const f of fields) { const widget = this.schema.view.widget[f] const prop = find(this.schema.properties, { name: f }) if (!prop) continue if (['dobo:image'].includes(prop.feature)) continue const attr = { 'x-ref': widget.name, labelFloating: true, name: widget.name } if (xModels.includes(widget.name)) attr['x-model'] = widget.name forOwn(omit(widget.attr, ['url', 'refUrl', 'refName']), (v, k) => { if (v === true) attr[k] = true else attr[k] = v }) if (['array', 'object', 'text'].includes(prop.type)) attr.col = '12-md' attr.label = this.component.req.t(attr.label) const xon = filter(xOns, { field: widget.name }) for (const o of xon) { attr[`@${o.bind}`] = o.handler } if (widget.componentOpts) attr['c-opts'] = base64JsonEncode(widget.componentOpts) if (prop.virtual) widget.component = 'form-plaintext' const immutable = get(this, 'formData._immutable') || [] if (!req.routeOptions.config.xSite) { if ((immutable.length === 1 && immutable[0] === '*') || immutable.includes(prop.name)) widget.component = 'form-plaintext' } widget.addons = widget.addons ?? [] if (!isArray(widget.addons)) widget.addons = [widget.addons] for (const ao of widget.addons) { const tag = ao.type === 'button' ? 'btn' : 'formInputAddon' ao.html = await this.component.buildTag({ tag, attr: ao.attr, html: ao.html }) ao.position = ao.position ?? 'append' } let html if (widget.component === 'form-plaintext' || this.params.attr.method !== 'POST') { html = await WdbForm.handleRo.call(this, { attr, prop, widget }) } else { html = await WdbForm.handleRw.call(this, { attr, prop, widget }) } body.push(html) } body.push('</c:fieldset>') } const html = await this.component.buildSentence(body, this.component.locals) this.params.html = `${html}\n${this.params.html}` const xData = get(this.schema, 'view.x.data', '') this.params.attr['x-data'] = isEmpty(xData) ? '' : `{ ${xData} }` this.params.attr['x-init'] = get(this.schema, 'view.x.init', '') this.params.tag = this.params.attr.tag ?? 'form' } } } export default form