neo.mjs 5.4.9 → 5.4.10

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.9'
23
+ * @member {String} version='5.4.10'
24
24
  */
25
- version: '5.4.9'
25
+ version: '5.4.10'
26
26
  }
27
27
 
28
28
  /**
@@ -5,6 +5,10 @@ Neo.overwrites = {
5
5
  Text: {
6
6
  labelPosition_ : 'inline',
7
7
  showOptionalText_: true
8
+ },
9
+ ZipCode: {
10
+ maxLength: 5,
11
+ minLength: 5
8
12
  }
9
13
  }
10
14
  }
@@ -1,5 +1,5 @@
1
1
  import FormPageContainer from '../FormPageContainer.mjs';
2
- import TextField from '../../../../src/form/field/Text.mjs';
2
+ import ZipCodeField from '../../../../src/form/field/ZipCode.mjs';
3
3
 
4
4
  /**
5
5
  * @class Form.view.pages.Page11
@@ -16,13 +16,15 @@ class Page11 extends FormPageContainer {
16
16
  * @member {Object[]} items
17
17
  */
18
18
  items: [{
19
- module : TextField,
20
- labelText: 'Page 11 Field 1',
21
- name : 'page11field1'
19
+ module : ZipCodeField,
20
+ labelText: 'Munich',
21
+ name : 'page11.field1',
22
+ required : true,
23
+ value : '80796'
22
24
  }, {
23
- module : TextField,
25
+ module : ZipCodeField,
24
26
  labelText: 'Page 11 Field 2',
25
- name : 'page11field2'
27
+ name : 'page11.field2'
26
28
  }]
27
29
  }
28
30
  }
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='5.4.9'
23
+ * @member {String} version='5.4.10'
24
24
  */
25
- version: '5.4.9'
25
+ version: '5.4.10'
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.9",
3
+ "version": "5.4.10",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -47,19 +47,19 @@
47
47
  "autoprefixer": "^10.4.14",
48
48
  "chalk": "^5.2.0",
49
49
  "clean-webpack-plugin": "^4.0.0",
50
- "commander": "^10.0.0",
50
+ "commander": "^10.0.1",
51
51
  "cssnano": "^6.0.0",
52
52
  "envinfo": "^7.8.1",
53
53
  "fs-extra": "^11.1.1",
54
54
  "highlightjs-line-numbers.js": "^2.8.0",
55
- "inquirer": "^9.1.5",
55
+ "inquirer": "^9.2.0",
56
56
  "neo-jsdoc": "^1.0.1",
57
57
  "neo-jsdoc-x": "^1.0.5",
58
- "postcss": "^8.4.21",
59
- "sass": "^1.61.0",
60
- "webpack": "^5.78.0",
61
- "webpack-cli": "^5.0.1",
62
- "webpack-dev-server": "4.13.2",
58
+ "postcss": "^8.4.23",
59
+ "sass": "^1.62.0",
60
+ "webpack": "^5.80.0",
61
+ "webpack-cli": "^5.0.2",
62
+ "webpack-dev-server": "4.13.3",
63
63
  "webpack-hook-plugin": "^1.0.7",
64
64
  "webpack-node-externals": "^3.0.0"
65
65
  },
@@ -16,7 +16,7 @@
16
16
  {"id": 12, "cardIndex": 8, "isHeader": false, "isValid": null, "name": "HiddenFields"},
17
17
  {"id": 13, "cardIndex": 9, "isHeader": false, "isValid": null, "name": "SelectFields"},
18
18
  {"id": 14, "cardIndex": null, "isHeader": true, "isValid": null, "name": "4. Optional data"},
19
- {"id": 15, "cardIndex": 10, "isHeader": false, "isValid": null, "name": "Page 11"},
19
+ {"id": 15, "cardIndex": 10, "isHeader": false, "isValid": null, "name": "ZipCodeFields"},
20
20
  {"id": 16, "cardIndex": 11, "isHeader": false, "isValid": null, "name": "Page 12"},
21
21
  {"id": 17, "cardIndex": 12, "isHeader": false, "isValid": null, "name": "Page 13"},
22
22
  {"id": 18, "cardIndex": 13, "isHeader": false, "isValid": null, "name": "Page 14"}
@@ -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.9'
240
+ * @default '5.4.10'
241
241
  * @memberOf! module:Neo
242
242
  * @name config.version
243
243
  * @type String
244
244
  */
245
- version: '5.4.9'
245
+ version: '5.4.10'
246
246
  };
247
247
 
