@websolutespa/bom-mixer-forms 1.9.1 → 1.9.3
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.
- package/CHANGELOG.md +12 -0
- package/dist/index.d.ts +8 -3
- package/dist/index.js +45 -5
- package/dist/index.mjs +45 -5
- package/package.json +1 -1
- package/src/forms/form-abstract-collection.ts +10 -2
- package/src/forms/form-abstract.ts +20 -2
- package/src/forms/form-emitter.ts +26 -3
- package/src/forms/types.ts +11 -11
- package/src/forms/utils.ts +0 -7
package/CHANGELOG.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ declare class FormAbstractCollection<U extends Record<string, FormValue> | FormV
|
|
|
34
34
|
initControl_(controlOrValue: FormAbstract | FormValue, key: any): FormAbstract;
|
|
35
35
|
protected setInitialOptions(options?: FormOptions): void;
|
|
36
36
|
protected checkAsyncPropState_(key: keyof FormFlags, activator?: FormActivator, root?: FormCollection): Promise<void>;
|
|
37
|
-
revalidate_(): Promise<
|
|
37
|
+
revalidate_(): Promise<boolean>;
|
|
38
38
|
validate_(root?: FormCollection): Promise<void>;
|
|
39
39
|
updateState_(): void;
|
|
40
40
|
reset(): void;
|
|
@@ -63,6 +63,8 @@ declare class FormAbstractCollection<U extends Record<string, FormValue> | FormV
|
|
|
63
63
|
set value(value: U);
|
|
64
64
|
get errors(): ValidationError;
|
|
65
65
|
set errors(errors: ValidationError);
|
|
66
|
+
get emptyErrors(): ValidationError;
|
|
67
|
+
set emptyErrors(emptyErrors: ValidationError);
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
declare class FormArray<T extends FormValue[] = FormValue[]> extends FormAbstractCollection<T, FormArrayControls> {
|
|
@@ -98,7 +100,6 @@ type FormValueGroup = {
|
|
|
98
100
|
};
|
|
99
101
|
type FormValueArray = FormValue[];
|
|
100
102
|
type IControlParam = {
|
|
101
|
-
uid: number;
|
|
102
103
|
control: FormControl;
|
|
103
104
|
};
|
|
104
105
|
type IFormOption = {
|
|
@@ -221,8 +222,11 @@ declare class FormEmitter<T = FormValue> extends EventEmitter {
|
|
|
221
222
|
get pristine(): boolean;
|
|
222
223
|
get untouched(): boolean;
|
|
223
224
|
get unsubmitted(): boolean;
|
|
225
|
+
get required(): boolean;
|
|
224
226
|
protected errors_: ValidationError;
|
|
225
227
|
get errors(): ValidationError;
|
|
228
|
+
protected emptyErrors_: ValidationError;
|
|
229
|
+
get emptyErrors(): ValidationError;
|
|
226
230
|
protected validators_: FormValidator[];
|
|
227
231
|
get validators(): FormValidator[];
|
|
228
232
|
constructor(value: T | null, validators?: (FormValidator | FormValidator[]));
|
|
@@ -245,6 +249,7 @@ declare class FormEmitter<T = FormValue> extends EventEmitter {
|
|
|
245
249
|
set touched(touched: boolean);
|
|
246
250
|
set submitted(submitted: boolean);
|
|
247
251
|
set errors(errors: ValidationError);
|
|
252
|
+
set emptyErrors(emptyErrors: ValidationError);
|
|
248
253
|
set validators(validators: FormValidator[]);
|
|
249
254
|
protected revalidate_(): void;
|
|
250
255
|
protected updateStateAndChange_(): Promise<boolean>;
|
|
@@ -259,7 +264,7 @@ declare class FormAbstract<T = FormValue> extends FormEmitter {
|
|
|
259
264
|
protected setInitialOptions(options?: FormOptions): void;
|
|
260
265
|
protected checkAsyncState_(root?: FormCollection): Promise<void>;
|
|
261
266
|
protected checkAsyncPropState_(key: keyof FormFlags, activator?: FormActivator, root?: FormCollection): Promise<void>;
|
|
262
|
-
protected revalidate_(): Promise<
|
|
267
|
+
protected revalidate_(): Promise<boolean>;
|
|
263
268
|
validateAndChange_(root?: FormCollection): Promise<boolean>;
|
|
264
269
|
validate_(root?: FormCollection): Promise<void>;
|
|
265
270
|
protected updateStateAndChange_(): Promise<boolean>;
|
package/dist/index.js
CHANGED
|
@@ -212,6 +212,7 @@ var FormEmitter = class extends EventEmitter {
|
|
|
212
212
|
this.value_ = validValue(value);
|
|
213
213
|
this.state_ = new FormState();
|
|
214
214
|
this.errors_ = {};
|
|
215
|
+
this.emptyErrors_ = {};
|
|
215
216
|
this.validators_ = validators ? Array.isArray(validators) ? validators : [validators] : [];
|
|
216
217
|
}
|
|
217
218
|
get isDirty() {
|
|
@@ -283,9 +284,15 @@ var FormEmitter = class extends EventEmitter {
|
|
|
283
284
|
get unsubmitted() {
|
|
284
285
|
return this.state_.unsubmitted;
|
|
285
286
|
}
|
|
287
|
+
get required() {
|
|
288
|
+
return Boolean(this.emptyErrors_.required);
|
|
289
|
+
}
|
|
286
290
|
get errors() {
|
|
287
291
|
return this.errors_;
|
|
288
292
|
}
|
|
293
|
+
get emptyErrors() {
|
|
294
|
+
return this.emptyErrors_;
|
|
295
|
+
}
|
|
289
296
|
get validators() {
|
|
290
297
|
return this.validators_;
|
|
291
298
|
}
|
|
@@ -345,21 +352,18 @@ var FormEmitter = class extends EventEmitter {
|
|
|
345
352
|
if (this.state_.disabled !== disabled) {
|
|
346
353
|
this.state_.disabled = disabled;
|
|
347
354
|
this.markAsDirty_ = true;
|
|
348
|
-
this.revalidate_();
|
|
349
355
|
}
|
|
350
356
|
}
|
|
351
357
|
set hidden(hidden) {
|
|
352
358
|
if (this.state_.hidden !== hidden) {
|
|
353
359
|
this.state_.hidden = hidden;
|
|
354
360
|
this.markAsDirty_ = true;
|
|
355
|
-
this.revalidate_();
|
|
356
361
|
}
|
|
357
362
|
}
|
|
358
363
|
set readonly(readonly) {
|
|
359
364
|
if (this.state_.readonly !== readonly) {
|
|
360
365
|
this.state_.readonly = readonly;
|
|
361
366
|
this.markAsDirty_ = true;
|
|
362
|
-
this.revalidate_();
|
|
363
367
|
}
|
|
364
368
|
}
|
|
365
369
|
set dirty(dirty) {
|
|
@@ -396,6 +400,19 @@ var FormEmitter = class extends EventEmitter {
|
|
|
396
400
|
}
|
|
397
401
|
this.errors_ = errors;
|
|
398
402
|
}
|
|
403
|
+
// emptyErrors
|
|
404
|
+
set emptyErrors(emptyErrors) {
|
|
405
|
+
if (!this.markAsDirty_) {
|
|
406
|
+
const previous = Object.entries(this.emptyErrors_);
|
|
407
|
+
const current = Object.entries(emptyErrors);
|
|
408
|
+
const differs = previous.length !== current.length || previous.reduce((p, [k, v], i) => {
|
|
409
|
+
const c = current[i];
|
|
410
|
+
return p || (c[0] !== k || c[1] !== v);
|
|
411
|
+
}, false);
|
|
412
|
+
this.markAsDirty_ = differs;
|
|
413
|
+
}
|
|
414
|
+
this.emptyErrors_ = emptyErrors;
|
|
415
|
+
}
|
|
399
416
|
// validators
|
|
400
417
|
set validators(validators) {
|
|
401
418
|
if (this.validators_ !== validators) {
|
|
@@ -468,6 +485,7 @@ var FormAbstract = class extends FormEmitter {
|
|
|
468
485
|
yield this.checkAsyncPropState_("disabled", options.disabled, root);
|
|
469
486
|
yield this.checkAsyncPropState_("hidden", options.hidden, root);
|
|
470
487
|
yield this.checkAsyncPropState_("readonly", options.readonly, root);
|
|
488
|
+
this.updateStateAndChange_();
|
|
471
489
|
}
|
|
472
490
|
});
|
|
473
491
|
}
|
|
@@ -485,7 +503,7 @@ var FormAbstract = class extends FormEmitter {
|
|
|
485
503
|
if (this.parent) {
|
|
486
504
|
return yield this.parent.revalidate_();
|
|
487
505
|
}
|
|
488
|
-
yield this.validateAndChange_();
|
|
506
|
+
return yield this.validateAndChange_();
|
|
489
507
|
});
|
|
490
508
|
}
|
|
491
509
|
validateAndChange_(root) {
|
|
@@ -498,6 +516,7 @@ var FormAbstract = class extends FormEmitter {
|
|
|
498
516
|
return __async(this, null, function* () {
|
|
499
517
|
yield this.checkAsyncState_(root);
|
|
500
518
|
const errors = {};
|
|
519
|
+
const emptyErrors = {};
|
|
501
520
|
if (this.validators.length === 0 || this.disabled || this.submitted) {
|
|
502
521
|
this.invalid = false;
|
|
503
522
|
} else {
|
|
@@ -518,8 +537,22 @@ var FormAbstract = class extends FormEmitter {
|
|
|
518
537
|
}));
|
|
519
538
|
this.invalid = results.length > 0;
|
|
520
539
|
Object.assign(errors, ...results);
|
|
540
|
+
const emptyValidations = this.validators_.map((x) => x("", root == null ? void 0 : root.value, this, root)).filter((x) => x);
|
|
541
|
+
const { emptyResults, emptyPromises } = emptyValidations.reduce((p, c) => {
|
|
542
|
+
(0, import_bom_core.isPromise)(c) ? p.emptyPromises.push(c) : p.emptyResults.push(c);
|
|
543
|
+
return p;
|
|
544
|
+
}, { emptyResults: [], emptyPromises: [] });
|
|
545
|
+
emptyPromises.forEach((x) => x.then((emptyError) => {
|
|
546
|
+
if (emptyError) {
|
|
547
|
+
this.emptyErrors = Object.assign({}, this.emptyErrors_, emptyError);
|
|
548
|
+
}
|
|
549
|
+
}).catch((emptyError) => {
|
|
550
|
+
console.warn("Validation.async.emptyError", emptyError);
|
|
551
|
+
}));
|
|
552
|
+
Object.assign(emptyErrors, ...emptyResults);
|
|
521
553
|
}
|
|
522
554
|
this.errors = errors;
|
|
555
|
+
this.emptyErrors = emptyErrors;
|
|
523
556
|
this.updateState_();
|
|
524
557
|
});
|
|
525
558
|
}
|
|
@@ -664,7 +697,7 @@ var FormAbstractCollection = class extends FormAbstract {
|
|
|
664
697
|
if (this.parent) {
|
|
665
698
|
return yield this.parent.revalidate_();
|
|
666
699
|
}
|
|
667
|
-
yield this.validateAndChange_(this);
|
|
700
|
+
return yield this.validateAndChange_(this);
|
|
668
701
|
});
|
|
669
702
|
}
|
|
670
703
|
validate_(root) {
|
|
@@ -838,6 +871,13 @@ var FormAbstractCollection = class extends FormAbstract {
|
|
|
838
871
|
}
|
|
839
872
|
set errors(errors) {
|
|
840
873
|
}
|
|
874
|
+
get emptyErrors() {
|
|
875
|
+
return this.reduce_((result, control) => {
|
|
876
|
+
return Object.assign(result, control.emptyErrors);
|
|
877
|
+
}, {});
|
|
878
|
+
}
|
|
879
|
+
set emptyErrors(emptyErrors) {
|
|
880
|
+
}
|
|
841
881
|
};
|
|
842
882
|
|
|
843
883
|
// src/forms/form-array.ts
|
package/dist/index.mjs
CHANGED
|
@@ -162,6 +162,7 @@ var FormEmitter = class extends EventEmitter {
|
|
|
162
162
|
this.value_ = validValue(value);
|
|
163
163
|
this.state_ = new FormState();
|
|
164
164
|
this.errors_ = {};
|
|
165
|
+
this.emptyErrors_ = {};
|
|
165
166
|
this.validators_ = validators ? Array.isArray(validators) ? validators : [validators] : [];
|
|
166
167
|
}
|
|
167
168
|
get isDirty() {
|
|
@@ -233,9 +234,15 @@ var FormEmitter = class extends EventEmitter {
|
|
|
233
234
|
get unsubmitted() {
|
|
234
235
|
return this.state_.unsubmitted;
|
|
235
236
|
}
|
|
237
|
+
get required() {
|
|
238
|
+
return Boolean(this.emptyErrors_.required);
|
|
239
|
+
}
|
|
236
240
|
get errors() {
|
|
237
241
|
return this.errors_;
|
|
238
242
|
}
|
|
243
|
+
get emptyErrors() {
|
|
244
|
+
return this.emptyErrors_;
|
|
245
|
+
}
|
|
239
246
|
get validators() {
|
|
240
247
|
return this.validators_;
|
|
241
248
|
}
|
|
@@ -295,21 +302,18 @@ var FormEmitter = class extends EventEmitter {
|
|
|
295
302
|
if (this.state_.disabled !== disabled) {
|
|
296
303
|
this.state_.disabled = disabled;
|
|
297
304
|
this.markAsDirty_ = true;
|
|
298
|
-
this.revalidate_();
|
|
299
305
|
}
|
|
300
306
|
}
|
|
301
307
|
set hidden(hidden) {
|
|
302
308
|
if (this.state_.hidden !== hidden) {
|
|
303
309
|
this.state_.hidden = hidden;
|
|
304
310
|
this.markAsDirty_ = true;
|
|
305
|
-
this.revalidate_();
|
|
306
311
|
}
|
|
307
312
|
}
|
|
308
313
|
set readonly(readonly) {
|
|
309
314
|
if (this.state_.readonly !== readonly) {
|
|
310
315
|
this.state_.readonly = readonly;
|
|
311
316
|
this.markAsDirty_ = true;
|
|
312
|
-
this.revalidate_();
|
|
313
317
|
}
|
|
314
318
|
}
|
|
315
319
|
set dirty(dirty) {
|
|
@@ -346,6 +350,19 @@ var FormEmitter = class extends EventEmitter {
|
|
|
346
350
|
}
|
|
347
351
|
this.errors_ = errors;
|
|
348
352
|
}
|
|
353
|
+
// emptyErrors
|
|
354
|
+
set emptyErrors(emptyErrors) {
|
|
355
|
+
if (!this.markAsDirty_) {
|
|
356
|
+
const previous = Object.entries(this.emptyErrors_);
|
|
357
|
+
const current = Object.entries(emptyErrors);
|
|
358
|
+
const differs = previous.length !== current.length || previous.reduce((p, [k, v], i) => {
|
|
359
|
+
const c = current[i];
|
|
360
|
+
return p || (c[0] !== k || c[1] !== v);
|
|
361
|
+
}, false);
|
|
362
|
+
this.markAsDirty_ = differs;
|
|
363
|
+
}
|
|
364
|
+
this.emptyErrors_ = emptyErrors;
|
|
365
|
+
}
|
|
349
366
|
// validators
|
|
350
367
|
set validators(validators) {
|
|
351
368
|
if (this.validators_ !== validators) {
|
|
@@ -418,6 +435,7 @@ var FormAbstract = class extends FormEmitter {
|
|
|
418
435
|
yield this.checkAsyncPropState_("disabled", options.disabled, root);
|
|
419
436
|
yield this.checkAsyncPropState_("hidden", options.hidden, root);
|
|
420
437
|
yield this.checkAsyncPropState_("readonly", options.readonly, root);
|
|
438
|
+
this.updateStateAndChange_();
|
|
421
439
|
}
|
|
422
440
|
});
|
|
423
441
|
}
|
|
@@ -435,7 +453,7 @@ var FormAbstract = class extends FormEmitter {
|
|
|
435
453
|
if (this.parent) {
|
|
436
454
|
return yield this.parent.revalidate_();
|
|
437
455
|
}
|
|
438
|
-
yield this.validateAndChange_();
|
|
456
|
+
return yield this.validateAndChange_();
|
|
439
457
|
});
|
|
440
458
|
}
|
|
441
459
|
validateAndChange_(root) {
|
|
@@ -448,6 +466,7 @@ var FormAbstract = class extends FormEmitter {
|
|
|
448
466
|
return __async(this, null, function* () {
|
|
449
467
|
yield this.checkAsyncState_(root);
|
|
450
468
|
const errors = {};
|
|
469
|
+
const emptyErrors = {};
|
|
451
470
|
if (this.validators.length === 0 || this.disabled || this.submitted) {
|
|
452
471
|
this.invalid = false;
|
|
453
472
|
} else {
|
|
@@ -468,8 +487,22 @@ var FormAbstract = class extends FormEmitter {
|
|
|
468
487
|
}));
|
|
469
488
|
this.invalid = results.length > 0;
|
|
470
489
|
Object.assign(errors, ...results);
|
|
490
|
+
const emptyValidations = this.validators_.map((x) => x("", root == null ? void 0 : root.value, this, root)).filter((x) => x);
|
|
491
|
+
const { emptyResults, emptyPromises } = emptyValidations.reduce((p, c) => {
|
|
492
|
+
isPromise(c) ? p.emptyPromises.push(c) : p.emptyResults.push(c);
|
|
493
|
+
return p;
|
|
494
|
+
}, { emptyResults: [], emptyPromises: [] });
|
|
495
|
+
emptyPromises.forEach((x) => x.then((emptyError) => {
|
|
496
|
+
if (emptyError) {
|
|
497
|
+
this.emptyErrors = Object.assign({}, this.emptyErrors_, emptyError);
|
|
498
|
+
}
|
|
499
|
+
}).catch((emptyError) => {
|
|
500
|
+
console.warn("Validation.async.emptyError", emptyError);
|
|
501
|
+
}));
|
|
502
|
+
Object.assign(emptyErrors, ...emptyResults);
|
|
471
503
|
}
|
|
472
504
|
this.errors = errors;
|
|
505
|
+
this.emptyErrors = emptyErrors;
|
|
473
506
|
this.updateState_();
|
|
474
507
|
});
|
|
475
508
|
}
|
|
@@ -614,7 +647,7 @@ var FormAbstractCollection = class extends FormAbstract {
|
|
|
614
647
|
if (this.parent) {
|
|
615
648
|
return yield this.parent.revalidate_();
|
|
616
649
|
}
|
|
617
|
-
yield this.validateAndChange_(this);
|
|
650
|
+
return yield this.validateAndChange_(this);
|
|
618
651
|
});
|
|
619
652
|
}
|
|
620
653
|
validate_(root) {
|
|
@@ -788,6 +821,13 @@ var FormAbstractCollection = class extends FormAbstract {
|
|
|
788
821
|
}
|
|
789
822
|
set errors(errors) {
|
|
790
823
|
}
|
|
824
|
+
get emptyErrors() {
|
|
825
|
+
return this.reduce_((result, control) => {
|
|
826
|
+
return Object.assign(result, control.emptyErrors);
|
|
827
|
+
}, {});
|
|
828
|
+
}
|
|
829
|
+
set emptyErrors(emptyErrors) {
|
|
830
|
+
}
|
|
791
831
|
};
|
|
792
832
|
|
|
793
833
|
// src/forms/form-array.ts
|
package/package.json
CHANGED
|
@@ -91,12 +91,12 @@ export class FormAbstractCollection<
|
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
async revalidate_(): Promise<
|
|
94
|
+
async revalidate_(): Promise<boolean> {
|
|
95
95
|
if (this.parent) {
|
|
96
96
|
return await this.parent.revalidate_();
|
|
97
97
|
}
|
|
98
98
|
// console.log('FormAbstractCollection.revalidate_', this.name);
|
|
99
|
-
await this.validateAndChange_(this);
|
|
99
|
+
return await this.validateAndChange_(this);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
async validate_(root?: FormCollection) {
|
|
@@ -305,4 +305,12 @@ export class FormAbstractCollection<
|
|
|
305
305
|
}
|
|
306
306
|
|
|
307
307
|
set errors(errors) { }
|
|
308
|
+
|
|
309
|
+
get emptyErrors(): ValidationError {
|
|
310
|
+
return this.reduce_((result: ValidationError, control: FormAbstract) => {
|
|
311
|
+
return Object.assign(result, control.emptyErrors);
|
|
312
|
+
}, {});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
set emptyErrors(emptyErrors) { }
|
|
308
316
|
}
|
|
@@ -58,11 +58,13 @@ export class FormAbstract<T = FormValue> extends FormEmitter {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
protected async checkAsyncState_(root?: FormCollection): Promise<void> {
|
|
61
|
+
// console.log('FormAbstract.checkAsyncState_', this.name);
|
|
61
62
|
const options = this.initialOptions_;
|
|
62
63
|
if (options) {
|
|
63
64
|
await this.checkAsyncPropState_('disabled', options.disabled, root);
|
|
64
65
|
await this.checkAsyncPropState_('hidden', options.hidden, root);
|
|
65
66
|
await this.checkAsyncPropState_('readonly', options.readonly, root);
|
|
67
|
+
this.updateStateAndChange_();
|
|
66
68
|
}
|
|
67
69
|
}
|
|
68
70
|
|
|
@@ -79,7 +81,7 @@ export class FormAbstract<T = FormValue> extends FormEmitter {
|
|
|
79
81
|
return await this.parent.revalidate_();
|
|
80
82
|
}
|
|
81
83
|
// console.log('FormAbstract.revalidate_', this.name);
|
|
82
|
-
await this.validateAndChange_();
|
|
84
|
+
return await this.validateAndChange_();
|
|
83
85
|
}
|
|
84
86
|
|
|
85
87
|
async validateAndChange_(root?: FormCollection): Promise<boolean> {
|
|
@@ -92,6 +94,7 @@ export class FormAbstract<T = FormValue> extends FormEmitter {
|
|
|
92
94
|
// console.log('FormAbstract.validate_', this.name);
|
|
93
95
|
await this.checkAsyncState_(root);
|
|
94
96
|
const errors: ValidationError = {};
|
|
97
|
+
const emptyErrors: ValidationError = {};
|
|
95
98
|
if (this.validators.length === 0 || this.disabled || this.submitted) {
|
|
96
99
|
this.invalid = false;
|
|
97
100
|
} else {
|
|
@@ -114,9 +117,24 @@ export class FormAbstract<T = FormValue> extends FormEmitter {
|
|
|
114
117
|
this.invalid = results.length > 0;
|
|
115
118
|
Object.assign(errors, ...results);
|
|
116
119
|
// console.log(`${this.name}.value`, '=', this.value_, '{', ...Object.keys(errors), '}');
|
|
117
|
-
//
|
|
120
|
+
// emptyErrors
|
|
121
|
+
const emptyValidations = this.validators_.map((x) => x('', root?.value, this, root)).filter((x) => x);
|
|
122
|
+
const { emptyResults, emptyPromises } = emptyValidations.reduce((p: { emptyResults: (ValidationError | null)[], emptyPromises: Promise<ValidationError | null>[] }, c: (ValidationError | null) | Promise<ValidationError | null>) => {
|
|
123
|
+
isPromise(c) ? p.emptyPromises.push(c as Promise<ValidationError | null>) : p.emptyResults.push(c);
|
|
124
|
+
return p;
|
|
125
|
+
}, { emptyResults: [], emptyPromises: [] });
|
|
126
|
+
emptyPromises.forEach(x => x.then((emptyError: ValidationError | null) => {
|
|
127
|
+
// console.log('Validation.async.error', emptyError);
|
|
128
|
+
if (emptyError) {
|
|
129
|
+
this.emptyErrors = Object.assign({}, this.emptyErrors_, emptyError);
|
|
130
|
+
}
|
|
131
|
+
}).catch(emptyError => {
|
|
132
|
+
console.warn('Validation.async.emptyError', emptyError);
|
|
133
|
+
}));
|
|
134
|
+
Object.assign(emptyErrors, ...emptyResults);
|
|
118
135
|
}
|
|
119
136
|
this.errors = errors;
|
|
137
|
+
this.emptyErrors = emptyErrors;
|
|
120
138
|
this.updateState_();
|
|
121
139
|
}
|
|
122
140
|
|
|
@@ -59,6 +59,7 @@ export class FormEmitter<T = FormValue> extends EventEmitter {
|
|
|
59
59
|
get pristine() { return this.state_.pristine; }
|
|
60
60
|
get untouched() { return this.state_.untouched; }
|
|
61
61
|
get unsubmitted() { return this.state_.unsubmitted; }
|
|
62
|
+
get required() { return Boolean(this.emptyErrors_.required); }
|
|
62
63
|
|
|
63
64
|
// errors
|
|
64
65
|
protected errors_: ValidationError;
|
|
@@ -66,6 +67,12 @@ export class FormEmitter<T = FormValue> extends EventEmitter {
|
|
|
66
67
|
return this.errors_;
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
// emptyErrors
|
|
71
|
+
protected emptyErrors_: ValidationError;
|
|
72
|
+
get emptyErrors() {
|
|
73
|
+
return this.emptyErrors_;
|
|
74
|
+
}
|
|
75
|
+
|
|
69
76
|
// validators
|
|
70
77
|
protected validators_: FormValidator[];
|
|
71
78
|
get validators() {
|
|
@@ -78,6 +85,7 @@ export class FormEmitter<T = FormValue> extends EventEmitter {
|
|
|
78
85
|
this.value_ = validValue(value);
|
|
79
86
|
this.state_ = new FormState();
|
|
80
87
|
this.errors_ = {};
|
|
88
|
+
this.emptyErrors_ = {};
|
|
81
89
|
this.validators_ = validators ? (Array.isArray(validators) ? validators : [validators]) : [];
|
|
82
90
|
}
|
|
83
91
|
|
|
@@ -142,21 +150,21 @@ export class FormEmitter<T = FormValue> extends EventEmitter {
|
|
|
142
150
|
if (this.state_.disabled !== disabled) {
|
|
143
151
|
this.state_.disabled = disabled;
|
|
144
152
|
this.markAsDirty_ = true;
|
|
145
|
-
this.revalidate_();
|
|
153
|
+
// this.revalidate_();
|
|
146
154
|
}
|
|
147
155
|
}
|
|
148
156
|
set hidden(hidden: boolean) {
|
|
149
157
|
if (this.state_.hidden !== hidden) {
|
|
150
158
|
this.state_.hidden = hidden;
|
|
151
159
|
this.markAsDirty_ = true;
|
|
152
|
-
this.revalidate_();
|
|
160
|
+
// this.revalidate_();
|
|
153
161
|
}
|
|
154
162
|
}
|
|
155
163
|
set readonly(readonly: boolean) {
|
|
156
164
|
if (this.state_.readonly !== readonly) {
|
|
157
165
|
this.state_.readonly = readonly;
|
|
158
166
|
this.markAsDirty_ = true;
|
|
159
|
-
this.revalidate_();
|
|
167
|
+
// this.revalidate_();
|
|
160
168
|
}
|
|
161
169
|
}
|
|
162
170
|
set dirty(dirty: boolean) {
|
|
@@ -197,6 +205,21 @@ export class FormEmitter<T = FormValue> extends EventEmitter {
|
|
|
197
205
|
this.errors_ = errors;
|
|
198
206
|
}
|
|
199
207
|
|
|
208
|
+
// emptyErrors
|
|
209
|
+
set emptyErrors(emptyErrors: ValidationError) {
|
|
210
|
+
if (!this.markAsDirty_) {
|
|
211
|
+
const previous = Object.entries(this.emptyErrors_);
|
|
212
|
+
const current = Object.entries(emptyErrors);
|
|
213
|
+
const differs = previous.length !== current.length ||
|
|
214
|
+
previous.reduce((p, [k, v], i) => {
|
|
215
|
+
const c = current[i];
|
|
216
|
+
return p || (c[0] !== k || c[1] !== v);
|
|
217
|
+
}, false);
|
|
218
|
+
this.markAsDirty_ = differs;
|
|
219
|
+
}
|
|
220
|
+
this.emptyErrors_ = emptyErrors;
|
|
221
|
+
}
|
|
222
|
+
|
|
200
223
|
// validators
|
|
201
224
|
set validators(validators) {
|
|
202
225
|
if (this.validators_ !== validators) {
|
package/src/forms/types.ts
CHANGED
|
@@ -11,20 +11,20 @@ export type FormValueGroup = { [key: string]: FormValue };
|
|
|
11
11
|
|
|
12
12
|
export type FormValueArray = FormValue[];
|
|
13
13
|
|
|
14
|
-
export type IControlParam = {
|
|
14
|
+
export type IControlParam = { control: FormControl };
|
|
15
15
|
|
|
16
16
|
export type IFormOption = { id: IEquatable, name: string };
|
|
17
17
|
|
|
18
18
|
export type FormOptions = {
|
|
19
19
|
schema?: ControlType;
|
|
20
|
-
name?: string
|
|
21
|
-
label?: string
|
|
20
|
+
name?: string;
|
|
21
|
+
label?: string;
|
|
22
22
|
value?: FormValue;
|
|
23
|
-
placeholder?: string
|
|
24
|
-
required?: FormActivator
|
|
25
|
-
hidden?: FormActivator
|
|
26
|
-
disabled?: FormActivator
|
|
27
|
-
readonly?: FormActivator
|
|
23
|
+
placeholder?: string;
|
|
24
|
+
required?: FormActivator;
|
|
25
|
+
hidden?: FormActivator;
|
|
26
|
+
disabled?: FormActivator;
|
|
27
|
+
readonly?: FormActivator;
|
|
28
28
|
options?: IOption[];
|
|
29
29
|
optionsExtra?: { asEquatable: boolean };
|
|
30
30
|
customData?: Record<string, any>;
|
|
@@ -81,9 +81,9 @@ export type IFormBuilderControlSchema = {
|
|
|
81
81
|
value?: FormValue;
|
|
82
82
|
placeholder?: string;
|
|
83
83
|
required?: FormActivator;
|
|
84
|
-
hidden?: FormActivator
|
|
85
|
-
disabled?: FormActivator
|
|
86
|
-
readonly?: FormActivator
|
|
84
|
+
hidden?: FormActivator;
|
|
85
|
+
disabled?: FormActivator;
|
|
86
|
+
readonly?: FormActivator;
|
|
87
87
|
options?: IOption[];
|
|
88
88
|
optionsExtra?: { asEquatable: boolean };
|
|
89
89
|
validators?: FormValidator | FormValidator[];
|
package/src/forms/utils.ts
CHANGED
|
@@ -21,13 +21,6 @@ export function mapState_(state: FormState): FormFlags & FormDerivedFlags {
|
|
|
21
21
|
untouched: !state.touched,
|
|
22
22
|
unsubmitted: !state.submitted,
|
|
23
23
|
};
|
|
24
|
-
/*
|
|
25
|
-
return Object.fromEntries(
|
|
26
|
-
Object.entries(
|
|
27
|
-
Object.getOwnPropertyDescriptors(state)
|
|
28
|
-
).map(([k, v]) => [k, v.value])
|
|
29
|
-
) as FormFlags & FormDerivedFlags;
|
|
30
|
-
*/
|
|
31
24
|
}
|
|
32
25
|
|
|
33
26
|
export function valueToString(value: IOption | IOption[] | IEquatable | IEquatable[] | null): string | string[] | undefined {
|