waibu-bootstrap 2.8.2 → 2.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,19 @@
1
1
  import { sizes } from '../method/after-build-tag/_lib.js'
2
2
 
3
3
  async function getInputAttr (group, formControl = true, ro) {
4
- const { has, omit, forOwn, isPlainObject, isArray, get, isString } = this.app.lib._
4
+ const { has, omit, isPlainObject, isArray, isString } = this.app.lib._
5
5
  const { callHandler } = this.app.bajo
6
6
  const { req } = this.component
7
7
  const { escape } = this.app.waibu
8
8
 
9
+ const buildOptions = (v, prop) => {
10
+ if (isString(v)) v = { value: v, text: v }
11
+ const { camelCase } = this.app.lib._
12
+ const key = camelCase(`${prop.name} ${v.text}`)
13
+ if (req.te(key)) v.text = req.t(key)
14
+ return v
15
+ }
16
+
9
17
  if (formControl) group._.class.push('form-control')
10
18
  const attr = omit(group._, ['hint', 'label', 'wrapper'])
11
19
  if (has(attr, 'name') && !has(attr, 'value')) {
@@ -14,26 +22,19 @@ async function getInputAttr (group, formControl = true, ro) {
14
22
  const prop = this.getProp(attr.name)
15
23
  attr.dataType = attr.dataType ?? prop.type
16
24
  attr.dataValue = this.formData[attr.name]
17
- if (isPlainObject(attr.dataValue) || isArray(attr.dataValue)) attr.dataValue = JSON.stringify(attr.dataValue)
18
- attr.value = escape(get(this.formData, `_fmt.${attr.name}`, attr.dataValue))
19
- attr.dataValue = escape(attr.dataValue)
20
25
  if (prop.values) {
21
- const values = (isString(prop.values) ? await callHandler(prop.values) : [...prop.values]).map(v => {
22
- if (isString(v)) v = { value: v, text: v }
23
- const { camelCase } = this.app.lib._
24
- const key = camelCase(`${prop.name} ${v.text}`)
25
- if (req.te(key)) v.text = req.t(key)
26
- return v
27
- })
28
- attr.options = values
26
+ attr.options = (isString(prop.values) ? await callHandler(prop.values) : [...prop.values]).map(v => buildOptions(v, prop))
27
+ } else if (isPlainObject(attr.dataValue)) {
28
+ attr.dataValue = JSON.stringify(attr.dataValue)
29
+ attr.value = attr.dataValue
30
+ } else if (isArray(attr.dataValue)) {
31
+ attr.options = attr.dataValue.map(v => buildOptions(v, prop))
32
+ } else {
33
+ attr.value = attr.dataValue
29
34
  }
35
+ attr.dataValue = escape(attr.dataValue)
30
36
  }
31
37
  }
32
- if (attr.href) {
33
- forOwn(this.formData, (v, k) => {
34
- attr.href = attr.href.replace(`{${k}}`, v)
35
- })
36
- }
37
38
  if (sizes.includes(attr.size) && formControl) attr.class.push(`form-control-${attr.size}`)
38
39
  return omit(attr, ['size', 'col'])
39
40
  }
@@ -102,19 +103,11 @@ export async function buildFormRadioToggle (group, params) {
102
103
  }
103
104
 
104
105
  export async function buildFormPlaintext (group, params) {
106
+ const { omit } = this.app.lib._
105
107
  const attr = await getInputAttr.call(this, group, false, true)
106
108
  attr.class.push('form-control-plaintext')
107
109
  attr.readonly = ''
108
- if (['object', 'array', 'text'].includes(attr.dataType)) {
109
- attr.style.minHeight = '100px'
110
- return await this.component.buildTag({ tag: 'textarea', attr, html: attr.value })
111
- }
112
- if (attr.href) {
113
- const content = attr.value ? this.component.req.t(attr.value) : attr.href
114
- const html = await this.component.buildTag({ tag: 'a', attr: { href: attr.href, content } })
115
- return await this.component.buildTag({ tag: 'div', attr, html })
116
- }
117
- return await this.component.buildTag({ tag: 'input', attr, selfClosing: true })
110
+ return await this.component.buildTag({ tag: 'div', attr: omit(attr, ['value']), html: attr.value })
118
111
  }
