neo.mjs 5.4.12 → 5.5.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.4.12'
23
+ * @member {String} version='5.5.0'
24
24
  */
25
- version: '5.4.12'
25
+ version: '5.5.0'
26
26
  }
27
27
 
28
28
  /**
@@ -16,10 +16,12 @@ class Page4 extends FormPageContainer {
16
16
  * @member {Object} itemDefaults
17
17
  */
18
18
  itemDefaults: {
19
- module : CheckBox,
20
- labelText : null,
21
- labelWidth: 70,
22
- name : 'fruits'
19
+ module : CheckBox,
20
+ groupRequired : true,
21
+ labelText : null,
22
+ labelWidth : 70,
23
+ name : 'fruits',
24
+ showErrorTexts: false
23
25
  },
24
26
  /**
25
27
  * @member {Object[]} items
@@ -40,11 +42,14 @@ class Page4 extends FormPageContainer {
40
42
  value : 'orange',
41
43
  valueLabelText: 'Orange'
42
44
  }, {
45
+ showErrorTexts: true, // overwriting the itemDefaults value
43
46
  value : 'strawberry',
44
47
  valueLabelText: 'Strawberry'
45
48
  }, {
46
49
  labelText : 'Boolean',
50
+ groupRequired : false, // overwriting the itemDefaults value
47
51
  name : 'boolean',
52
+ showErrorTexts: true, // overwriting the itemDefaults value
48
53
  style : {marginTop: '50px'},
49
54
  uncheckedValue: false,
50
55
  value : true
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='5.4.12'
23
+ * @member {String} version='5.5.0'
24
24
  */
25
- version: '5.4.12'
25
+ version: '5.5.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.4.12",
3
+ "version": "5.5.0",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -56,7 +56,7 @@
56
56
  "neo-jsdoc": "^1.0.1",
57
57
  "neo-jsdoc-x": "^1.0.5",
58
58
  "postcss": "^8.4.23",
59
- "sass": "^1.62.0",
59
+ "sass": "^1.62.1",
60
60
  "webpack": "^5.80.0",
61
61
  "webpack-cli": "^5.0.2",
62
62
  "webpack-dev-server": "4.13.3",
@@ -237,12 +237,12 @@ const DefaultConfig = {
237
237
  useVdomWorker: true,
238
238
  /**
239
239
  * buildScripts/injectPackageVersion.mjs will update this value
240
- * @default '5.4.12'
240
+ * @default '5.5.0'
241
241
  * @memberOf! module:Neo
242
242
  * @name config.version
243
243
  * @type String
244
244
  */
245
- version: '5.4.12'
245
+ version: '5.5.0'
246
246
  };
247
247
 
