@ldquocc/dynamic-form 0.0.3 → 0.0.4
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.
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, Injectable, signal, untracked, input, computed, Input, Directive, effect, forwardRef, Component, EventEmitter, output, Output } from '@angular/core';
|
|
3
1
|
import * as i1 from '@angular/forms';
|
|
4
2
|
import { FormsModule, ReactiveFormsModule, FormControl, Validators, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
5
3
|
import { of, delay, Subject, takeUntil, finalize, Observable, debounceTime, distinctUntilChanged } from 'rxjs';
|
|
6
4
|
import * as i1$2 from '@angular/common';
|
|
7
5
|
import { CommonModule, CurrencyPipe } from '@angular/common';
|
|
8
6
|
import { RouterModule } from '@angular/router';
|
|
7
|
+
import * as i0 from '@angular/core';
|
|
8
|
+
import { InjectionToken, inject, Injectable, signal, untracked, input, computed, Input, Directive, effect, forwardRef, Component, EventEmitter, output, Output } from '@angular/core';
|
|
9
9
|
import * as i3$3 from 'ng-zorro-antd/form';
|
|
10
10
|
import { NzFormModule } from 'ng-zorro-antd/form';
|
|
11
11
|
import { isEqual } from 'lodash-es';
|
|
@@ -42,14 +42,6 @@ import { NzGridModule } from 'ng-zorro-antd/grid';
|
|
|
42
42
|
import * as i4$2 from 'ng-zorro-antd/collapse';
|
|
43
43
|
import { NzCollapseModule } from 'ng-zorro-antd/collapse';
|
|
44
44
|
|
|
45
|
-
var FormModeEnum;
|
|
46
|
-
(function (FormModeEnum) {
|
|
47
|
-
FormModeEnum["Add"] = "add";
|
|
48
|
-
FormModeEnum["Edit"] = "edit";
|
|
49
|
-
FormModeEnum["View"] = "view";
|
|
50
|
-
FormModeEnum["Design"] = "design";
|
|
51
|
-
})(FormModeEnum || (FormModeEnum = {}));
|
|
52
|
-
|
|
53
45
|
// Core Angular modules (cần thiết ở hầu hết các component).
|
|
54
46
|
const CORE_MODULES = [CommonModule];
|
|
55
47
|
// Form handling (thường dùng với Reactive)
|
|
@@ -568,6 +560,241 @@ class DateRangeField extends BaseDateField {
|
|
|
568
560
|
}
|
|
569
561
|
}
|
|
570
562
|
|
|
563
|
+
// Các patterns regex thường dùng trong ứng dụng
|
|
564
|
+
const PATTERN_PRESETS = {
|
|
565
|
+
alpha: '^[a-zA-Z]+$',
|
|
566
|
+
alphaNumeric: '^[a-zA-Z0-9]+$',
|
|
567
|
+
name: "^[0-9a-zA-Z_ ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼỀỀỂẾưăạảấầẩẫậắằẳẵặẹẻẽềềểếỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễệỉịọỏốồổỗộớờởỡợụủứừỬỮỰỲỴÝỶỸửữựỳỵýỷỹ\\.+,:%&=;s.\\/\\-_'\\()]+$",
|
|
568
|
+
username: '^[a-z0-9_.s]+$',
|
|
569
|
+
regexPostCode: '^[a-zA-Z0-9-s]+$',
|
|
570
|
+
alphaDash: '^[a-zA-Z0-9_-s.]+$',
|
|
571
|
+
alphaVN: '^[a-zA-Z_ ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼỀỀỂẾưăạảấầẩẫậắằẳẵặẹẻẽềềểếỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễệỉịọỏốồổỗộớờởỡợụủứừỬỮỰỲỴÝỶỸửữựỳỵýỷỹ\\,s]+$',
|
|
572
|
+
alphaNumericVN: '^[0-9a-zA-Z_ ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼỀỀỂẾưăạảấầẩẫậắằẳẵặẹẻẽềềểếỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễệỉịọỏốồổỗộớờởỡợụủứừỬỮỰỲỴÝỶỸửữựỳỵýỷỹ\\s]+$',
|
|
573
|
+
alphaDashVN: "^[0-9a-zA-Z_ ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼỀỀỂẾưăạảấầẩẫậắằẳẵặẹẻẽềềểếỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễệỉịọỏốồổỗộớờởỡợụủứừỬỮỰỲỴÝỶỸửữựỳỵýỷỹ\\.+,:%&=;s.\\/\\-_'\\()]+$",
|
|
574
|
+
unitName: '^[a-zA-Z0-9 ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼỀỀỂẾưăạảấầẩẫậắằẳẵặẹẻẽềềểếỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễệỉịọỏốồổỗộớờởỡợụủứừỬỮỰỲỴÝỶỸửữựỳỵỷỹs_-]+$',
|
|
575
|
+
date: '([12]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01]))',
|
|
576
|
+
time: '(?=[01]\\d|2[0123])=(?=[012345]\\d)=(?=[012345]\\d)',
|
|
577
|
+
dateTime: '[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[01][0-9])=[0-5][0-9]=[0-5][0-9]',
|
|
578
|
+
// dateV: "^(0?[1-9]|[12][0-9]|3[01])[\\/](0?[1-9]|1[012])[\\/]\\d{4}$",
|
|
579
|
+
// dateV: /^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-](19|20)\d\d/,
|
|
580
|
+
// dateV: "^([0-2][0-9]|(3)[0-1])(\-)(((0)[0-9])|((1)[0-2]))(\-)\d{4}$",
|
|
581
|
+
dateVN: '^(?=0[1-9]|[12]d|3[01])([/.-])(?=0[1-9]|1[012])\\1(?=19|20)dd$',
|
|
582
|
+
dateTimeVN: '^(0?[1-9]|[12][0-9]|3[01])[\\/](0?[1-9]|1[012])[\\/]\\d{4} (\\d{2})=(\\d{2})=(\\d{2})$',
|
|
583
|
+
dateShortTimeVN: '^(0?[1-9]|[12][0-9]|3[01])[\\/](0?[1-9]|1[012])[\\/]\\d{4} (\\d{2})=(\\d{2})$',
|
|
584
|
+
integer: '^\\-?[0-9]+$',
|
|
585
|
+
decimal: '^\\-?[0-9]*\\.?[0-9]+$',
|
|
586
|
+
ipAddress: '^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$',
|
|
587
|
+
base64: '[^a-zA-Z0-9\\/\\+=]',
|
|
588
|
+
citizenId: '^\\d{12}$',
|
|
589
|
+
passport: '^[A-Z0-9]{6,12}$', // Hộ chiếu - 6-12 ký tự (chữ IN HOA và số)
|
|
590
|
+
// dnkhcn: "/^DNKHCN-[A-Z]{2}-d{4}$/",
|
|
591
|
+
// msdn: "/^d{10}$/",
|
|
592
|
+
intergerNotZero: '^[0-9]*[1-9][0-9]*$',
|
|
593
|
+
//link: "(https?=//(?=www.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9].[^s]{2,}|www.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9].[^s]{2,}|https?=//(?=www.|(?!www))[a-zA-Z0-9]+.[^s]{2,}|www.[a-zA-Z0-9]+.[^s]{2,})",
|
|
594
|
+
// code: "^['A-Z''0-9''._\\-']*$",
|
|
595
|
+
code: "^['A-Z''0-9''./_\\-\\/\\Đ']*$",
|
|
596
|
+
codeHsda: "^['A-Z''0-9''./_\\-']*$",
|
|
597
|
+
link_location: '(https?://)?([\\da-z.-]+)\\.([a-z.]{2,6})([/\\w .-]*)?(\\?[\\w=&,.%-]*)?',
|
|
598
|
+
link: '(https?://)?([\\da-z.-]+)\\.([a-z.]{2,6})[/\\w .-]*/?',
|
|
599
|
+
//password: "/(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[$@$!%*?&]).{8,}/",
|
|
600
|
+
accountName: '^[a-zA-Z0-9_.]{2,20}$',
|
|
601
|
+
name_or_fullName: '^[a-zA-Z0-9_ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼỀỀỂưăạảấầẩẫậắằẳẵặẹẻẽềềểỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễếệỉịọỏốồổỗộớờởỡợụủứừỬỮỰỲỴÝỶỸửữựỳỵỷỹ ]{1,20}$',
|
|
602
|
+
packageName: '^(?:[a-zA-Z]+(?:d*[a-zA-Z_]*)*)(?:.[a-zA-Z]+(?:d*[a-zA-Z_]*)*)+$',
|
|
603
|
+
email: '^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$',
|
|
604
|
+
passwordRegex: '^(?!.*\\s)(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[~`!@#$%^&*()--+={}\\[\\]|\\\\:;"\'<>,.?/_₹]).{8,}$',
|
|
605
|
+
// phoneNumber: "^(\\+84|0)([235789])([0-9]{8,9})\\b",
|
|
606
|
+
phoneNumber: '^(\\+84|0)([235789])([0-9]{8,9})$',
|
|
607
|
+
seqNum: '^(100|[0-9]{1,2})$',
|
|
608
|
+
link_basemap: '(https://www.|http://www.|https://|http://)?[a-zA-Z]{2,}(.[a-zA-Z]{2,})(.[a-zA-Z]{2,})?/[a-zA-Z0-9]{2,}|((https://www.|http://www.|https://|http://)?[a-zA-Z]{2,}(.[a-zA-Z]{2,})(.[a-zA-Z]{2,})?)|(https://www.|http://www.|https://|http://)?[a-zA-Z0-9]{2,}.[a-zA-Z0-9]{2,}.[a-zA-Z0-9]{2,}(.[a-zA-Z0-9]{2,})?',
|
|
609
|
+
alphaDashBreakLineVN: "^[0-9a-zA-Z_ ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼỀỀỂẾưăạảấầẩẫậắằẳẵặẹẻẽềềểếỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễệỉịọỏốồổỗộớờởỡợụủứừỬỮỰỲỴÝỶỸửữựỳỵýỷỹ\\.+,:%&=;s.\\/\\-_'\\(\\)\n]+$",
|
|
610
|
+
fax: '^(\\+?\\d{1,4}[\\s-]?)?(\\(?\\d{2,4}\\)?[\\s-]?)?[\\d\\s-]{5,15}$',
|
|
611
|
+
alphaDashNameVN: "^[a-zA-Z_ ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼỀỀỂẾưăạảấầẩẫậắằẳẵặẹẻẽềềểếỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễệỉịọỏốồổỗộớờởỡợụủứừỬỮỰỲỴÝỶỸửữựỳỵýỷỹ\.s.\/\-\_'\\(\\)]{2,}$",
|
|
612
|
+
businessCode: '^\\d{10}(-\\d{3})?$',
|
|
613
|
+
};
|
|
614
|
+
// Các error message cho các pattern regex.
|
|
615
|
+
const PATTERN_ERROR_MESSAGES = {
|
|
616
|
+
required: '%s không được để trống!',
|
|
617
|
+
number: '%s phải là số!',
|
|
618
|
+
email: '%s không đúng định dạng địa chỉ Email!',
|
|
619
|
+
minlength: '%s có kích thước tối thiểu %s ký tự!',
|
|
620
|
+
maxlength: '%s có kích thước tối đa %s ký tự!',
|
|
621
|
+
min: '%s phải lớn hơn hoặc bằng %s!',
|
|
622
|
+
max: '%s phải nhỏ hơn hoặc bằng %s!',
|
|
623
|
+
alpha: '%s chỉ chứa ký tự thường và ký tự in hoa không dấu!',
|
|
624
|
+
alphaNumeric: '%s chỉ chứa ký tự thường, ký tự in hoa không dấu và số!',
|
|
625
|
+
name: '%s chỉ chứa ký tự thường, ký tự in hoa có dấu, số, dấu chấm, dấu phẩy, gạch dưới _ hoặc gạch ngang -, dấu ngoặc ()!',
|
|
626
|
+
username: '%s chỉ chứa ký tự thường, số, dấu chấm và dấu gạch dưới _',
|
|
627
|
+
regexPostCode: '%s chỉ chứa ký tự thường, ký tự in hoa không dấu, số, gạch ngang -',
|
|
628
|
+
alphaDash: '%s chỉ chứa ký tự thường, ký tự in hoa không dấu, số, gạch dưới _ hoặc gạch ngang -, dấu ngoặc ()!',
|
|
629
|
+
alphaVN: '%s chỉ chứa ký tự thường và ký tự in hoa có dấu!',
|
|
630
|
+
alphaNumericVN: '%s chỉ chứa ký tự thường, ký tự in hoa có dấu và số!',
|
|
631
|
+
alphaDashVN: '%s chỉ chứa ký tự thường, ký tự in hoa có dấu, số, dấu chấm, dấu phẩy, gạch dưới _ hoặc gạch ngang -, dấu ngoặc ()!',
|
|
632
|
+
alphaDashNameVN: '%s chỉ chứa ký tự thường, ký tự in hoa có dấu và ít nhất 2 ký tự!',
|
|
633
|
+
unitName: '%s chỉ chứa ký tự thường, ký tự in hoa có dấu, số, gạch dưới _ hoặc gạch ngang -',
|
|
634
|
+
date: '%s không đúng định dạng năm tháng ngày (YYYY-MM-DD)!',
|
|
635
|
+
time: '%s không đúng định dạng giờ phút giây (HH:MM:SS)!',
|
|
636
|
+
dateTime: '%s không đúng định dạng năm tháng ngày giờ phút giây (YYYY-MM-DD HH:MM:SS)!',
|
|
637
|
+
dateVN: '%s không đúng định dạng ngày tháng năm (DD/MM/YYYY)!',
|
|
638
|
+
dateTimeVN: '%s không đúng định dạng ngày tháng năm giờ phút giây (DD/MM/YYYY HH:MI:SS)!',
|
|
639
|
+
dateShortTimeVN: '%s không đúng định dạng ngày tháng năm giờ phút (DD/MM/YYYY HH:MI)!',
|
|
640
|
+
integer: '%s phải là số nguyên!',
|
|
641
|
+
decimal: '%s phải là số thập phân!',
|
|
642
|
+
ipAddress: '%s không đúng định dạng địa chỉ IP!',
|
|
643
|
+
base64: '%s không đúng định dạng Base64!',
|
|
644
|
+
intergerNotZero: '%s phải là số nguyên dương khác 0!',
|
|
645
|
+
link_location: '%s không đúng định dạng!',
|
|
646
|
+
link: '%s không đúng định dạng!',
|
|
647
|
+
codeHsda: "%s chỉ chứa các chữ cái in hoa không dấu, số và dấu '.', '_', '-'",
|
|
648
|
+
code: "%s chỉ chứa các chữ cái in hoa không dấu, số và dấu '.', '_', '-', '/'",
|
|
649
|
+
// code: "%s chỉ chứa các chữ cái in hoa,chữ cái thường không dấu, số và dấu '.', '_', '-'",
|
|
650
|
+
accountName: '%s chỉ bao gồm các kí tự từ A-Z, các số từ 0-9 và ít nhất 2 ký tự',
|
|
651
|
+
name_or_fullName: '',
|
|
652
|
+
// pwdErrorTip:
|
|
653
|
+
// "%s phải có ít nhất 8 ký tự. Ít nhất 1 ký tự hoa, số, ký tự thường và ký tự đặc biệt",
|
|
654
|
+
phoneNumber: 'Số điện thoại không hợp lệ (Gợi ý: Số điện thoại phải bắt đầu bằng đầu số 02, 03, 05, 07, 08, 09 hoặc +84 và có độ dài 10-11 ký tự)',
|
|
655
|
+
seqNum: '(Gợi ý: Thứ tự hiển thị phải là dạng số và có giá trị từ 1-100)',
|
|
656
|
+
link_basemap: '%s không đúng định dạng!',
|
|
657
|
+
passwordRegex: '%s phải có ít nhất 8 ký tự. Ít nhất 1 ký tự hoa, ký tự thường, số và ký tự đặc biệt',
|
|
658
|
+
alphaDashBreakLineVN: '%s chỉ chứa ký tự thường, ký tự in hoa có dấu, số, dấu chấm, dấu phẩy, gạch dưới _ hoặc gạch ngang -, dấu ngoặc ()!',
|
|
659
|
+
citizenId: '%s phải đúng định dạng 12 số!',
|
|
660
|
+
businessCode: '',
|
|
661
|
+
};
|
|
662
|
+
|
|
663
|
+
const resolvePattern = (pattern) => {
|
|
664
|
+
if (!pattern)
|
|
665
|
+
return { type: 'unknown', value: '' };
|
|
666
|
+
// Trường hợp là RegExp thực sự
|
|
667
|
+
if (pattern instanceof RegExp)
|
|
668
|
+
return { type: 'regexObject', value: pattern };
|
|
669
|
+
// Trường hợp là tên preset (ưu tiên nếu trùng)
|
|
670
|
+
if (pattern in PATTERN_PRESETS) {
|
|
671
|
+
return { type: 'regexKey', value: PATTERN_PRESETS[pattern] };
|
|
672
|
+
}
|
|
673
|
+
try {
|
|
674
|
+
// Trường hợp là chuỗi regex dạng "^abc$"
|
|
675
|
+
return { type: 'regexString', value: new RegExp(pattern) };
|
|
676
|
+
}
|
|
677
|
+
catch (err) {
|
|
678
|
+
console.warn(`Không thể parse pattern "${pattern}"`, err);
|
|
679
|
+
return { type: 'unknown', value: '' };
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
const DEFAULT_INPUT_VALUE = '';
|
|
684
|
+
/**
|
|
685
|
+
* Interface base chung cho Các dạng Input Field.
|
|
686
|
+
*/
|
|
687
|
+
class InputBaseField extends BaseField {
|
|
688
|
+
constructor(init) {
|
|
689
|
+
super(init);
|
|
690
|
+
/**
|
|
691
|
+
* Gán giá trị cho các props cần giá trị mặc định ở Input.
|
|
692
|
+
*/
|
|
693
|
+
this.controlType = ControlTypeEnum.Input;
|
|
694
|
+
this.value = DEFAULT_INPUT_VALUE;
|
|
695
|
+
this.initialValue = DEFAULT_INPUT_VALUE;
|
|
696
|
+
this.suffixes = [];
|
|
697
|
+
this.isCurrency = false;
|
|
698
|
+
Object.assign(this, init);
|
|
699
|
+
}
|
|
700
|
+
// Mảng ValidatorFn các validation chung được hỗ trợ sẵn bởi Reactive form của angular cho Input.
|
|
701
|
+
getInputCommonValidators() {
|
|
702
|
+
const validators = this.getCommonValidators();
|
|
703
|
+
if (this.minLength)
|
|
704
|
+
validators.push(Validators.minLength(this.minLength));
|
|
705
|
+
if (this.maxLength)
|
|
706
|
+
validators.push(Validators.maxLength(this.maxLength));
|
|
707
|
+
if (this.pattern) {
|
|
708
|
+
const resolvePatternResult = resolvePattern(this.pattern);
|
|
709
|
+
if (resolvePatternResult?.type !== 'unknown')
|
|
710
|
+
validators.push(Validators.pattern(resolvePatternResult.value));
|
|
711
|
+
}
|
|
712
|
+
return validators;
|
|
713
|
+
}
|
|
714
|
+
// Mảng ValidatorFn các custom validation có thể dùng cho Input.
|
|
715
|
+
getInputCustomValidators() {
|
|
716
|
+
const validators = this.getCustomValidators();
|
|
717
|
+
validators.push(noLeadingSpaceValidator());
|
|
718
|
+
return validators;
|
|
719
|
+
}
|
|
720
|
+
// Tạo Form Control cho Input Field.
|
|
721
|
+
toFormControl() {
|
|
722
|
+
const commonValidators = this.getInputCommonValidators();
|
|
723
|
+
const customValidators = this.getInputCustomValidators();
|
|
724
|
+
return new FormControl(this.value ?? '', [...commonValidators, ...customValidators]);
|
|
725
|
+
}
|
|
726
|
+
// Giá trị mặc định.
|
|
727
|
+
getDefaultValue() {
|
|
728
|
+
return DEFAULT_INPUT_VALUE;
|
|
729
|
+
}
|
|
730
|
+
toFormValue(modelValue) {
|
|
731
|
+
return String(modelValue);
|
|
732
|
+
}
|
|
733
|
+
getErrorMessage(errorKey, errorValue, allFields) {
|
|
734
|
+
if (errorKey === CommonValidaterEnum.Pattern) {
|
|
735
|
+
if (this.pattern)
|
|
736
|
+
return getDefaultPatternErrorMessage(this.label, this.pattern);
|
|
737
|
+
}
|
|
738
|
+
if (errorKey === CommonValidaterEnum.MinLength)
|
|
739
|
+
return getDefaultMinLengthErrorMessage(this.label, errorValue);
|
|
740
|
+
if (errorKey === CommonValidaterEnum.MaxLength)
|
|
741
|
+
return getDefaultMaxLengthErrorMessage(this.label, errorValue);
|
|
742
|
+
if (errorKey === CustomValidaterEnum.LeadingSpace)
|
|
743
|
+
return getLeadingSpaceErrorMessage(this.label);
|
|
744
|
+
return super.getErrorMessage(errorKey, errorValue, allFields);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
/**
|
|
749
|
+
* Interface của Input Field type là Text.
|
|
750
|
+
*/
|
|
751
|
+
class InputTextField extends InputBaseField {
|
|
752
|
+
constructor(init) {
|
|
753
|
+
super(init);
|
|
754
|
+
/**
|
|
755
|
+
* Gán giá trị cho các props cần giá trị mặc định ở Input Text.
|
|
756
|
+
*/
|
|
757
|
+
this.type = FieldTypeEnum.InputText;
|
|
758
|
+
Object.assign(this, init);
|
|
759
|
+
}
|
|
760
|
+
// Tạo Form Control cho Input Text Field.
|
|
761
|
+
toFormControl() {
|
|
762
|
+
const commonValidators = this.getInputCommonValidators();
|
|
763
|
+
const customValidators = this.getInputCustomValidators();
|
|
764
|
+
return new FormControl(this.value ?? '', [...commonValidators, ...customValidators]);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/**
|
|
769
|
+
* Interface của Input Field type là Password.
|
|
770
|
+
*/
|
|
771
|
+
class InputPasswordField extends InputBaseField {
|
|
772
|
+
constructor(init) {
|
|
773
|
+
super(init);
|
|
774
|
+
/**
|
|
775
|
+
* Gán giá trị cho các props cần giá trị mặc định ở Input Password.
|
|
776
|
+
*/
|
|
777
|
+
this.type = FieldTypeEnum.InputPassword;
|
|
778
|
+
Object.assign(this, init);
|
|
779
|
+
}
|
|
780
|
+
// Mảng ValidatorFn các validation chung được hỗ trợ sẵn bởi Reactive form của angular cho Input Password.
|
|
781
|
+
getInputPasswordCommonValidators() {
|
|
782
|
+
const validators = this.getInputCommonValidators();
|
|
783
|
+
return validators;
|
|
784
|
+
}
|
|
785
|
+
// Mảng ValidatorFn các validation chung được hỗ trợ sẵn bởi angular cho Input Password.
|
|
786
|
+
getInputPasswordCustomValidators() {
|
|
787
|
+
const validators = this.getInputCustomValidators();
|
|
788
|
+
return validators;
|
|
789
|
+
}
|
|
790
|
+
// Tạo Form Control cho Input Password Field.
|
|
791
|
+
toFormControl() {
|
|
792
|
+
const commonValidators = this.getInputPasswordCommonValidators();
|
|
793
|
+
const customValidators = this.getInputPasswordCustomValidators();
|
|
794
|
+
return new FormControl(this.value ?? '', [...commonValidators, ...customValidators]);
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
571
798
|
/**
|
|
572
799
|
* Interface base chung cho Các dạng Input Field.
|
|
573
800
|
*/
|
|
@@ -2723,126 +2950,6 @@ const reminderCustomRequiredValidator = () => {
|
|
|
2723
2950
|
};
|
|
2724
2951
|
};
|
|
2725
2952
|
|
|
2726
|
-
// Các patterns regex thường dùng trong ứng dụng
|
|
2727
|
-
const PATTERN_PRESETS = {
|
|
2728
|
-
alpha: '^[a-zA-Z]+$',
|
|
2729
|
-
alphaNumeric: '^[a-zA-Z0-9]+$',
|
|
2730
|
-
name: "^[0-9a-zA-Z_ ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼỀỀỂẾưăạảấầẩẫậắằẳẵặẹẻẽềềểếỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễệỉịọỏốồổỗộớờởỡợụủứừỬỮỰỲỴÝỶỸửữựỳỵýỷỹ\\.+,:%&=;s.\\/\\-_'\\()]+$",
|
|
2731
|
-
username: '^[a-z0-9_.s]+$',
|
|
2732
|
-
regexPostCode: '^[a-zA-Z0-9-s]+$',
|
|
2733
|
-
alphaDash: '^[a-zA-Z0-9_-s.]+$',
|
|
2734
|
-
alphaVN: '^[a-zA-Z_ ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼỀỀỂẾưăạảấầẩẫậắằẳẵặẹẻẽềềểếỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễệỉịọỏốồổỗộớờởỡợụủứừỬỮỰỲỴÝỶỸửữựỳỵýỷỹ\\,s]+$',
|
|
2735
|
-
alphaNumericVN: '^[0-9a-zA-Z_ ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼỀỀỂẾưăạảấầẩẫậắằẳẵặẹẻẽềềểếỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễệỉịọỏốồổỗộớờởỡợụủứừỬỮỰỲỴÝỶỸửữựỳỵýỷỹ\\s]+$',
|
|
2736
|
-
alphaDashVN: "^[0-9a-zA-Z_ ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼỀỀỂẾưăạảấầẩẫậắằẳẵặẹẻẽềềểếỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễệỉịọỏốồổỗộớờởỡợụủứừỬỮỰỲỴÝỶỸửữựỳỵýỷỹ\\.+,:%&=;s.\\/\\-_'\\()]+$",
|
|
2737
|
-
unitName: '^[a-zA-Z0-9 ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼỀỀỂẾưăạảấầẩẫậắằẳẵặẹẻẽềềểếỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễệỉịọỏốồổỗộớờởỡợụủứừỬỮỰỲỴÝỶỸửữựỳỵỷỹs_-]+$',
|
|
2738
|
-
date: '([12]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01]))',
|
|
2739
|
-
time: '(?=[01]\\d|2[0123])=(?=[012345]\\d)=(?=[012345]\\d)',
|
|
2740
|
-
dateTime: '[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[01][0-9])=[0-5][0-9]=[0-5][0-9]',
|
|
2741
|
-
// dateV: "^(0?[1-9]|[12][0-9]|3[01])[\\/](0?[1-9]|1[012])[\\/]\\d{4}$",
|
|
2742
|
-
// dateV: /^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-](19|20)\d\d/,
|
|
2743
|
-
// dateV: "^([0-2][0-9]|(3)[0-1])(\-)(((0)[0-9])|((1)[0-2]))(\-)\d{4}$",
|
|
2744
|
-
dateVN: '^(?=0[1-9]|[12]d|3[01])([/.-])(?=0[1-9]|1[012])\\1(?=19|20)dd$',
|
|
2745
|
-
dateTimeVN: '^(0?[1-9]|[12][0-9]|3[01])[\\/](0?[1-9]|1[012])[\\/]\\d{4} (\\d{2})=(\\d{2})=(\\d{2})$',
|
|
2746
|
-
dateShortTimeVN: '^(0?[1-9]|[12][0-9]|3[01])[\\/](0?[1-9]|1[012])[\\/]\\d{4} (\\d{2})=(\\d{2})$',
|
|
2747
|
-
integer: '^\\-?[0-9]+$',
|
|
2748
|
-
decimal: '^\\-?[0-9]*\\.?[0-9]+$',
|
|
2749
|
-
ipAddress: '^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$',
|
|
2750
|
-
base64: '[^a-zA-Z0-9\\/\\+=]',
|
|
2751
|
-
citizenId: '^\\d{12}$',
|
|
2752
|
-
passport: '^[A-Z0-9]{6,12}$', // Hộ chiếu - 6-12 ký tự (chữ IN HOA và số)
|
|
2753
|
-
// dnkhcn: "/^DNKHCN-[A-Z]{2}-d{4}$/",
|
|
2754
|
-
// msdn: "/^d{10}$/",
|
|
2755
|
-
intergerNotZero: '^[0-9]*[1-9][0-9]*$',
|
|
2756
|
-
//link: "(https?=//(?=www.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9].[^s]{2,}|www.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9].[^s]{2,}|https?=//(?=www.|(?!www))[a-zA-Z0-9]+.[^s]{2,}|www.[a-zA-Z0-9]+.[^s]{2,})",
|
|
2757
|
-
// code: "^['A-Z''0-9''._\\-']*$",
|
|
2758
|
-
code: "^['A-Z''0-9''./_\\-\\/\\Đ']*$",
|
|
2759
|
-
codeHsda: "^['A-Z''0-9''./_\\-']*$",
|
|
2760
|
-
link_location: '(https?://)?([\\da-z.-]+)\\.([a-z.]{2,6})([/\\w .-]*)?(\\?[\\w=&,.%-]*)?',
|
|
2761
|
-
link: '(https?://)?([\\da-z.-]+)\\.([a-z.]{2,6})[/\\w .-]*/?',
|
|
2762
|
-
//password: "/(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[$@$!%*?&]).{8,}/",
|
|
2763
|
-
accountName: '^[a-zA-Z0-9_.]{2,20}$',
|
|
2764
|
-
name_or_fullName: '^[a-zA-Z0-9_ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼỀỀỂưăạảấầẩẫậắằẳẵặẹẻẽềềểỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễếệỉịọỏốồổỗộớờởỡợụủứừỬỮỰỲỴÝỶỸửữựỳỵỷỹ ]{1,20}$',
|
|
2765
|
-
packageName: '^(?:[a-zA-Z]+(?:d*[a-zA-Z_]*)*)(?:.[a-zA-Z]+(?:d*[a-zA-Z_]*)*)+$',
|
|
2766
|
-
email: '^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$',
|
|
2767
|
-
passwordRegex: '^(?!.*\\s)(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[~`!@#$%^&*()--+={}\\[\\]|\\\\:;"\'<>,.?/_₹]).{8,}$',
|
|
2768
|
-
// phoneNumber: "^(\\+84|0)([235789])([0-9]{8,9})\\b",
|
|
2769
|
-
phoneNumber: '^(\\+84|0)([235789])([0-9]{8,9})$',
|
|
2770
|
-
seqNum: '^(100|[0-9]{1,2})$',
|
|
2771
|
-
link_basemap: '(https://www.|http://www.|https://|http://)?[a-zA-Z]{2,}(.[a-zA-Z]{2,})(.[a-zA-Z]{2,})?/[a-zA-Z0-9]{2,}|((https://www.|http://www.|https://|http://)?[a-zA-Z]{2,}(.[a-zA-Z]{2,})(.[a-zA-Z]{2,})?)|(https://www.|http://www.|https://|http://)?[a-zA-Z0-9]{2,}.[a-zA-Z0-9]{2,}.[a-zA-Z0-9]{2,}(.[a-zA-Z0-9]{2,})?',
|
|
2772
|
-
alphaDashBreakLineVN: "^[0-9a-zA-Z_ ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼỀỀỂẾưăạảấầẩẫậắằẳẵặẹẻẽềềểếỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễệỉịọỏốồổỗộớờởỡợụủứừỬỮỰỲỴÝỶỸửữựỳỵýỷỹ\\.+,:%&=;s.\\/\\-_'\\(\\)\n]+$",
|
|
2773
|
-
fax: '^(\\+?\\d{1,4}[\\s-]?)?(\\(?\\d{2,4}\\)?[\\s-]?)?[\\d\\s-]{5,15}$',
|
|
2774
|
-
alphaDashNameVN: "^[a-zA-Z_ ÀÁÂÃÈÉÊÌÍÒÓÔÕÙÚĂĐĨŨƠàáâãèéêìíòóôõùúăđĩũơƯĂẠẢẤẦẨẪẬẮẰẲẴẶẸẺẼỀỀỂẾưăạảấầẩẫậắằẳẵặẹẻẽềềểếỄỆỈỊỌỎỐỒỔỖỘỚỜỞỠỢỤỦỨỪễệỉịọỏốồổỗộớờởỡợụủứừỬỮỰỲỴÝỶỸửữựỳỵýỷỹ\.s.\/\-\_'\\(\\)]{2,}$",
|
|
2775
|
-
businessCode: '^\\d{10}(-\\d{3})?$',
|
|
2776
|
-
};
|
|
2777
|
-
// Các error message cho các pattern regex.
|
|
2778
|
-
const PATTERN_ERROR_MESSAGES = {
|
|
2779
|
-
required: '%s không được để trống!',
|
|
2780
|
-
number: '%s phải là số!',
|
|
2781
|
-
email: '%s không đúng định dạng địa chỉ Email!',
|
|
2782
|
-
minlength: '%s có kích thước tối thiểu %s ký tự!',
|
|
2783
|
-
maxlength: '%s có kích thước tối đa %s ký tự!',
|
|
2784
|
-
min: '%s phải lớn hơn hoặc bằng %s!',
|
|
2785
|
-
max: '%s phải nhỏ hơn hoặc bằng %s!',
|
|
2786
|
-
alpha: '%s chỉ chứa ký tự thường và ký tự in hoa không dấu!',
|
|
2787
|
-
alphaNumeric: '%s chỉ chứa ký tự thường, ký tự in hoa không dấu và số!',
|
|
2788
|
-
name: '%s chỉ chứa ký tự thường, ký tự in hoa có dấu, số, dấu chấm, dấu phẩy, gạch dưới _ hoặc gạch ngang -, dấu ngoặc ()!',
|
|
2789
|
-
username: '%s chỉ chứa ký tự thường, số, dấu chấm và dấu gạch dưới _',
|
|
2790
|
-
regexPostCode: '%s chỉ chứa ký tự thường, ký tự in hoa không dấu, số, gạch ngang -',
|
|
2791
|
-
alphaDash: '%s chỉ chứa ký tự thường, ký tự in hoa không dấu, số, gạch dưới _ hoặc gạch ngang -, dấu ngoặc ()!',
|
|
2792
|
-
alphaVN: '%s chỉ chứa ký tự thường và ký tự in hoa có dấu!',
|
|
2793
|
-
alphaNumericVN: '%s chỉ chứa ký tự thường, ký tự in hoa có dấu và số!',
|
|
2794
|
-
alphaDashVN: '%s chỉ chứa ký tự thường, ký tự in hoa có dấu, số, dấu chấm, dấu phẩy, gạch dưới _ hoặc gạch ngang -, dấu ngoặc ()!',
|
|
2795
|
-
alphaDashNameVN: '%s chỉ chứa ký tự thường, ký tự in hoa có dấu và ít nhất 2 ký tự!',
|
|
2796
|
-
unitName: '%s chỉ chứa ký tự thường, ký tự in hoa có dấu, số, gạch dưới _ hoặc gạch ngang -',
|
|
2797
|
-
date: '%s không đúng định dạng năm tháng ngày (YYYY-MM-DD)!',
|
|
2798
|
-
time: '%s không đúng định dạng giờ phút giây (HH:MM:SS)!',
|
|
2799
|
-
dateTime: '%s không đúng định dạng năm tháng ngày giờ phút giây (YYYY-MM-DD HH:MM:SS)!',
|
|
2800
|
-
dateVN: '%s không đúng định dạng ngày tháng năm (DD/MM/YYYY)!',
|
|
2801
|
-
dateTimeVN: '%s không đúng định dạng ngày tháng năm giờ phút giây (DD/MM/YYYY HH:MI:SS)!',
|
|
2802
|
-
dateShortTimeVN: '%s không đúng định dạng ngày tháng năm giờ phút (DD/MM/YYYY HH:MI)!',
|
|
2803
|
-
integer: '%s phải là số nguyên!',
|
|
2804
|
-
decimal: '%s phải là số thập phân!',
|
|
2805
|
-
ipAddress: '%s không đúng định dạng địa chỉ IP!',
|
|
2806
|
-
base64: '%s không đúng định dạng Base64!',
|
|
2807
|
-
intergerNotZero: '%s phải là số nguyên dương khác 0!',
|
|
2808
|
-
link_location: '%s không đúng định dạng!',
|
|
2809
|
-
link: '%s không đúng định dạng!',
|
|
2810
|
-
codeHsda: "%s chỉ chứa các chữ cái in hoa không dấu, số và dấu '.', '_', '-'",
|
|
2811
|
-
code: "%s chỉ chứa các chữ cái in hoa không dấu, số và dấu '.', '_', '-', '/'",
|
|
2812
|
-
// code: "%s chỉ chứa các chữ cái in hoa,chữ cái thường không dấu, số và dấu '.', '_', '-'",
|
|
2813
|
-
accountName: '%s chỉ bao gồm các kí tự từ A-Z, các số từ 0-9 và ít nhất 2 ký tự',
|
|
2814
|
-
name_or_fullName: '',
|
|
2815
|
-
// pwdErrorTip:
|
|
2816
|
-
// "%s phải có ít nhất 8 ký tự. Ít nhất 1 ký tự hoa, số, ký tự thường và ký tự đặc biệt",
|
|
2817
|
-
phoneNumber: 'Số điện thoại không hợp lệ (Gợi ý: Số điện thoại phải bắt đầu bằng đầu số 02, 03, 05, 07, 08, 09 hoặc +84 và có độ dài 10-11 ký tự)',
|
|
2818
|
-
seqNum: '(Gợi ý: Thứ tự hiển thị phải là dạng số và có giá trị từ 1-100)',
|
|
2819
|
-
link_basemap: '%s không đúng định dạng!',
|
|
2820
|
-
passwordRegex: '%s phải có ít nhất 8 ký tự. Ít nhất 1 ký tự hoa, ký tự thường, số và ký tự đặc biệt',
|
|
2821
|
-
alphaDashBreakLineVN: '%s chỉ chứa ký tự thường, ký tự in hoa có dấu, số, dấu chấm, dấu phẩy, gạch dưới _ hoặc gạch ngang -, dấu ngoặc ()!',
|
|
2822
|
-
citizenId: '%s phải đúng định dạng 12 số!',
|
|
2823
|
-
businessCode: '',
|
|
2824
|
-
};
|
|
2825
|
-
|
|
2826
|
-
const resolvePattern = (pattern) => {
|
|
2827
|
-
if (!pattern)
|
|
2828
|
-
return { type: 'unknown', value: '' };
|
|
2829
|
-
// Trường hợp là RegExp thực sự
|
|
2830
|
-
if (pattern instanceof RegExp)
|
|
2831
|
-
return { type: 'regexObject', value: pattern };
|
|
2832
|
-
// Trường hợp là tên preset (ưu tiên nếu trùng)
|
|
2833
|
-
if (pattern in PATTERN_PRESETS) {
|
|
2834
|
-
return { type: 'regexKey', value: PATTERN_PRESETS[pattern] };
|
|
2835
|
-
}
|
|
2836
|
-
try {
|
|
2837
|
-
// Trường hợp là chuỗi regex dạng "^abc$"
|
|
2838
|
-
return { type: 'regexString', value: new RegExp(pattern) };
|
|
2839
|
-
}
|
|
2840
|
-
catch (err) {
|
|
2841
|
-
console.warn(`Không thể parse pattern "${pattern}"`, err);
|
|
2842
|
-
return { type: 'unknown', value: '' };
|
|
2843
|
-
}
|
|
2844
|
-
};
|
|
2845
|
-
|
|
2846
2953
|
const getDefaultPatternErrorMessage = (label, pattern) => {
|
|
2847
2954
|
let finalErrorMessage = '';
|
|
2848
2955
|
const resolvePatternResult = resolvePattern(pattern);
|
|
@@ -2874,6 +2981,14 @@ const getLeadingSpaceErrorMessage = (label) => {
|
|
|
2874
2981
|
return `${label || 'Trường này'} không được bắt đầu bằng khoảng trắng`;
|
|
2875
2982
|
};
|
|
2876
2983
|
|
|
2984
|
+
var FormModeEnum;
|
|
2985
|
+
(function (FormModeEnum) {
|
|
2986
|
+
FormModeEnum["Add"] = "add";
|
|
2987
|
+
FormModeEnum["Edit"] = "edit";
|
|
2988
|
+
FormModeEnum["View"] = "view";
|
|
2989
|
+
FormModeEnum["Design"] = "design";
|
|
2990
|
+
})(FormModeEnum || (FormModeEnum = {}));
|
|
2991
|
+
|
|
2877
2992
|
/**
|
|
2878
2993
|
* Abstract class chung cho Field.
|
|
2879
2994
|
*/
|
|
@@ -2928,119 +3043,23 @@ class BaseField {
|
|
|
2928
3043
|
}
|
|
2929
3044
|
}
|
|
2930
3045
|
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
* Interface base chung cho Các dạng Input Field.
|
|
2934
|
-
*/
|
|
2935
|
-
class InputBaseField extends BaseField {
|
|
2936
|
-
constructor(init) {
|
|
2937
|
-
super(init);
|
|
2938
|
-
/**
|
|
2939
|
-
* Gán giá trị cho các props cần giá trị mặc định ở Input.
|
|
2940
|
-
*/
|
|
2941
|
-
this.controlType = ControlTypeEnum.Input;
|
|
2942
|
-
this.value = DEFAULT_INPUT_VALUE;
|
|
2943
|
-
this.initialValue = DEFAULT_INPUT_VALUE;
|
|
2944
|
-
this.suffixes = [];
|
|
2945
|
-
this.isCurrency = false;
|
|
2946
|
-
Object.assign(this, init);
|
|
2947
|
-
}
|
|
2948
|
-
// Mảng ValidatorFn các validation chung được hỗ trợ sẵn bởi Reactive form của angular cho Input.
|
|
2949
|
-
getInputCommonValidators() {
|
|
2950
|
-
const validators = this.getCommonValidators();
|
|
2951
|
-
if (this.minLength)
|
|
2952
|
-
validators.push(Validators.minLength(this.minLength));
|
|
2953
|
-
if (this.maxLength)
|
|
2954
|
-
validators.push(Validators.maxLength(this.maxLength));
|
|
2955
|
-
if (this.pattern) {
|
|
2956
|
-
const resolvePatternResult = resolvePattern(this.pattern);
|
|
2957
|
-
if (resolvePatternResult?.type !== 'unknown')
|
|
2958
|
-
validators.push(Validators.pattern(resolvePatternResult.value));
|
|
2959
|
-
}
|
|
2960
|
-
return validators;
|
|
2961
|
-
}
|
|
2962
|
-
// Mảng ValidatorFn các custom validation có thể dùng cho Input.
|
|
2963
|
-
getInputCustomValidators() {
|
|
2964
|
-
const validators = this.getCustomValidators();
|
|
2965
|
-
validators.push(noLeadingSpaceValidator());
|
|
2966
|
-
return validators;
|
|
2967
|
-
}
|
|
2968
|
-
// Tạo Form Control cho Input Field.
|
|
2969
|
-
toFormControl() {
|
|
2970
|
-
const commonValidators = this.getInputCommonValidators();
|
|
2971
|
-
const customValidators = this.getInputCustomValidators();
|
|
2972
|
-
return new FormControl(this.value ?? '', [...commonValidators, ...customValidators]);
|
|
2973
|
-
}
|
|
2974
|
-
// Giá trị mặc định.
|
|
2975
|
-
getDefaultValue() {
|
|
2976
|
-
return DEFAULT_INPUT_VALUE;
|
|
2977
|
-
}
|
|
2978
|
-
toFormValue(modelValue) {
|
|
2979
|
-
return String(modelValue);
|
|
2980
|
-
}
|
|
2981
|
-
getErrorMessage(errorKey, errorValue, allFields) {
|
|
2982
|
-
if (errorKey === CommonValidaterEnum.Pattern) {
|
|
2983
|
-
if (this.pattern)
|
|
2984
|
-
return getDefaultPatternErrorMessage(this.label, this.pattern);
|
|
2985
|
-
}
|
|
2986
|
-
if (errorKey === CommonValidaterEnum.MinLength)
|
|
2987
|
-
return getDefaultMinLengthErrorMessage(this.label, errorValue);
|
|
2988
|
-
if (errorKey === CommonValidaterEnum.MaxLength)
|
|
2989
|
-
return getDefaultMaxLengthErrorMessage(this.label, errorValue);
|
|
2990
|
-
if (errorKey === CustomValidaterEnum.LeadingSpace)
|
|
2991
|
-
return getLeadingSpaceErrorMessage(this.label);
|
|
2992
|
-
return super.getErrorMessage(errorKey, errorValue, allFields);
|
|
2993
|
-
}
|
|
2994
|
-
}
|
|
2995
|
-
|
|
2996
|
-
/**
|
|
2997
|
-
* Interface của Input Field type là Text.
|
|
2998
|
-
*/
|
|
2999
|
-
class InputTextField extends InputBaseField {
|
|
3046
|
+
// Dữ liệu sau khi đã tiến hành xử lý gom nhóm từ fields và groups.
|
|
3047
|
+
class GroupedFields {
|
|
3000
3048
|
constructor(init) {
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
* Gán giá trị cho các props cần giá trị mặc định ở Input Text.
|
|
3004
|
-
*/
|
|
3005
|
-
this.type = FieldTypeEnum.InputText;
|
|
3049
|
+
this.noGroup = [];
|
|
3050
|
+
this.grouped = [];
|
|
3006
3051
|
Object.assign(this, init);
|
|
3007
3052
|
}
|
|
3008
|
-
// Tạo Form Control cho Input Text Field.
|
|
3009
|
-
toFormControl() {
|
|
3010
|
-
const commonValidators = this.getInputCommonValidators();
|
|
3011
|
-
const customValidators = this.getInputCustomValidators();
|
|
3012
|
-
return new FormControl(this.value ?? '', [...commonValidators, ...customValidators]);
|
|
3013
|
-
}
|
|
3014
3053
|
}
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
* Interface của Input Field type là Password.
|
|
3018
|
-
*/
|
|
3019
|
-
class InputPasswordField extends InputBaseField {
|
|
3054
|
+
// Đại diện cho 1 group.
|
|
3055
|
+
class FieldGroup {
|
|
3020
3056
|
constructor(init) {
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
this.type = FieldTypeEnum.InputPassword;
|
|
3057
|
+
this.isActive = false;
|
|
3058
|
+
this.showArrow = true;
|
|
3059
|
+
this.disabled = false;
|
|
3060
|
+
this.required = false;
|
|
3026
3061
|
Object.assign(this, init);
|
|
3027
3062
|
}
|
|
3028
|
-
// Mảng ValidatorFn các validation chung được hỗ trợ sẵn bởi Reactive form của angular cho Input Password.
|
|
3029
|
-
getInputPasswordCommonValidators() {
|
|
3030
|
-
const validators = this.getInputCommonValidators();
|
|
3031
|
-
return validators;
|
|
3032
|
-
}
|
|
3033
|
-
// Mảng ValidatorFn các validation chung được hỗ trợ sẵn bởi angular cho Input Password.
|
|
3034
|
-
getInputPasswordCustomValidators() {
|
|
3035
|
-
const validators = this.getInputCustomValidators();
|
|
3036
|
-
return validators;
|
|
3037
|
-
}
|
|
3038
|
-
// Tạo Form Control cho Input Password Field.
|
|
3039
|
-
toFormControl() {
|
|
3040
|
-
const commonValidators = this.getInputPasswordCommonValidators();
|
|
3041
|
-
const customValidators = this.getInputPasswordCustomValidators();
|
|
3042
|
-
return new FormControl(this.value ?? '', [...commonValidators, ...customValidators]);
|
|
3043
|
-
}
|
|
3044
3063
|
}
|
|
3045
3064
|
|
|
3046
3065
|
const buildForm = (fields, mode, model) => {
|
|
@@ -3100,25 +3119,6 @@ const createSelectPlaceholder = (field) => {
|
|
|
3100
3119
|
return `Nhập ${field.key?.toLowerCase()}`;
|
|
3101
3120
|
};
|
|
3102
3121
|
|
|
3103
|
-
// Dữ liệu sau khi đã tiến hành xử lý gom nhóm từ fields và groups.
|
|
3104
|
-
class GroupedFields {
|
|
3105
|
-
constructor(init) {
|
|
3106
|
-
this.noGroup = [];
|
|
3107
|
-
this.grouped = [];
|
|
3108
|
-
Object.assign(this, init);
|
|
3109
|
-
}
|
|
3110
|
-
}
|
|
3111
|
-
// Đại diện cho 1 group.
|
|
3112
|
-
class FieldGroup {
|
|
3113
|
-
constructor(init) {
|
|
3114
|
-
this.isActive = false;
|
|
3115
|
-
this.showArrow = true;
|
|
3116
|
-
this.disabled = false;
|
|
3117
|
-
this.required = false;
|
|
3118
|
-
Object.assign(this, init);
|
|
3119
|
-
}
|
|
3120
|
-
}
|
|
3121
|
-
|
|
3122
3122
|
const isInputTextField = (field) => {
|
|
3123
3123
|
return field.controlType === ControlTypeEnum.Input && field.type === FieldTypeEnum.InputText;
|
|
3124
3124
|
};
|
|
@@ -6443,7 +6443,7 @@ class ReminderOption {
|
|
|
6443
6443
|
* Public API Surface of dynamic-form
|
|
6444
6444
|
*/
|
|
6445
6445
|
// ==========================================
|
|
6446
|
-
//
|
|
6446
|
+
// 0. BASE FIELD MODELS (CẦN ĐƯỢC EXPORT TRƯỚC ĐỂ TRÁNH LỖI CIRCULAR DEPENDENCY CLASS EXTENDS UNDEFINED)
|
|
6447
6447
|
// ==========================================
|
|
6448
6448
|
|
|
6449
6449
|
/**
|