adaptform 2.0.4 → 2.0.5
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 +51 -0
- package/LICENSE.md +2 -2
- package/README.md +420 -1
- package/dist/{Form-DOdrOtbT.d.cts → Form-Be3I6LX0.d.cts} +83 -3
- package/dist/{Form-DOdrOtbT.d.ts → Form-Be3I6LX0.d.ts} +83 -3
- package/dist/index.cjs +341 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +341 -20
- package/dist/index.mjs.map +1 -1
- package/dist/luxon.cjs.map +1 -1
- package/dist/luxon.d.cts +1 -1
- package/dist/luxon.d.ts +1 -1
- package/dist/luxon.mjs.map +1 -1
- package/package.json +15 -5
package/dist/index.mjs
CHANGED
|
@@ -6,7 +6,7 @@ var Field = class {
|
|
|
6
6
|
this._errors = [];
|
|
7
7
|
this.isValid = null;
|
|
8
8
|
this.isTouched = false;
|
|
9
|
-
this.
|
|
9
|
+
this.fieldType = new TypeConstructor(options ?? {});
|
|
10
10
|
this.defaultValue = defaultValue ?? null;
|
|
11
11
|
for (const plugin of this.options.plugins ?? []) {
|
|
12
12
|
plugin.init?.(this);
|
|
@@ -26,11 +26,11 @@ var Field = class {
|
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
get options() {
|
|
29
|
-
return this.
|
|
29
|
+
return this.fieldType.options;
|
|
30
30
|
}
|
|
31
31
|
set options(options) {
|
|
32
|
-
let cur_options = this.
|
|
33
|
-
this.
|
|
32
|
+
let cur_options = this.fieldType.options;
|
|
33
|
+
this.fieldType.options = Object.assign(cur_options, options);
|
|
34
34
|
}
|
|
35
35
|
get rawValue() {
|
|
36
36
|
return this._rawValue;
|
|
@@ -49,7 +49,7 @@ var Field = class {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
this._rawValue = rawValue;
|
|
52
|
-
this._valueClear = this.
|
|
52
|
+
this._valueClear = this.fieldType.cast(valueClear);
|
|
53
53
|
this._errors = [];
|
|
54
54
|
this.isTouched = true;
|
|
55
55
|
this.checkAndSetValid();
|
|
@@ -92,11 +92,11 @@ var Field = class {
|
|
|
92
92
|
}
|
|
93
93
|
if (this._valueClear === null) {
|
|
94
94
|
this._errors.push(
|
|
95
|
-
this.options.messages?.type ?? `\u041E\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044F ${this.
|
|
95
|
+
this.options.messages?.type ?? `\u041E\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044F ${this.fieldType.getTypeName()}`
|
|
96
96
|
);
|
|
97
97
|
return false;
|
|
98
98
|
}
|
|
99
|
-
const typeErrors = this.
|
|
99
|
+
const typeErrors = this.fieldType.validate(this._valueClear, form);
|
|
100
100
|
if (typeErrors.length > 0) {
|
|
101
101
|
this._errors.push(...typeErrors);
|
|
102
102
|
return false;
|
|
@@ -129,7 +129,6 @@ var Field = class {
|
|
|
129
129
|
reset() {
|
|
130
130
|
if (this.defaultValue !== null && this.defaultValue !== void 0) {
|
|
131
131
|
this.rawValue = this.defaultValue;
|
|
132
|
-
this.isValid = true;
|
|
133
132
|
} else {
|
|
134
133
|
this._rawValue = null;
|
|
135
134
|
this._valueClear = null;
|
|
@@ -153,6 +152,7 @@ var ArrayField = class {
|
|
|
153
152
|
...options
|
|
154
153
|
};
|
|
155
154
|
this._items = initial.map((v) => this.factory(v));
|
|
155
|
+
this.checkValid();
|
|
156
156
|
}
|
|
157
157
|
// ===== value =====
|
|
158
158
|
set itemsValue(items) {
|
|
@@ -220,7 +220,8 @@ var ArrayField = class {
|
|
|
220
220
|
if (!ok) valid = false;
|
|
221
221
|
}
|
|
222
222
|
if (this.options.validate) {
|
|
223
|
-
const
|
|
223
|
+
const values = this._items.map((i) => i.valueClear);
|
|
224
|
+
const result = this.options.validate(values, form);
|
|
224
225
|
if (result === false) {
|
|
225
226
|
this._errors.push(
|
|
226
227
|
this.options.messages?.validate ?? "\u041E\u0448\u0438\u0431\u043A\u0430 \u0432\u0430\u043B\u0438\u0434\u0430\u0446\u0438\u0438"
|
|
@@ -238,7 +239,8 @@ var ArrayField = class {
|
|
|
238
239
|
return this.checkValid(form);
|
|
239
240
|
}
|
|
240
241
|
get isValid() {
|
|
241
|
-
|
|
242
|
+
if (this._errors.length > 0) return false;
|
|
243
|
+
return this._items.every((i) => i.isValid === true);
|
|
242
244
|
}
|
|
243
245
|
get error() {
|
|
244
246
|
return this._errors[0] ?? "";
|
|
@@ -273,6 +275,7 @@ var ArrayFormField = class {
|
|
|
273
275
|
form.fields = data;
|
|
274
276
|
return form;
|
|
275
277
|
});
|
|
278
|
+
this.checkValid();
|
|
276
279
|
}
|
|
277
280
|
// ===== value =====
|
|
278
281
|
set forms(forms) {
|
|
@@ -364,7 +367,8 @@ var ArrayFormField = class {
|
|
|
364
367
|
return this.checkValid(form);
|
|
365
368
|
}
|
|
366
369
|
get isValid() {
|
|
367
|
-
|
|
370
|
+
if (this._errors.length > 0) return false;
|
|
371
|
+
return this._forms.every((i) => i.checkValid() === true);
|
|
368
372
|
}
|
|
369
373
|
get errors() {
|
|
370
374
|
return this._errors;
|
|
@@ -381,10 +385,255 @@ var ArrayFormField = class {
|
|
|
381
385
|
}
|
|
382
386
|
};
|
|
383
387
|
|
|
388
|
+
// src/core/ErrorsShema.ts
|
|
389
|
+
var ErrorsSchema = class _ErrorsSchema {
|
|
390
|
+
constructor() {
|
|
391
|
+
this._staticRules = /* @__PURE__ */ new Map();
|
|
392
|
+
this._dynamicRules = [];
|
|
393
|
+
this._valueTransformers = [];
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Добавляет статическое правило - точное соответствие ключа ошибки
|
|
397
|
+
* @param errorKey - точный ключ ошибки из ответа сервера
|
|
398
|
+
* @param fieldName - имя поля в форме или функция для динамического определения
|
|
399
|
+
*/
|
|
400
|
+
staticKey(errorKey, fieldName) {
|
|
401
|
+
this._staticRules.set(errorKey, fieldName);
|
|
402
|
+
return this;
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Добавляет динамическое правило с регулярным выражением
|
|
406
|
+
* @param pattern - регулярное выражение для сопоставления ключа ошибки
|
|
407
|
+
* @param mapping - имя поля или функция для извлечения имени поля из совпадения
|
|
408
|
+
* @param options - дополнительные опции (приоритет и т.д.)
|
|
409
|
+
*/
|
|
410
|
+
dynamicKey(pattern, mapping, options) {
|
|
411
|
+
this._dynamicRules.push({
|
|
412
|
+
pattern,
|
|
413
|
+
mapping,
|
|
414
|
+
priority: options?.priority ?? 0
|
|
415
|
+
});
|
|
416
|
+
this._dynamicRules.sort((a, b) => b.priority - a.priority);
|
|
417
|
+
return this;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Устанавливает обработчик для ошибок, которые не подошли ни под одно правило
|
|
421
|
+
*/
|
|
422
|
+
fallback(handler) {
|
|
423
|
+
this._fallbackHandler = handler;
|
|
424
|
+
return this;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Добавляет трансформер для значений ошибок
|
|
428
|
+
* Полезно для нормализации сообщений (например, если сервер возвращает массив ошибок)
|
|
429
|
+
*/
|
|
430
|
+
transformValue(transformer) {
|
|
431
|
+
this._valueTransformers.push(transformer);
|
|
432
|
+
return this;
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Быстрый метод для создания схемы из простого объекта маппинга
|
|
436
|
+
*/
|
|
437
|
+
static fromObject(mapping) {
|
|
438
|
+
const schema = new _ErrorsSchema();
|
|
439
|
+
for (const [errorKey, fieldName] of Object.entries(mapping)) {
|
|
440
|
+
schema.staticKey(errorKey, fieldName);
|
|
441
|
+
}
|
|
442
|
+
return schema;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Создает схему для массива однотипных форм
|
|
446
|
+
*/
|
|
447
|
+
static forArray(itemSchema, arrayFieldName, indexExtractor) {
|
|
448
|
+
const schema = new _ErrorsSchema();
|
|
449
|
+
schema.dynamicKey(
|
|
450
|
+
new RegExp(`^${arrayFieldName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\[(\\d+)\\]\\.(.+)$`),
|
|
451
|
+
(match) => {
|
|
452
|
+
const index = match[1];
|
|
453
|
+
const fieldName = match[2];
|
|
454
|
+
return `${arrayFieldName}.${index}.${fieldName}`;
|
|
455
|
+
},
|
|
456
|
+
{ priority: 100 }
|
|
457
|
+
);
|
|
458
|
+
return schema;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Основной метод парсинга ошибок с поддержкой трансформеров
|
|
462
|
+
* Поддерживает вложенные структуры через точечную нотацию
|
|
463
|
+
*/
|
|
464
|
+
parseErrors(errors, prefix = "") {
|
|
465
|
+
const result = {};
|
|
466
|
+
for (const [key, value] of Object.entries(errors)) {
|
|
467
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
468
|
+
if (this.isNestedObject(value)) {
|
|
469
|
+
const nestedErrors = this.parseErrors(value, fullKey);
|
|
470
|
+
Object.assign(result, nestedErrors);
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
if (value === null || value === void 0) {
|
|
474
|
+
continue;
|
|
475
|
+
}
|
|
476
|
+
let transformedValue = value;
|
|
477
|
+
for (const transformer of this._valueTransformers) {
|
|
478
|
+
transformedValue = transformer(transformedValue);
|
|
479
|
+
}
|
|
480
|
+
const mapping = this.findMapping(fullKey, transformedValue);
|
|
481
|
+
if (mapping) {
|
|
482
|
+
if (typeof mapping === "function") {
|
|
483
|
+
const fieldName = mapping(transformedValue);
|
|
484
|
+
if (fieldName) {
|
|
485
|
+
result[fieldName] = typeof transformedValue === "string" ? transformedValue : JSON.stringify(transformedValue);
|
|
486
|
+
}
|
|
487
|
+
} else {
|
|
488
|
+
result[mapping] = typeof transformedValue === "string" ? transformedValue : JSON.stringify(transformedValue);
|
|
489
|
+
}
|
|
490
|
+
} else if (this._fallbackHandler) {
|
|
491
|
+
const fieldName = this._fallbackHandler(fullKey, transformedValue);
|
|
492
|
+
if (fieldName) {
|
|
493
|
+
result[fieldName] = typeof transformedValue === "string" ? transformedValue : JSON.stringify(transformedValue);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
return result;
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Парсит ошибки сервера и возвращает расширенную информацию
|
|
501
|
+
*/
|
|
502
|
+
parseErrorsDetailed(errors, prefix = "") {
|
|
503
|
+
const result = {};
|
|
504
|
+
for (const [key, value] of Object.entries(errors)) {
|
|
505
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
506
|
+
if (this.isNestedObject(value)) {
|
|
507
|
+
const nestedErrors = this.parseErrorsDetailed(value, fullKey);
|
|
508
|
+
Object.assign(result, nestedErrors);
|
|
509
|
+
continue;
|
|
510
|
+
}
|
|
511
|
+
if (value === null || value === void 0) {
|
|
512
|
+
continue;
|
|
513
|
+
}
|
|
514
|
+
let transformedValue = value;
|
|
515
|
+
for (const transformer of this._valueTransformers) {
|
|
516
|
+
transformedValue = transformer(transformedValue);
|
|
517
|
+
}
|
|
518
|
+
const matchResult = this.findMappingDetailed(fullKey, transformedValue);
|
|
519
|
+
if (matchResult) {
|
|
520
|
+
const message = typeof transformedValue === "string" ? transformedValue : JSON.stringify(transformedValue);
|
|
521
|
+
result[matchResult.fieldName] = {
|
|
522
|
+
fieldName: matchResult.fieldName,
|
|
523
|
+
message,
|
|
524
|
+
sourceKey: fullKey,
|
|
525
|
+
matchedBy: matchResult.matchedBy
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
return result;
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Создает схему для вложенной формы
|
|
533
|
+
*/
|
|
534
|
+
nest(prefix) {
|
|
535
|
+
const nestedSchema = new _ErrorsSchema();
|
|
536
|
+
for (const [key, mapping] of this._staticRules.entries()) {
|
|
537
|
+
nestedSchema.staticKey(`${prefix}.${key}`, mapping);
|
|
538
|
+
}
|
|
539
|
+
for (const rule of this._dynamicRules) {
|
|
540
|
+
const newPattern = new RegExp(`^${prefix}\\.${rule.pattern.source.replace(/^\^/, "")}`);
|
|
541
|
+
nestedSchema.dynamicKey(newPattern, rule.mapping, { priority: rule.priority });
|
|
542
|
+
}
|
|
543
|
+
for (const transformer of this._valueTransformers) {
|
|
544
|
+
nestedSchema.transformValue(transformer);
|
|
545
|
+
}
|
|
546
|
+
if (this._fallbackHandler) {
|
|
547
|
+
nestedSchema.fallback((key, value) => {
|
|
548
|
+
if (key.startsWith(`${prefix}.`)) {
|
|
549
|
+
return this._fallbackHandler(key.slice(prefix.length + 1), value);
|
|
550
|
+
}
|
|
551
|
+
return null;
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
return nestedSchema;
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Клонирует текущую схему
|
|
558
|
+
*/
|
|
559
|
+
clone() {
|
|
560
|
+
const cloned = new _ErrorsSchema();
|
|
561
|
+
for (const [key, mapping] of this._staticRules.entries()) {
|
|
562
|
+
cloned._staticRules.set(key, mapping);
|
|
563
|
+
}
|
|
564
|
+
for (const rule of this._dynamicRules) {
|
|
565
|
+
cloned._dynamicRules.push({ ...rule });
|
|
566
|
+
}
|
|
567
|
+
cloned._fallbackHandler = this._fallbackHandler;
|
|
568
|
+
cloned._valueTransformers = [...this._valueTransformers];
|
|
569
|
+
return cloned;
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Объединяет текущую схему с другой
|
|
573
|
+
*/
|
|
574
|
+
merge(other) {
|
|
575
|
+
const merged = this.clone();
|
|
576
|
+
for (const [key, mapping] of other._staticRules.entries()) {
|
|
577
|
+
merged._staticRules.set(key, mapping);
|
|
578
|
+
}
|
|
579
|
+
merged._dynamicRules.push(...other._dynamicRules);
|
|
580
|
+
merged._dynamicRules.sort((a, b) => b.priority - a.priority);
|
|
581
|
+
merged._valueTransformers.push(...other._valueTransformers);
|
|
582
|
+
if (other._fallbackHandler) {
|
|
583
|
+
merged._fallbackHandler = other._fallbackHandler;
|
|
584
|
+
}
|
|
585
|
+
return merged;
|
|
586
|
+
}
|
|
587
|
+
isNestedObject(value) {
|
|
588
|
+
return value && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
|
|
589
|
+
}
|
|
590
|
+
findMappingDetailed(key, value) {
|
|
591
|
+
if (this._staticRules.has(key)) {
|
|
592
|
+
const mapping = this._staticRules.get(key);
|
|
593
|
+
const fieldName = typeof mapping === "function" ? mapping(value) : mapping;
|
|
594
|
+
return fieldName ? { fieldName, matchedBy: "static" } : null;
|
|
595
|
+
}
|
|
596
|
+
for (const rule of this._dynamicRules) {
|
|
597
|
+
const match = key.match(rule.pattern);
|
|
598
|
+
if (match) {
|
|
599
|
+
const fieldName = typeof rule.mapping === "function" ? rule.mapping(match) : rule.mapping;
|
|
600
|
+
return fieldName ? { fieldName, matchedBy: "dynamic" } : null;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
if (this._fallbackHandler) {
|
|
604
|
+
const fieldName = this._fallbackHandler(key, value);
|
|
605
|
+
return fieldName ? { fieldName, matchedBy: "fallback" } : null;
|
|
606
|
+
}
|
|
607
|
+
return null;
|
|
608
|
+
}
|
|
609
|
+
findMapping(key, value) {
|
|
610
|
+
if (this._staticRules.has(key)) {
|
|
611
|
+
return this._staticRules.get(key);
|
|
612
|
+
}
|
|
613
|
+
for (const rule of this._dynamicRules) {
|
|
614
|
+
const match = key.match(rule.pattern);
|
|
615
|
+
if (match) {
|
|
616
|
+
if (typeof rule.mapping === "function") {
|
|
617
|
+
const fieldName = rule.mapping(match);
|
|
618
|
+
return fieldName;
|
|
619
|
+
}
|
|
620
|
+
return rule.mapping;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
if (this._fallbackHandler) {
|
|
624
|
+
const fieldName = this._fallbackHandler(key, value);
|
|
625
|
+
return fieldName;
|
|
626
|
+
}
|
|
627
|
+
return null;
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
var DefaultErrorsSchema = new ErrorsSchema().fallback((key) => key);
|
|
631
|
+
|
|
384
632
|
// src/core/Form.ts
|
|
385
633
|
var Form = class {
|
|
386
634
|
constructor() {
|
|
387
635
|
this._globalErrors = {};
|
|
636
|
+
this.errorsShema = DefaultErrorsSchema;
|
|
388
637
|
}
|
|
389
638
|
get _fields() {
|
|
390
639
|
const fields = {};
|
|
@@ -437,9 +686,17 @@ var Form = class {
|
|
|
437
686
|
const errors = {};
|
|
438
687
|
const fields = this._fields;
|
|
439
688
|
for (const key of Object.keys(fields)) {
|
|
440
|
-
const
|
|
441
|
-
if (
|
|
442
|
-
|
|
689
|
+
const field = fields[key];
|
|
690
|
+
if (field instanceof ArrayFormField) {
|
|
691
|
+
const formErrors = this.collectArrayFormErrors(field);
|
|
692
|
+
if (formErrors.length > 0) {
|
|
693
|
+
errors[key] = formErrors;
|
|
694
|
+
}
|
|
695
|
+
} else {
|
|
696
|
+
const fieldErrors = field.errors;
|
|
697
|
+
if (fieldErrors.length > 0) {
|
|
698
|
+
errors[key] = fieldErrors;
|
|
699
|
+
}
|
|
443
700
|
}
|
|
444
701
|
}
|
|
445
702
|
for (const key of Object.keys(this._globalErrors)) {
|
|
@@ -450,20 +707,84 @@ var Form = class {
|
|
|
450
707
|
}
|
|
451
708
|
return errors;
|
|
452
709
|
}
|
|
710
|
+
/**
|
|
711
|
+
* Рекурсивно собирает все ошибки из ArrayFormField
|
|
712
|
+
*/
|
|
713
|
+
collectArrayFormErrors(arrayField) {
|
|
714
|
+
const allErrors = [];
|
|
715
|
+
allErrors.push(...arrayField.errors);
|
|
716
|
+
for (let i = 0; i < arrayField.forms.length; i++) {
|
|
717
|
+
const form = arrayField.forms[i];
|
|
718
|
+
const formAllErrors = form.allErrors;
|
|
719
|
+
for (const [fieldName, fieldErrors] of Object.entries(formAllErrors)) {
|
|
720
|
+
for (const error of fieldErrors) {
|
|
721
|
+
allErrors.push(`\u0424\u043E\u0440\u043C\u0430 ${i + 1}, ${fieldName}: ${error}`);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
return allErrors;
|
|
726
|
+
}
|
|
453
727
|
get globalErrors() {
|
|
454
728
|
return { ...this._globalErrors };
|
|
455
729
|
}
|
|
456
730
|
set errors(errors) {
|
|
457
731
|
const fields = this._fields;
|
|
458
732
|
this._globalErrors = {};
|
|
459
|
-
for (const key of Object.keys(
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
733
|
+
for (const key of Object.keys(fields)) {
|
|
734
|
+
fields[key].error = null;
|
|
735
|
+
}
|
|
736
|
+
const parsedErrors = this.errorsShema.parseErrors(errors);
|
|
737
|
+
for (const [fieldName, errorMessage] of Object.entries(parsedErrors)) {
|
|
738
|
+
this.applyErrorToField(fieldName, errorMessage, fields, this);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* Применяет ошибку к соответствующему полю
|
|
743
|
+
* Поддерживает вложенные поля через точечную нотацию
|
|
744
|
+
*/
|
|
745
|
+
applyErrorToField(fieldPath, errorMessage, fields, targetForm) {
|
|
746
|
+
if (!targetForm) {
|
|
747
|
+
console.error("applyErrorToField: targetForm is undefined");
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
if (fieldPath in fields && fields[fieldPath]) {
|
|
751
|
+
fields[fieldPath].error = errorMessage;
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
const parts = fieldPath.split(".");
|
|
755
|
+
const rootField = parts[0];
|
|
756
|
+
if (rootField in fields && fields[rootField]) {
|
|
757
|
+
const field = fields[rootField];
|
|
758
|
+
if (parts.length === 1) {
|
|
759
|
+
field.error = errorMessage;
|
|
760
|
+
} else if (parts.length > 1) {
|
|
761
|
+
this.applyNestedError(field, parts.slice(1), errorMessage, fieldPath, targetForm);
|
|
762
|
+
}
|
|
763
|
+
} else {
|
|
764
|
+
targetForm.setGlobalError(fieldPath, errorMessage);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
applyNestedError(field, pathParts, errorMessage, fullPath, targetForm) {
|
|
768
|
+
if (!targetForm) {
|
|
769
|
+
console.error("applyNestedError: targetForm is undefined");
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
const [currentPart, ...remainingParts] = pathParts;
|
|
773
|
+
if (field instanceof ArrayFormField) {
|
|
774
|
+
const index = parseInt(currentPart);
|
|
775
|
+
if (!isNaN(index) && index >= 0 && index < field.forms.length) {
|
|
776
|
+
const form = field.forms[index];
|
|
777
|
+
if (remainingParts.length > 0) {
|
|
778
|
+
const formFields = form["_fields"];
|
|
779
|
+
this.applyErrorToField(remainingParts.join("."), errorMessage, formFields, form);
|
|
780
|
+
} else {
|
|
781
|
+
form.setGlobalError(`index_${index}`, errorMessage);
|
|
782
|
+
}
|
|
464
783
|
} else {
|
|
465
|
-
|
|
784
|
+
targetForm.setGlobalError(fullPath, errorMessage);
|
|
466
785
|
}
|
|
786
|
+
} else {
|
|
787
|
+
targetForm.setGlobalError(fullPath, errorMessage);
|
|
467
788
|
}
|
|
468
789
|
}
|
|
469
790
|
setGlobalError(key, message) {
|