neo.mjs 5.1.17 → 5.2.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.
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='5.1.17'
23
+ * @member {String} version='5.2.1'
24
24
  */
25
- version: '5.1.17'
25
+ version: '5.2.1'
26
26
  }
27
27
 
28
28
  /**
@@ -16,30 +16,59 @@ class ViewportController extends Component {
16
16
  /**
17
17
  * @param {Object} data
18
18
  */
19
- onValidateAllPagesButtonClick(data) {
20
- let me = this,
21
- form = me.getReference('main-form'),
22
- isValid = form.validate();
19
+ async onValidateAllPagesButtonClick(data) {
20
+ let me = this,
21
+ form = me.getReference('main-form'),
22
+ isValid = await form.validate(),
23
+ formValues = await form.getValues();
23
24
 
24
- console.log('Form values', form.getValues());
25
+ console.log('All pages', {isValid, formValues});
26
+
27
+ await me.updateRecordValidityState()
25
28
  }
26
29
 
27
30
  /**
28
31
  * @param {Object} data
29
32
  */
30
- onValidatePageButtonClick(data) {
33
+ async onValidatePageButtonClick(data) {
34
+ let me = this,
35
+ activeIndex = me.getModel().data.activeIndex,
36
+ activeCard = me.getReference('pages-container').items[activeIndex],
37
+ formValues = await activeCard.getValues();
38
+
39
+ await activeCard.validate();
40
+ await me.updateRecordValidityState(activeIndex)
41
+
42
+ console.log(`Current page: ${activeIndex + 1}`, formValues);
43
+ }
44
+
45
+ /**
46
+ * Not passing a pageIndex validates all pages
47
+ * @param {Number|null} [pageIndex]
48
+ * @returns {Promise<void>}
49
+ */
50
+ async updateRecordValidityState(pageIndex=null) {
31
51
  let me = this,
32
52
  model = me.getModel(),
33
- activeIndex = model.data.activeIndex,
34
53
  pagesContainer = me.getReference('pages-container'),
54
+ sideNav = me.getReference('side-nav'),
35
55
  store = model.getStore('sideNav'),
36
- activeCard = pagesContainer.items[activeIndex],
37
- listIndex = me.getReference('side-nav').getActiveIndex(activeIndex),
38
- isValid = activeCard.validate();
56
+ i = 0,
57
+ len = pagesContainer.items.length,
58
+ isValid, listIndex, page;
59
+
60
+ if (Neo.isNumber(pageIndex)) {
61
+ i = pageIndex;
62
+ len = pageIndex + 1;
63
+ }
39
64
 
40
- console.log(`Current page: ${activeIndex + 1}`, activeCard.getValues());
65
+ for (; i < len; i++) {
66
+ page = pagesContainer.items[i];
67
+ listIndex = sideNav.getActiveIndex(i);
68
+ isValid = await page.isValid();
41
69
 
42
- store.getAt(listIndex).isValid = isValid;
70
+ store.getAt(listIndex).isValid = isValid;
71
+ }
43
72
  }
44
73
  }
45
74
 
@@ -18,12 +18,13 @@ class Page3 extends FormPageContainer {
18
18
  items: [{
19
19
  module : TextField,
20
20
  labelText: 'Page 3 Field 1',
21
- name : 'page3field1',
22
- required : true
21
+ name : 'page3.field1',
22
+ required : true,
23
+ value : 'foo'
23
24
  }, {
24
25
  module : TextField,
25
26
  labelText: 'Page 3 Field 2',
26
- name : 'page3field2'
27
+ name : 'page3.field2'
27
28
  }]
28
29
  }
29
30
  }
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='5.1.17'
23
+ * @member {String} version='5.2.1'
24
24
  */
25
- version: '5.1.17'
25
+ version: '5.2.1'
26
26
  }
27
27
 
