neo.mjs 5.7.7 → 5.9.0

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.
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='5.7.7'
23
+ * @member {String} version='5.9.0'
24
24
  */
25
- version: '5.7.7'
25
+ version: '5.9.0'
26
26
  }
27
27
 
28
28
  /**
@@ -75,7 +75,8 @@ class FormContainer extends BaseFormContainer {
75
75
  {module: () => import('./pages/Page11.mjs')},
76
76
  {module: () => import('./pages/Page12.mjs')},
77
77
  {module: () => import('./pages/Page13.mjs')},
78
- {module: () => import('./pages/Page14.mjs')}
78
+ {module: () => import('./pages/Page14.mjs')},
79
+ {module: () => import('./pages/Page15.mjs')}
79
80
  ]
80
81
  }, {
81
82
  module: Toolbar,
@@ -0,0 +1,34 @@
1
+ import CurrencyField from '../../../../src/form/field/Currency.mjs';
2
+ import FormPageContainer from '../FormPageContainer.mjs';
3
+
4
+ /**
5
+ * @class Form.view.pages.Page15
6
+ * @extends Form.view.FormPageContainer
7
+ */
8
+ class Page15 extends FormPageContainer {
9
+ static config = {
10
+ /**
11
+ * @member {String} className='Form.view.pages.Page15'
12
+ * @protected
13
+ */
14
+ className: 'Form.view.pages.Page15',
15
+ /**
16
+ * @member {Object[]} items
17
+ */
18
+ items: [{
19
+ module : CurrencyField,
20
+ labelText: 'Amount in €',
21
+ name : 'page15.field1',
22
+ value : 15.00
23
+ }, {
24
+ module : CurrencyField,
25
+ labelText: 'Amount in $',
26
+ name : 'page15.field2',
27
+ value : 16.10
28
+ }]
29
+ }
30
+ }
31
+
32
+ Neo.applyClassConfig(Page15);
33
+
34
+ export default Page15;
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='5.7.7'
23
+ * @member {String} version='5.9.0'
24
24
  */
25
- version: '5.7.7'
25
+ version: '5.9.0'
26
26
  }
27
27
 
28
28
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "5.7.7",
3
+ "version": "5.9.0",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -19,6 +19,7 @@
19
19
  {"id": 15, "cardIndex": 10, "isHeader": false, "isValid": null, "name": "ZipCodeFields"},
20
20
  {"id": 16, "cardIndex": 11, "isHeader": false, "isValid": null, "name": "EmailFields"},
21
21
  {"id": 17, "cardIndex": 12, "isHeader": false, "isValid": null, "name": "UrlFields"},
22
- {"id": 18, "cardIndex": 13, "isHeader": false, "isValid": null, "name": "PhoneFields"}
22
+ {"id": 18, "cardIndex": 13, "isHeader": false, "isValid": null, "name": "PhoneFields"},
23
+ {"id": 19, "cardIndex": 14, "isHeader": false, "isValid": null, "name": "CurrencyFields"}
23
24
  ]
24
25
  }
@@ -236,12 +236,12 @@ const DefaultConfig = {
236
236
  useVdomWorker: true,
237
237
  /**
238
238
  * buildScripts/injectPackageVersion.mjs will update this value
239
- * @default '5.7.7'
239
+ * @default '5.9.0'
240
240
  * @memberOf! module:Neo
241
241
  * @name config.version
242
242
  * @type String
243
243
  */
244
- version: '5.7.7'
244
+ version: '5.9.0'
245
245
  };
246
246
 