119
112
 
120
113
  export async function buildFormColor (group, params) {
@@ -143,7 +136,12 @@ export async function buildFormSelect (group, params) {
143
136
  const { omit, trim } = this.app.lib._
144
137
  const { isSet } = this.app.lib.aneka
145
138
  const { $ } = this.component
139
+ const { unescape } = this.app.waibu
146
140
  let attr = await getInputAttr.call(this, group, false)
141
+ if (attr.remoteUrl) delete attr.options
142
+ try {
143
+ attr.dataValue = JSON.parse(unescape(attr.dataValue)).join('|')
144
+ } catch (err) {}
147
145
  attr.value = isSet(attr.value) ? (attr.value + '') : undefined
148
146
  attr.class.push('form-select')
149
147
  let html = params.html
@@ -4,9 +4,9 @@ import { build } from './form-input.js'
4
4
  async function formPlaintext () {
5
5
  return class FormPlaintext extends this.app.baseClass.MpaWidget {
6
6
  build = async () => {
7
+ const { req } = this.component
7
8
  const { isEmpty, get } = this.app.lib._
8
9
  const { escape } = this.app.waibu
9
- const { isHtmlLink } = this.app.bajoExtra
10
10
  this.params.attr.disabled = true
11
11
  const { name } = this.params.attr
12
12
  if (this.params.attr.labelFloating) this.params.attr.class.push('border', 'rounded')
@@ -17,11 +17,13 @@ async function formPlaintext () {
17
17
  const format = get(this.schema, `view.format.${name}`)
18
18
  const labelField = get(this.schema, `view.widget.${name}.attr.labelField`)
19
19
  if (prop.ref) {
20
- const newValue = this.getRefValue({ field: name, labelField, refName: this.getRefName(name) })
21
- if (format && !isEmpty(newValue)) this.params.attr.href = await format.call(this, newValue, this.formData, { linkOnly: true })
22
- } else if (format && !isEmpty(value)) value = await format.call(this, value, this.formData)
20
+ const result = this.getRefValue({ field: name, labelField, refName: this.getRefName(name) })
21
+ if (result) {
22
+ value = format ? await format.call(this, value, this.formData, { req }) : result
23
+ }
24
+ } else if (format) value = await format.call(this, value, this.formData, { req })
23
25
  this.params.attr.dataValue = escape(dataValue)
24
- if (!isHtmlLink(value)) this.params.attr.value = escape(value)
26
+ this.params.attr.value = value
25
27
  this.params.attr.dataType = prop.type
26
28
  }
27
29
  await build.call(this, buildFormPlaintext, this.params)
@@ -25,13 +25,20 @@ async function formSelectExt () {
25
25
  this.params.attr.id = this.params.attr.id ?? generateId('alpha')
26
26
  this.params.attr['x-ref'] = xref
27
27
  const xData = ['instance: null', 'value: null']
28
- const plugins = ['drag_drop']
29
- if (!this.params.attr.noDropdownInput) plugins.push('dropdown_input')
30
- if (this.params.attr.removeBtn) plugins.push('remove_button')
31
- if (this.params.attr.clearBtn) plugins.push('clear_button')
32
- if (this.params.attr.optgroupColumns) plugins.push('optgroup_columns')
28
+ const plugins = {
29
+ drag_drop: {}
30
+ }
31
+ if (!this.params.attr.noDropdownInput) plugins.dropdown_input = {}
32
+ // if (this.params.attr.removeBtn) plugins.remove_button = {}
33
+ if (this.params.attr.clearBtn) plugins.clear_button = {}
34
+ if (this.params.attr.optgroupColumns) plugins.optgroup_columns = {}
35
+ if (this.params.attr.multiple) {
36
+ plugins.checkbox_options = {}
37
+ plugins.clear_button = {}
38
+ }
33
39
  if (this.params.attr.noCaret) this.params.attr.class.push('no-caret') // TODO: no caret remove caret on ALL instances, need to make it instance specific
34
40
  let opts = { plugins }
41
+ if (this.params.attr.allowCreate) opts.create = true
35
42
  let cOpts = {}
36
43
  if (this.params.attr.cOpts) {
37
44
  try {
@@ -124,6 +131,11 @@ async function formSelectExt () {
124
131
  })
125
132
  }
126
133
  `
134
+ } else {
135
+ text += `if (!_.isEmpty(this.value)) {
136
+ if (!_.isArray(this.value)) this.value = [this.value]
137
+ this.instance.setValue(this.value)
138
+ }`
127
139
  }
128
140
  text += '}'
129
141
  xData.push(text)
@@ -131,6 +143,7 @@ async function formSelectExt () {
131
143
  // this.params.attr['@load.window'] = 'onLoad()'
132
144
  this.params.attr['x-init'] = 'onLoad()'
133
145
  await build.call(this, buildFormSelect, this.params)
146
+ /*
134
147
  let options = []
135
148
  if (this.params.attr.options) {
136
149
  try {
@@ -140,6 +153,7 @@ async function formSelectExt () {
140
153
  }
141
154
  }
142
155
  if (options.length > 0) this.params.attr.options = options
156
+ */
143
157
  this.params.attr = omit(this.params.attr, ['noDropdownInput', 'removeBtn', 'clearBtn', 'c-opts', 'remoteUrl', 'remoteSearchField', 'remoteLabelField', 'remoteValueField', 'remoteQuery', 'remoteApiKey'])
144
158
  }
145
159
  }
@@ -7,7 +7,10 @@ async function theme () {
7
7
  'waibuBootstrap.virtual:/bootstrap/js/bootstrap.bundle.min.js',
8
8
  'bajo.virtual:/lodash/lodash.min.js',
9
9
  '$waibuMpa:/wmpa.js',
10
- '$waibuBootstrap.asset:/js/wbs.js'
10
+ {
11
+ src: '$waibuBootstrap.asset:/js/wbs.js',
12
+ defer: true
13
+ }
11
14
  ]
12
15
  const meta = [{
13
16
  name: 'viewport',
@@ -3,10 +3,6 @@
3
3
  class Wbs {
4
4
  constructor () {
5
5
  this.engine = window.mdb ?? window.bootstrap
6
- this.init()
7
- }
8
-
9
- init () {
10
6
  window.addEventListener('load', evt => {
11
7
  const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]')
12
8
  const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new this.engine.Popover(popoverTriggerEl)) // eslint-disable-line no-unused-vars
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waibu-bootstrap",
3
- "version": "2.8.2",
3
+ "version": "2.9.1",
4
4
  "description": "Bootstrap suport for Waibu Framework",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/wiki/CHANGES.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-05-16
4
+
5
+ - [2.9.1] Bug fix in ```form-select-ext``` widget
6
+ - [2.9.1] Bug fix in ```util.getInputAttr``` helper
7
+
8
+ ## 2026-05-11
9
+
10
+ - [2.9.0] Updates to match ```dobo@2.23.0``` specs
11
+ - [2.9.0] Bug fix in ```theme.js```
12
+ - [2.9.0] Auto link for widget bound to database with refs
13
+
14
+ ## 2026-05-03
15
+
16
+ - [2.8.2] Bug fix in ```form-plaintext``` widgets
17
+
3
18
  ## 2026-04-25
4
19
 
5
20
  - [2.8.0] Change options to format value using the new key set by dobo