28
28
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "5.1.17",
3
+ "version": "5.2.1",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -40,6 +40,7 @@
40
40
  .neo-label-wrapper {
41
41
  .neo-center-border, .neo-left-border, .neo-right-border {
42
42
  border-bottom-color: v(textfield-border-color-hovered);
43
+ border-top-color : v(textfield-border-color-hovered);
43
44
  }
44
45
 
45
46
  .neo-left-border, .neo-right-border {
@@ -237,12 +237,12 @@ const DefaultConfig = {
237
237
  useVdomWorker: true,
238
238
  /**
239
239
  * buildScripts/injectPackageVersion.mjs will update this value
240
- * @default '5.1.17'
240
+ * @default '5.2.1'
241
241
  * @memberOf! module:Neo
242
242
  * @name config.version
243
243
  * @type String
244
244
  */
245
- version: '5.1.17'
245
+ version: '5.2.1'
246
246
  };
247
247
 
248
248
  Object.assign(DefaultConfig, {
@@ -31,30 +31,30 @@ class Container extends BaseContainer {
31
31
  }
32
32
 
33
33
  /**
34
+ * @param {Neo.container.Base} parent
35
+ * @param {Object[]} modules
34
36
  * @returns {Object[]}
35
37
  */
36
- findNotLoadedModules(container=this) {
37
- let modules = [];
38
-
39
- container.items.forEach(item => {
40
- if (Neo.typeOf(item.module) === 'Function') {
41
- modules.push(item)
38
+ findNotLoadedModules(parent=this, modules=[]) {
39
+ parent.items.forEach(item => {
40
+ if (Neo.typeOf(item.module) === 'Function' && !item.isLoading) {
41
+ modules.push({item, parent});
42
42
  } else {
43
- item.items && this.findNotLoadedModules(item);
43
+ item.items && this.findNotLoadedModules(item, modules);
44
44
  }
45
45
  });
46
46
 
47
- console.log(modules);
48
-
49
47
  return modules;
50
48
  }
51
49
 
52
50
  /**
53
- * Either pass a field id or name
51
+ * Either pass a field name or id
54
52
  * @param {String} name
55
- * @returns {Neo.form.field.Base|null} fields
53
+ * @returns {Promise<Neo.form.field.Base|null>} fields
56
54
  */
57
- getField(name) {
55
+ async getField(name) {
56
+ await this.loadModules();
57
+
58
58
  let fields = ComponentManager.getChildComponents(this),
59
59
  field;
60
60
 
@@ -70,12 +70,12 @@ class Container extends BaseContainer {
70
70
  }
71
71
 
72
72
  /**
73
- * @returns {Neo.form.field.Base[]} fields
73
+ * @returns {Promise<Neo.form.field.Base[]>} fields
74
74
  */
75
- getFields() {
75
+ async getFields() {
76
76
  let fields = [];
77
77
 
78
- this.findNotLoadedModules();
78
+ await this.loadModules();
79
79
 
80
80
  ComponentManager.getChildComponents(this).forEach(item => {
81
81
  item instanceof BaseField && fields.push(item);
@@ -85,12 +85,13 @@ class Container extends BaseContainer {
85
85
  }
86
86
 
87
87
  /**
88
- * @returns {Object}
88
+ * @returns {Promise<Object>}
89
89
  */
90
- getSubmitValues() {
91
- let values = {};
90
+ async getSubmitValues() {
91
+ let fields = await this.getFields(),
92
+ values = {};
92
93
 
93
- this.getFields().forEach(item => {
94
+ fields.forEach(item => {
94
95
  values[item.name || item.id] = item.getSubmitValue();
95
96
  });
96
97
 
@@ -98,13 +99,23 @@ class Container extends BaseContainer {
98
99
  }
99
100
 
100
101
  /**
101
- * @returns {Object}
102
+ * @returns {Promise<Object>}
102
103
  */
103
- getValues() {
104
- let values = {};
105
-
106
- this.getFields().forEach(item => {
107
- values[item.name || item.id] = item.value;
104
+ async getValues() {
105
+ let fields = await this.getFields(),
106
+ values = {},
107
+ key, ns, nsArray;
108
+
109
+ fields.forEach(item => {
110
+ if (item.name) {
111
+ nsArray = item.name.split('.');
112
+ key = nsArray.pop();
113
+ ns = Neo.ns(nsArray, true, values);
114
+
115
+ ns[key] = item.value;
116
+ } else {
117
+ values[item.id] = item.value;
118
+ }
108
119
  });
109
120
 
110
121
  return values;
@@ -112,10 +123,10 @@ class Container extends BaseContainer {
112
123
 
113
124
  /**
114
125
  * Returns true in case no form field isValid() call returns false
115
- * @returns {Boolean}
126
+ * @returns {Promise<Boolean>}
116
127
  */
117
- isValid() {
118
- let fields = this.getFields(),
128
+ async isValid() {
129
+ let fields = await this.getFields(),
119
130
  i = 0,
120
131
  len = fields.length;
121
132
 
@@ -128,16 +139,35 @@ class Container extends BaseContainer {
128
139
  return true;
129
140
  }
130
141
 
142
+ /**
143
+ * Loads all not loaded items inside card layouts
144
+ * @returns {Promise<Neo.component.Base[]>}
145
+ */
146
+ async loadModules() {
147
+ let me = this,
148
+ modules = me.findNotLoadedModules(),
149
+ promises = [];
150
+
151
+ modules.forEach(module => {
152
+ promises.push(module.parent.layout.loadModule(module.item));
153
+ });
154
+
155
+ modules = await Promise.all(promises);
156
+
157
+ return modules;
158
+ }
159
+
131
160
  /**
132
161
  * Resets field values by field name or field id.
133
162
  * Fields not included with a value will get reset to null.
134
163
  * @param {Object} [values]
135
164
  */
136
- reset(values={}) {
137
- let keys = values ? Object.keys(values) : [],
165
+ async reset(values={}) {
166
+ let keys = values ? Object.keys(values) : [],
167
+ fields = await this.getFields(),
138
168
  index;
139
169
 
140
- this.getFields().forEach(item => {
170
+ fields.forEach(item => {
141
171
  index = keys.indexOf(item.name);
142
172
 
143
173
  if (index < 0) {
@@ -145,18 +175,19 @@ class Container extends BaseContainer {
145
175
  }
146
176
 
147
177
  item.reset(index > -1 ? values[keys[index]] : null);
148
- });
178
+ })
149
179
  }
150
180
 
151
181
  /**
152
182
  * Set field values by field name or field id
153
183
  * @param {Object} values={}
154
184
  */
155
- setValues(values={}) {
156
- let keys = Object.keys(values),
185
+ async setValues(values={}) {
186
+ let keys = Object.keys(values),
187
+ fields = await this.getFields(),
157
188
  index;
158
189
 
159
- this.getFields().forEach(item => {
190
+ fields.forEach(item => {
160
191
  index = keys.indexOf(item.name);
161
192
 
162
193
  if (index < 0) {
@@ -166,19 +197,20 @@ class Container extends BaseContainer {
166
197
  if (index > -1) {
167
198
  item.value = values[keys[index]];
168
199
  }
169
- });
200
+ })
170
201
  }
171
202
 
172
203
  /**
173
204
  * Updates the invalid state for all fields which have validate() implemented.
174
205
  * This can be useful for create-entity forms which show up "clean" until pressing a submit button.
175
- * @returns {Boolean}
206
+ * @returns {Promise<Boolean>}
176
207
  */
177
- validate() {
208
+ async validate() {
178
209
  let isValid = true,
210
+ fields = await this.getFields(),
179
211
  validField;
180
212
 
181
- this.getFields().forEach(item => {
213
+ fields.forEach(item => {
182
214
  validField = item.validate?.(false);
183
215
 
184
216
  if (!validField) {
@@ -175,6 +175,12 @@ class Text extends Base {
175
175
  ]}
176
176
  }
177
177
 
178
+ /**
179
+ * Set this value to false, in case a field should display errors up front.
180
+ * Otherwise, errors will stay hidden on mounting, unless you trigger validate(false).
181
+ * @member {Boolean} clean=true
182
+ */
183
+ clean = true
178
184
  /**
179
185
  * data passes maxLength, minLength & valueLength properties
180
186
  * @member {Function} errorTextMaxLength=data=>`Max length violation: ${valueLength} / ${maxLength}`
@@ -189,11 +195,6 @@ class Text extends Base {
189
195
  * @member {String} errorTextRequired='Required'
190
196
  */
191
197
  errorTextRequired = 'Required'
192
- /**
193
- * Set this value to false, in case a field should display errors up front
194
- * @member {Boolean} validBeforeMount=true
195
- */
196
- validBeforeMount = true
197
198
 
198
199
  /**
199
200
  * @param {Object} config
@@ -1088,11 +1089,13 @@ class Text extends Base {
1088
1089
  onFocusLeave(data) {
1089
1090
  let me = this,
1090
1091
  centerBorderEl = me.getCenterBorderEl(), // labelPosition: 'inline'
1091
- cls = me.cls;
1092
+ cls;
1092
1093
 
1093
1094
  if (!me.readOnly) {
1094
1095
  me.validate(); // silent
1095
1096
 
1097
+ cls = me.cls; // has to get set after validate()
1098
+
1096
1099
  NeoArray.remove(cls, 'neo-focus');
1097
1100
  me.cls = cls;
1098
1101
 
@@ -1202,7 +1205,7 @@ class Text extends Base {
1202
1205
 
1203
1206
  super.reset(value);
1204
1207
 
1205
- if (value === null && me.validBeforeMount) {
1208
+ if (value === null && me.clean) {
1206
1209
  me.updateError(null);
1207
1210
  }
1208
1211
  }
@@ -1234,7 +1237,7 @@ class Text extends Base {
1234
1237
  cls = me.cls,
1235
1238
  errorNode, isValid;
1236
1239
 
1237
- if (!(me.validBeforeMount && !me.mounted)) {
1240
+ if (!(me.clean && !me.mounted)) {
1238
1241
  me._error = value;
1239
1242
 
1240
1243
  isValid = !value || value === '';
@@ -1312,6 +1315,11 @@ class Text extends Base {
1312
1315
  errorParam = {maxLength, minLength, valueLength},
1313
1316
  errorText;
1314
1317
 
1318
+ if (!silent) {
1319
+ // in case we manually call validate(false) on a form or field before it is mounted, we do want to see errors.
1320
+ me.clean = false;
1321
+ }
1322
+
1315
1323
  if (Neo.isFunction(me.validator)) {
1316
1324
  errorText = me.validator(me);
1317
1325
 
@@ -184,6 +184,8 @@ class Card extends Base {
184
184
  index = items.indexOf(item);
185
185
  }
186
186
 
187
+ item.isLoading = true; // prevent the item from getting queued multiple times inside form.Container
188
+
187
189
  module = await module();
188
190
  module = module.default;
189
191
  proto = module.prototype;
@@ -193,6 +195,7 @@ class Card extends Base {
193
195
  item.wrapperCls = [...wrapperCls, sCfg.itemCls];
194
196
  item.module = module;
195
197
 
198
+ delete item.isLoading;
196
199
  delete item.vdom;
197
200
 
198
201
  items[index] = item = Neo.create(item);