247
247
  Object.assign(DefaultConfig, {
@@ -24,6 +24,24 @@ class Base extends Component {
24
24
  * @member {String|null} formGroup_=null
25
25
  */
26
26
  formGroup_: null,
27
+ /**
28
+ * @member {String|null} name_=null
29
+ */
30
+ name_: null,
31
+ /**
32
+ * Neo itself does not need field names to get mapped to the DOM (input nodes),
33
+ * except for CheckBoxes & Radios to work. It can be useful for testing tools
34
+ * & accessibility though, so the default got set to true.
35
+ * Feel free to change it to false to keep the DOM minimal.
36
+ * @member {Boolean} renderName_=true
37
+ */
38
+ renderName_: true,
39
+ /**
40
+ * In case renderName is set to true, you can optionally render the combination
41
+ * of all formGroup(s) & the field name into the DOM => input node
42
+ * @member {Boolean} renderPath=true
43
+ */
44
+ renderPath: true,
27
45
  /**
28
46
  * @member {*} value_=null
29
47
  */
@@ -35,6 +53,22 @@ class Base extends Component {
35
53
  * @member {String|null} formGroupString=null
36
54
  */
37
55
  formGroupString = null
56
+ /**
57
+ * An internal cache for formGroup(s) and the field name
58
+ * @member {String|null} path=null
59
+ */
60
+ path = null
61
+
62
+ /**
63
+ * Triggered after the name config got changed
64
+ * @param {String|null} value
65
+ * @param {String|null} oldValue
66
+ */
67
+ afterSetName(value, oldValue) {
68
+ let me = this;
69
+
70
+ me.renderName && me.changeInputElKey('name', me.renderPath ? me.getPath() : value)
71
+ }
38
72
 
39
73
  /**
40
74
  * Triggered after the value config got changed
@@ -43,7 +77,7 @@ class Base extends Component {
43
77
  */
44
78
  afterSetValue(value, oldValue) {
45
79
  if (oldValue !== undefined) {
46
- this.fireChangeEvent(value, oldValue);
80
+ this.fireChangeEvent(value, oldValue)
47
81
  }
48
82
  }
49
83
 
@@ -72,7 +106,25 @@ class Base extends Component {
72
106
 
73
107
  me.formGroupString = returnValue;
74
108
 
75
- return returnValue;
109
+ return returnValue
110
+ }
111
+
112
+ /**
113
+ * Changes the value of a inputEl vdom object attribute or removes it in case it has no value
114
+ * @param {String} key
115
+ * @param {Array|Number|Object|String|null} value
116
+ * @param {Boolean} silent=false
117
+ */
118
+ changeInputElKey(key, value, silent=false) {
119
+ let me = this;
120
+
121
+ if (value || Neo.isBoolean(value) || value === 0) {
122
+ me.getInputEl()[key] = value;
123
+ } else {
124
+ delete me.getInputEl()[key];
125
+ }
126
+
127
+ !silent && me.update()
76
128
  }
77
129
 
78
130
  /**
@@ -103,6 +155,41 @@ class Base extends Component {
103
155
  }
104
156
  }
105
157
 
158
+ /**
159
+ * Override this method as needed
160
+ * @returns {Object|null}
161
+ */
162
+ getInputEl() {
163
+ return this.vdom
164
+ }
165
+
166
+ /**
167
+ * Returns the combination of the field formGroup(s) & name
168
+ * @returns {String|null}
169
+ */
170
+ getPath() {
171
+ let me = this,
172
+ path;
173
+
174
+ if (!me.path) {
175
+ path = me.formGroup ? me.formGroup.split('.') : [];
176
+
177
+ me.name && path.push(me.name);
178
+
179
+ if (path.length < 1) {
180
+ return null
181
+ }
182
+
183
+ me.path = path.join('.');
184
+ }
185
+
186
+ if (!me.path) {
187
+ me.path = 'none'
188
+ }
189
+
190
+ return me.path === 'none' ? null: me.path
191
+ }
192
+
106
193
  /**
107
194
  * @returns {*}
108
195
  */
@@ -93,16 +93,12 @@ class CheckBox extends Base {
93
93
  * @member {Number|String} labelWidth_=150
94
94
  */
95
95
  labelWidth_: 150,
96
- /**
97
- * @member {String} The name (group) of the input dom node
98
- */
99
- name_: '',
100
96
  /**
101
97
  * @member {Boolean} required_=false
102
98
  */
103
99
  required_: false,
104
100
  /**
105
- * Use case: Set this config to false for all but one items with the same name.
101
+ * Use case: Set this config to false for all but one item with the same name.
106
102
  * @member {Boolean} showErrorTexts_=true
107
103
  */
108
104
  showErrorTexts_: true,
@@ -259,8 +255,7 @@ class CheckBox extends Base {
259
255
  * @protected
260
256
  */
261
257
  afterSetInputType(value, oldValue) {
262
- this.vdom.cn[0].cn[1].type = value;
263
- this.update()
258
+ this.changeInputElKey('type', value)
264
259
  }
265
260
 
266
261
  /**
@@ -320,17 +315,6 @@ class CheckBox extends Base {
320
315
  }
321
316
  }
322
317
 
323
- /**
324
- * Triggered after the name config got changed
325
- * @param {String} value
326
- * @param {String} oldValue
327
- * @protected
328
- */
329
- afterSetName(value, oldValue) {
330
- this.vdom.cn[0].cn[1].name = value;
331
- this.update()
332
- }
333
-
334
318
  /**
335
319
  * Triggered after the required config got changed
336
320
  * @param {Boolean} value
@@ -358,10 +342,7 @@ class CheckBox extends Base {
358
342
  * @protected
359
343
  */
360
344
  afterSetValue(value, oldValue) {
361
- if (value) {
362
- this.vdom.cn[0].cn[1].value = value;
363
- this.update()
364
- }
345
+ this.changeInputElKey('value', value)
365
346
  }
366
347
 
367
348
  /**
@@ -419,6 +400,17 @@ class CheckBox extends Base {
419
400
  return this.beforeSetEnumValue(value, oldValue, 'labelPosition')
420
401
  }
421
402
 
403
+ /**
404
+ * Triggered before the renderName config gets changed.
405
+ * CheckBoxes & radios rely on this flag being set to true
406
+ * @param {Boolean} value
407
+ * @param {Boolean} oldValue
408
+ * @protected
409
+ */
410
+ beforeSetRenderName(value, oldValue) {
411
+ return true
412
+ }
413
+
422
414
  /**
423
415
  * @returns {String}
424
416
  */
@@ -426,6 +418,13 @@ class CheckBox extends Base {
426
418
  return `${this.id}__icon`
427
419
  }
428
420
 
421
+ /**
422
+ * @returns {Object|null}
423
+ */
424
+ getInputEl() {
425
+ return this.vdom.cn[0].cn[1]
426
+ }
427
+
429
428
  /**
430
429
  * @returns {String}
431
430
  */
@@ -0,0 +1,54 @@
1
+ import Number from './Number.mjs';
2
+
3
+ /**
4
+ * @class Neo.form.field.Currency
5
+ * @extends Neo.form.field.Number
6
+ */
7
+ class Currency extends Number {
8
+ static config = {
9
+ /**
10
+ * @member {String} className='Neo.form.field.Currency'
11
+ * @protected
12
+ */
13
+ className: 'Neo.form.field.Currency',
14
+ /**
15
+ * @member {String} ntype='currencyfield'
16
+ * @protected
17
+ */
18
+ ntype: 'currencyfield',
19
+ /**
20
+ * @member {Number} stepSize=0.01
21
+ */
22
+ stepSize: 0.01
23
+ }
24
+
25
+ /**
26
+ * @param {Number|null} value
27
+ * @returns {Number}
28
+ */
29
+ inputValueAdjustor(value) {
30
+ if (Neo.isString(value)) {
31
+ value = parseFloat(value).toFixed(2);
32
+
33
+ return parseInt(value.replace('.', '')) / 100
34
+ }
35
+
36
+ return value
37
+ }
38
+
39
+ /**
40
+ * @param {Number|null} value
41
+ * @returns {String}
42
+ */
43
+ inputValueRenderer(value) {
44
+ if (value === null) {
45
+ return null
46
+ }
47
+
48
+ return value.toFixed(2)
49
+ }
50
+ }
51
+
52
+ Neo.applyClassConfig(Currency);
53
+
54
+ export default Currency;
@@ -243,6 +243,18 @@ class Number extends Text {
243
243
  return value
244
244
  }
245
245
 
246
+ /**
247
+ * @param {Number|null} value
248
+ * @returns {Boolean}
249
+ */
250
+ fitsStepSize(value) {
251
+ if (value === null) {
252
+ return true
253
+ }
254
+
255
+ return (parseInt(value.toString().replace('.', '')) * (1 / this.stepSize)) % 1 === 0
256
+ }
257
+
246
258
  /**
247
259
  * @returns {Boolean}
248
260
  */
@@ -261,7 +273,7 @@ class Number extends Text {
261
273
  return false;
262
274
  }
263
275
 
264
- if ((value / me.stepSize) % 1 !== 0) {
276
+ if (!me.fitsStepSize(value)) {
265
277
  return false;
266
278
  }
267
279
 
@@ -393,7 +405,7 @@ class Number extends Text {
393
405
  } else if (Neo.isNumber(minValue) && isNumber && value < minValue) {
394
406
  me._error = me.errorTextMinValue(errorParam);
395
407
  returnValue = false;
396
- } else if ((value / me.stepSize) % 1 !== 0) {
408
+ } else if (!me.fitsStepSize(value)) {
397
409
  me._error = me.errorTextStepSize(errorParam);
398
410
  returnValue = false;
399
411
  }
@@ -667,7 +667,7 @@ class Text extends Base {
667
667
  * @protected
668
668
  */
669
669
  afterSetSpellCheck(value, oldValue) {
670
- this.changeInputElKey('spellcheck', Neo.isBoolean(value) ? value : null);
670
+ this.changeInputElKey('spellcheck', Neo.isBoolean(value) ? value : null)
671
671
  }
672
672
 
673
673
  /**
@@ -780,7 +780,7 @@ class Text extends Base {
780
780
 
781
781
  me.silentVdomUpdate = true;
782
782
 
783
- me.getInputEl().value = value;
783
+ me.getInputEl().value = me.inputValueRenderer(value);
784
784
 
785
785
  me.validate(); // silent
786
786
 
@@ -932,24 +932,6 @@ class Text extends Base {
932
932
  return value
933
933
  }
934
934
 
935
- /**
936
- * Changes the value of a inputEl vdom object attribute or removes it in case it has no value
937
- * @param {String} key
938
- * @param {Array|Number|Object|String|null} value
939
- * @param {Boolean} silent=false
940
- */
941
- changeInputElKey(key, value, silent=false) {
942
- let me = this;
943
-
944
- if (value || Neo.isBoolean(value) || value === 0) {
945
- me.getInputEl()[key] = value;
946
- } else {
947
- delete me.getInputEl()[key];
948
- }
949
-
950
- !silent && me.update()
951
- }
952
-
953
935
  /**
954
936
  * Resets the field to its original value or null depending on the clearToOriginalValue config
955
937
  */
@@ -1122,6 +1104,26 @@ class Text extends Base {
1122
1104
  return false
1123
1105
  }
1124
1106
 
1107
+ /**
1108
+ * Transform an input node value before applied to this.value.
1109
+ * Override as needed
1110
+ * @param {*} value
1111
+ * @returns {*}
1112
+ */
1113
+ inputValueAdjustor(value) {
1114
+ return value
1115
+ }
1116
+
1117
+ /**
1118
+ * Transform a value before getting rendered.
1119
+ * Override as needed
1120
+ * @param {*} value
1121
+ * @returns {*}
1122
+ */
1123
+ inputValueRenderer(value) {
1124
+ return value
1125
+ }
1126
+
1125
1127
  /**
1126
1128
  * @returns {Boolean}
1127
1129
  */
@@ -1220,7 +1222,7 @@ class Text extends Base {
1220
1222
  vnode.vnode.attributes.value = value;
1221
1223
  }
1222
1224
 
1223
- me.value = value
1225
+ me.value = me.inputValueAdjustor(value)
1224
1226
  }
1225
1227
 
1226
1228
  /**