248
248
  Object.assign(DefaultConfig, {
@@ -1,5 +1,6 @@
1
- import Base from './Base.mjs';
2
- import NeoArray from '../../util/Array.mjs';
1
+ import Base from './Base.mjs';
2
+ import ComponentManager from '../../manager/Component.mjs';
3
+ import NeoArray from '../../util/Array.mjs';
3
4
 
4
5
  /**
5
6
  * @class Neo.form.field.CheckBox
@@ -37,10 +38,18 @@ class CheckBox extends Base {
37
38
  * @member {String|null} error_=null
38
39
  */
39
40
  error_: null,
41
+ /**
42
+ * @member {Function} errorTextGroupRequired='Required'
43
+ */
44
+ errorTextGroupRequired: data => `Please check at least one item of the group: ${data.name}`,
40
45
  /**
41
46
  * @member {String} errorTextRequired='Required'
42
47
  */
43
48
  errorTextRequired: 'Required',
49
+ /**
50
+ * @member {Boolean} groupRequired_=false
51
+ */
52
+ groupRequired_: false,
44
53
  /**
45
54
  * @member {Boolean} hideLabel_=false
46
55
  */
@@ -87,6 +96,11 @@ class CheckBox extends Base {
87
96
  * @member {Boolean} required_=false
88
97
  */
89
98
  required_: false,
99
+ /**
100
+ * Use case: Set this config to false for all but one items with the same name.
101
+ * @member {Boolean} showErrorTexts_=true
102
+ */
103
+ showErrorTexts_: true,
90
104
  /**
91
105
  * In case the CheckBox does not belong to a group (multiple fields with the same name),
92
106
  * you can pass a custom value for the unchecked state.
@@ -148,6 +162,10 @@ class CheckBox extends Base {
148
162
  newCls = value ? me.iconClsChecked : me.iconCls,
149
163
  oldCls = value ? me.iconCls : me.iconClsChecked;
150
164
 
165
+ if (oldValue) {
166
+ me.clean = false;
167
+ }
168
+
151
169
  me.validate(); // silent
152
170
 
153
171
  labelEl.cn[1].checked = value;
@@ -171,6 +189,16 @@ class CheckBox extends Base {
171
189
  this.updateError(value)
172
190
  }
173
191
 
192
+ /**
193
+ * Triggered after the required groupRequired got changed
194
+ * @param {Boolean} value
195
+ * @param {Boolean} oldValue
196
+ * @protected
197
+ */
198
+ afterSetGroupRequired(value, oldValue) {
199
+ oldValue !== undefined && this.validate(false)
200
+ }
201
+
174
202
  /**
175
203
  * Triggered after the hideLabel config got changed
176
204
  * @param {String} value
@@ -291,6 +319,16 @@ class CheckBox extends Base {
291
319
  oldValue !== undefined && this.validate(false)
292
320
  }
293
321
 
322
+ /**
323
+ * Triggered after the showErrorTexts config got changed
324
+ * @param {Boolean} value
325
+ * @param {Boolean} oldValue
326
+ * @protected
327
+ */
328
+ afterSetShowErrorTexts(value, oldValue) {
329
+ oldValue !== undefined && this.validate(false)
330
+ }
331
+
294
332
  /**
295
333
  * Triggered after the value config got changed
296
334
  * @param {String} value
@@ -323,6 +361,21 @@ class CheckBox extends Base {
323
361
  me.update()
324
362
  }
325
363
 
364
+ /**
365
+ * Triggered before the groupRequired config gets changed.
366
+ * @param {Boolean} value
367
+ * @param {Boolean} oldValue
368
+ * @protected
369
+ */
370
+ beforeSetGroupRequired(value, oldValue) {
371
+ if (value && this.required) {
372
+ console.warn('Do not use groupRequired & required at the same time. Switching to required.', this);
373
+ return false
374
+ }
375
+
376
+ return value
377
+ }
378
+
326
379
  /**
327
380
  * Triggered before the labelCls config gets changed.
328
381
  * @param {String[]} value
@@ -407,8 +460,9 @@ class CheckBox extends Base {
407
460
  @param {Boolean} silent=false
408
461
  */
409
462
  updateError(value, silent=false) {
410
- let me = this,
411
- cls = me.cls,
463
+ let me = this,
464
+ cls = me.cls,
465
+ showError = value && me.showErrorTexts,
412
466
  errorNode;
413
467
 
414
468
  if (!(me.clean && !me.mounted)) {
@@ -419,13 +473,13 @@ class CheckBox extends Base {
419
473
 
420
474
  errorNode = me.vdom.cn[1];
421
475
 
422
- if (value) {
476
+ if (showError) {
423
477
  errorNode.html = value;
424
478
  } else {
425
479
  delete errorNode.html;
426
480
  }
427
481
 
428
- errorNode.removeDom = !value;
482
+ errorNode.removeDom = !showError;
429
483
 
430
484
  !silent && me.update()
431
485
  }
@@ -438,14 +492,47 @@ class CheckBox extends Base {
438
492
  */
439
493
  validate(silent=true) {
440
494
  let me = this,
441
- returnValue = true;
495
+ name = me.name,
496
+ returnValue = true,
497
+ checkBox, checkBoxes;
442
498
 
443
499
  if (!silent) {
444
500
  // in case we manually call validate(false) on a form or field before it is mounted, we do want to see errors.
445
501
  me.clean = false;
446
502
  }
447
503
 
448
- if (me.required && !me.checked) {
504
+ if (me.groupRequired) {
505
+ returnValue = false;
506
+
507
+ // discuss: we could limit this to checkBoxes / radios inside the same form, IF a top level form is used
508
+ checkBoxes = ComponentManager.find({
509
+ ntype: me.ntype,
510
+ name : me.name
511
+ });
512
+
513
+ // get the group validity state first
514
+ for (checkBox of checkBoxes) {
515
+ if (checkBox.checked) {
516
+ returnValue = true;
517
+ break;
518
+ }
519
+ }
520
+
521
+ // update all group items
522
+ for (checkBox of checkBoxes) {
523
+ if (checkBox.id !== me.id) {
524
+ if (!me.clean) {
525
+ checkBox.clean = false;
526
+ }
527
+
528
+ checkBox[me.clean ? '_error' : 'error'] = returnValue ? null : checkBox.errorTextGroupRequired({name})
529
+ }
530
+ }
531
+
532
+ if (!returnValue) {
533
+ me._error = me.errorTextGroupRequired({name});
534
+ }
535
+ } else if (me.required && !me.checked) {
449
536
  me._error = me.errorTextRequired;
450
537
  returnValue = false;
451
538
  }
@@ -162,6 +162,34 @@ class Number extends Text {
162
162
  }
163
163
  }
164
164
 
165
+ /**
166
+ * Triggered before the maxLength config gets changed
167
+ * @param {Number|null} value
168
+ * @param {Number|null} oldValue
169
+ * @protected
170
+ */
171
+ beforeSetMaxLength(value, oldValue) {
172
+ if (value !== null) {
173
+ console.warn('input type number does not support maxLength. use maxValue instead.', this)
174
+ }
175
+
176
+ return null;
177
+ }
178
+
179
+ /**
180
+ * Triggered before the minLength config gets changed
181
+ * @param {Number|null} value
182
+ * @param {Number|null} oldValue
183
+ * @protected
184
+ */
185
+ beforeSetMinLength(value, oldValue) {
186
+ if (value !== null) {
187
+ console.warn('input type number does not support minLength. use minValue instead.', this)
188
+ }
189
+
190
+ return null;
191
+ }
192
+
165
193
  /**
166
194
  * Triggered after the triggerPosition config got changed
167
195
  * @param {String} value
@@ -351,32 +379,25 @@ class Number extends Text {
351
379
  minValue = me.minValue,
352
380
  stepSize = me.stepSize,
353
381
  stepSizePow = Math.pow(10, me.stepSizeDigits),
354
- returnValue = true,
382
+ returnValue = super.validate(silent),
355
383
  errorParam = {maxValue, minValue, stepSize, value};
356
384
 
357
- if (!silent) {
358
- // in case we manually call validate(false) on a form or field before it is mounted, we do want to see errors.
359
- me.clean = false;
360
- }
361
-
362
- if (Neo.isNumber(maxValue) && isNumber && value > maxValue) {
363
- me._error = me.errorTextMaxValue(errorParam);
364
- returnValue = false;
365
- } else if (Neo.isNumber(minValue) && isNumber && value < minValue) {
366
- me._error = me.errorTextMinValue(errorParam);
367
- returnValue = false;
368
- } else if ((Math.round((value % me.stepSize) * stepSizePow) / stepSizePow) !== 0) {
369
- me._error = me.errorTextStepSize(errorParam);
370
- returnValue = false;
371
- }
372
-
373
385
  if (returnValue) {
374
- me._error = null;
386
+ if (Neo.isNumber(maxValue) && isNumber && value > maxValue) {
387
+ me._error = me.errorTextMaxValue(errorParam);
388
+ returnValue = false;
389
+ } else if (Neo.isNumber(minValue) && isNumber && value < minValue) {
390
+ me._error = me.errorTextMinValue(errorParam);
391
+ returnValue = false;
392
+ } else if ((Math.round((value % me.stepSize) * stepSizePow) / stepSizePow) !== 0) {
393
+ me._error = me.errorTextStepSize(errorParam);
394
+ returnValue = false;
395
+ }
375
396
  }
376
397
 
377
- !me.clean && me.updateError(me._error, silent);
398
+ !returnValue && !me.clean && me.updateError(me._error, silent);
378
399
 
379
- return !returnValue ? false : super.validate(silent);
400
+ return returnValue
380
401
  }
381
402
  }
382
403
 
@@ -1,5 +1,5 @@
1
1
  import CheckBox from './CheckBox.mjs';
2
- import ComponentManager from '../../manager/Component.mjs'
2
+ import ComponentManager from '../../manager/Component.mjs';
3
3
 
4
4
  /**
5
5
  * @class Neo.form.field.Radio