248
248
  Object.assign(DefaultConfig, {
@@ -259,11 +259,11 @@ class Base extends CoreBase {
259
259
  */
260
260
  role_: null,
261
261
  /**
262
- * Set this to true for bulk updates.
263
- * Ensure to set it back to false afterwards.
264
- * @member {Boolean} silentVdomUpdate=false
262
+ * Set this to true for bulk updates. Ensure to set it back to false afterwards.
263
+ * Internally the value will get saved as a number to ensure that child methods won't stop the silent mode too early.
264
+ * @member {Boolean} silentVdomUpdate_=false
265
265
  */
266
- silentVdomUpdate: false,
266
+ silentVdomUpdate_: false,
267
267
  /**
268
268
  * Style attributes added to this vdom root. see: getVdomRoot()
269
269
  * @member {Object} style_=null
@@ -982,6 +982,21 @@ class Base extends CoreBase {
982
982
  return value;
983
983
  }
984
984
 
985
+ /**
986
+ * Triggered before the silentVdomUpdate config gets changed.
987
+ * @param {Boolean} value
988
+ * @param {Boolean} oldValue
989
+ * @returns {Number}
990
+ * @protected
991
+ */
992
+ beforeSetSilentVdomUpdate(value, oldValue) {
993
+ if (value === true) {
994
+ return Neo.isNumber(oldValue) ? (oldValue + 1) : 1
995
+ }
996
+
997
+ return (Neo.isNumber(oldValue) && oldValue > 0) ? (oldValue - 1) : 0
998
+ }
999
+
985
1000
  /**
986
1001
  * Changes the value of a vdom object attribute or removes it in case it has no value
987
1002
  * @param {String} key
@@ -0,0 +1,30 @@
1
+ import Text from './Text.mjs';
2
+
3
+ /**
4
+ * An extended form.field.Text which uses an input type 'tel'
5
+ * @class Neo.form.field.Phone
6
+ * @extends Neo.form.field.Text
7
+ */
8
+ class Phone extends Text {
9
+ static config = {
10
+ /**
11
+ * @member {String} className='Neo.form.field.Phone'
12
+ * @protected
13
+ */
14
+ className: 'Neo.form.field.Phone',
15
+ /**
16
+ * @member {String} ntype='phonefield'
17
+ * @protected
18
+ */
19
+ ntype: 'phonefield',
20
+ /**
21
+ * Value for the inputType_ textfield config
22
+ * @member {String} inputType='tel'
23
+ */
24
+ inputType: 'tel'
25
+ }
26
+ }
27
+
28
+ Neo.applyClassConfig(Phone);
29
+
30
+ export default Phone;
@@ -74,12 +74,17 @@ class Text extends Base {
74
74
  */
75
75
  error_: null,
76
76
  /**
77
- * data passes maxLength, minLength & valueLength properties
77
+ * data passes inputPattern, maxLength, minLength & valueLength properties
78
+ * @member {Function} errorTextInputPattern=data=>`Input pattern violation: ${data.inputPattern}`
79
+ */
80
+ errorTextInputPattern: data => `Input pattern violation: ${data.inputPattern}`,
81
+ /**
82
+ * data passes inputPattern, maxLength, minLength & valueLength properties
78
83
  * @member {Function} errorTextMaxLength=data=>`Max length violation: ${valueLength} / ${maxLength}`
79
84
  */
80
85
  errorTextMaxLength: data => `Max length violation: ${data.valueLength} / ${data.maxLength}`,
81
86
  /**
82
- * data passes maxLength, minLength & valueLength properties
87
+ * data passes inputPattern, maxLength, minLength & valueLength properties
83
88
  * @member {Function} errorTextMinLength=data=>`Min length violation: ${data.valueLength} / ${data.minLength}`
84
89
  */
85
90
  errorTextMinLength: data => `Min length violation: ${data.valueLength} / ${data.minLength}`,
@@ -92,7 +97,7 @@ class Text extends Base {
92
97
  */
93
98
  hideLabel_: false,
94
99
  /**
95
- * @member {RegExp|null} inputPattern=null
100
+ * @member {RegExp|null} inputPattern_=null
96
101
  */
97
102
  inputPattern_: null,
98
103
  /**
@@ -330,7 +335,12 @@ class Text extends Base {
330
335
  * @protected
331
336
  */
332
337
  afterSetInputPattern(value, oldValue) {
338
+ if (value) {
339
+ value = value.toString();
340
+ value = value.substring(1, value.length - 1);
341
+ }
333
342
 
343
+ this.changeInputElKey('pattern', value);
334
344
  }
335
345
 
336
346
  /**
@@ -1128,21 +1138,16 @@ class Text extends Base {
1128
1138
  * @protected
1129
1139
  */
1130
1140
  onInputValueChange(data) {
1131
- let me = this,
1132
- value = data.value,
1133
- oldValue = me.value,
1134
- vnode = VNodeUtil.findChildVnode(me.vnode, {nodeName: 'input'});
1141
+ let me = this,
1142
+ value = data.value,
1143
+ vnode = VNodeUtil.findChildVnode(me.vnode, {nodeName: 'input'});
1135
1144
 
1136
1145
  if (vnode) {
1137
1146
  // required for validation -> revert a wrong user input
1138
1147
  vnode.vnode.attributes.value = value;
1139
1148
  }
1140
1149
 
1141
- if (me.inputPattern && !me.inputPattern.test(value) ) {
1142
- me.afterSetValue(oldValue, value);
1143
- } else if (value !== oldValue) {
1144
- me.value = value;
1145
- }
1150
+ me.value = value;
1146
1151
  }
1147
1152
 
1148
1153
  /**
@@ -1259,7 +1264,7 @@ class Text extends Base {
1259
1264
  isValid = !value || value === '';
1260
1265
 
1261
1266
  NeoArray[!isValid ? 'add' : 'remove'](cls, 'neo-invalid');
1262
- me[silent ? '_cls' : 'cls'] = cls;
1267
+ me.cls = cls;
1263
1268
 
1264
1269
  errorNode = VDomUtil.findVdomChild(me.vdom, {cls: 'neo-textfield-error'}).vdom;
1265
1270
 
@@ -1319,16 +1324,17 @@ class Text extends Base {
1319
1324
  * @returns {Boolean} Returns true in case there are no client-side errors
1320
1325
  */
1321
1326
  validate(silent=true) {
1322
- let me = this,
1323
- errorField = silent ? '_error' : 'error',
1324
- maxLength = me.maxLength,
1325
- minLength = me.minLength,
1326
- required = me.required,
1327
- returnValue = true,
1328
- value = me.value,
1329
- valueLength = value?.toString().length,
1330
- isEmpty = value !== 0 && (!value || valueLength < 1),
1331
- errorParam = {maxLength, minLength, valueLength},
1327
+ let me = this,
1328
+ errorField = silent ? '_error' : 'error',
1329
+ maxLength = me.maxLength,
1330
+ minLength = me.minLength,
1331
+ required = me.required,
1332
+ returnValue = true,
1333
+ value = me.value,
1334
+ valueLength = value?.toString().length,
1335
+ inputPattern = me.inputPattern,
1336
+ isEmpty = value !== 0 && (!value || valueLength < 1),
1337
+ errorParam = {inputPattern, maxLength, minLength, valueLength},
1332
1338
  errorText;
1333
1339
 
1334
1340
  if (!silent) {
@@ -1343,7 +1349,9 @@ class Text extends Base {
1343
1349
  me[errorField] = errorText;
1344
1350
  returnValue = false;
1345
1351
  }
1346
- } else if (required && isEmpty) {
1352
+ }
1353
+
1354
+ if (required && isEmpty) {
1347
1355
  me[errorField] = me.errorTextRequired;
1348
1356
  returnValue = false;
1349
1357
  } else if (Neo.isNumber(maxLength) && valueLength > maxLength) {
@@ -1356,6 +1364,11 @@ class Text extends Base {
1356
1364
  me[errorField] = me.errorTextMinLength(errorParam);
1357
1365
  returnValue = false;
1358
1366
  }
1367
+ } else if (inputPattern && !inputPattern.test(value)) {
1368
+ if (required || !isEmpty) {
1369
+ me[errorField] = me.errorTextInputPattern(errorParam);
1370
+ returnValue = false;
1371
+ }
1359
1372
  }
1360
1373
 
1361
1374
  if (returnValue) {
@@ -0,0 +1,26 @@
1
+ import Text from './Text.mjs';
2
+
3
+ /**
4
+ * An extended form.field.Text which uses an input pattern to limit the amount of character which users can enter.
5
+ * The first version will only support numbers. Feel free to open feature requests.
6
+ * @class Neo.form.field.ZipCode
7
+ * @extends Neo.form.field.Text
8
+ */
9
+ class ZipCode extends Text {
10
+ static config = {
11
+ /**
12
+ * @member {String} className='Neo.form.field.ZipCode'
13
+ * @protected
14
+ */
15
+ className: 'Neo.form.field.ZipCode',
16
+ /**
17
+ * @member {String} ntype='zipcodefield'
18
+ * @protected
19
+ */
20
+ ntype: 'zipcodefield'
21
+ }
22
+ }
23
+
24
+ Neo.applyClassConfig(ZipCode);
25
+
26
+ export default ZipCode;