@ldquocc/dynamic-form 0.0.4 → 0.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.
|
@@ -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';
|
|
1
3
|
import * as i1 from '@angular/forms';
|
|
2
4
|
import { FormsModule, ReactiveFormsModule, FormControl, Validators, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
3
5
|
import { of, delay, Subject, takeUntil, finalize, Observable, debounceTime, distinctUntilChanged } from 'rxjs';
|
|
4
6
|
import * as i1$2 from '@angular/common';
|
|
5
7
|
import { CommonModule, CurrencyPipe } from '@angular/common';
|
|
6
8
|
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,6 +42,14 @@ 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
|
+
|
|
45
53
|
// Core Angular modules (cần thiết ở hầu hết các component).
|
|
46
54
|
const CORE_MODULES = [CommonModule];
|
|
47
55
|
// Form handling (thường dùng với Reactive)
|
|
@@ -560,241 +568,6 @@ class DateRangeField extends BaseDateField {
|
|
|
560
568
|
}
|
|
561
569
|
}
|
|
562
570
|
|
|
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
|
-
|
|
798
571
|
/**
|
|
799
572
|
* Interface base chung cho Các dạng Input Field.
|
|
800
573
|
*/
|
|
@@ -2925,29 +2698,149 @@ const maxFileSizeInMBValidator = (maxSizeInMB) => {
|
|
|
2925
2698
|
return null;
|
|
2926
2699
|
};
|
|
2927
2700
|
};
|
|
2928
|
-
const reminderCustomRequiredValidator = () => {
|
|
2929
|
-
return (control) => {
|
|
2930
|
-
const reminderValue = control?.value;
|
|
2931
|
-
if (!reminderValue) {
|
|
2932
|
-
return {
|
|
2933
|
-
reminderCustomRequired: {
|
|
2934
|
-
requiredValue: `Giá trị radio và cả từ select hoặc date`,
|
|
2935
|
-
},
|
|
2936
|
-
};
|
|
2937
|
-
}
|
|
2938
|
-
if (reminderValue) {
|
|
2939
|
-
const { reminderDate } = reminderValue;
|
|
2940
|
-
if (!reminderDate) {
|
|
2941
|
-
return {
|
|
2942
|
-
reminderCustomRequired: {
|
|
2943
|
-
actualValue: reminderDate,
|
|
2944
|
-
requiredValue: `Giá trị từ select hoặc date`,
|
|
2945
|
-
},
|
|
2946
|
-
};
|
|
2947
|
-
}
|
|
2948
|
-
}
|
|
2949
|
-
return null;
|
|
2950
|
-
};
|
|
2701
|
+
const reminderCustomRequiredValidator = () => {
|
|
2702
|
+
return (control) => {
|
|
2703
|
+
const reminderValue = control?.value;
|
|
2704
|
+
if (!reminderValue) {
|
|
2705
|
+
return {
|
|
2706
|
+
reminderCustomRequired: {
|
|
2707
|
+
requiredValue: `Giá trị radio và cả từ select hoặc date`,
|
|
2708
|
+
},
|
|
2709
|
+
};
|
|
2710
|
+
}
|
|
2711
|
+
if (reminderValue) {
|
|
2712
|
+
const { reminderDate } = reminderValue;
|
|
2713
|
+
if (!reminderDate) {
|
|
2714
|
+
return {
|
|
2715
|
+
reminderCustomRequired: {
|
|
2716
|
+
actualValue: reminderDate,
|
|
2717
|
+
requiredValue: `Giá trị từ select hoặc date`,
|
|
2718
|
+
},
|
|
2719
|
+
};
|
|
2720
|
+
}
|
|
2721
|
+
}
|
|
2722
|
+
return null;
|
|
2723
|
+
};
|
|
2724
|
+
};
|
|
2725
|
+
|
|
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
|
+
}
|
|
2951
2844
|
};
|
|
2952
2845
|
|
|
2953
2846
|
const getDefaultPatternErrorMessage = (label, pattern) => {
|
|
@@ -2981,14 +2874,6 @@ const getLeadingSpaceErrorMessage = (label) => {
|
|
|
2981
2874
|
return `${label || 'Trường này'} không được bắt đầu bằng khoảng trắng`;
|
|
2982
2875
|
};
|
|
2983
2876
|
|
|
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
|
-
|
|
2992
2877
|
/**
|
|
2993
2878
|
* Abstract class chung cho Field.
|
|
2994
2879
|
*/
|
|
@@ -3043,23 +2928,119 @@ class BaseField {
|
|
|
3043
2928
|
}
|
|
3044
2929
|
}
|
|
3045
2930
|
|
|
3046
|
-
|
|
3047
|
-
|
|
2931
|
+
const DEFAULT_INPUT_VALUE = '';
|
|
2932
|
+
/**
|
|
2933
|
+
* Interface base chung cho Các dạng Input Field.
|
|
2934
|
+
*/
|
|
2935
|
+
class InputBaseField extends BaseField {
|
|
3048
2936
|
constructor(init) {
|
|
3049
|
-
|
|
3050
|
-
|
|
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 {
|
|
3000
|
+
constructor(init) {
|
|
3001
|
+
super(init);
|
|
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;
|
|
3051
3006
|
Object.assign(this, init);
|
|
3052
3007
|
}
|
|
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
|
+
}
|
|
3053
3014
|
}
|
|
3054
|
-
|
|
3055
|
-
|
|
3015
|
+
|
|
3016
|
+
/**
|
|
3017
|
+
* Interface của Input Field type là Password.
|
|
3018
|
+
*/
|
|
3019
|
+
class InputPasswordField extends InputBaseField {
|
|
3056
3020
|
constructor(init) {
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3021
|
+
super(init);
|
|
3022
|
+
/**
|
|
3023
|
+
* Gán giá trị cho các props cần giá trị mặc định ở Input Password.
|
|
3024
|
+
*/
|
|
3025
|
+
this.type = FieldTypeEnum.InputPassword;
|
|
3061
3026
|
Object.assign(this, init);
|
|
3062
3027
|
}
|
|
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
|
+
}
|
|
3063
3044
|
}
|
|
3064
3045
|
|
|
3065
3046
|
const buildForm = (fields, mode, model) => {
|
|
@@ -3119,6 +3100,25 @@ const createSelectPlaceholder = (field) => {
|
|
|
3119
3100
|
return `Nhập ${field.key?.toLowerCase()}`;
|
|
3120
3101
|
};
|
|
3121
3102
|
|
|
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
|
};
|
|
@@ -6398,57 +6398,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
|
|
|
6398
6398
|
type: Output
|
|
6399
6399
|
}] } });
|
|
6400
6400
|
|
|
6401
|
-
var TableCellTypeEnum;
|
|
6402
|
-
(function (TableCellTypeEnum) {
|
|
6403
|
-
TableCellTypeEnum["ACTION"] = "action";
|
|
6404
|
-
TableCellTypeEnum["CHECK"] = "check";
|
|
6405
|
-
TableCellTypeEnum["SUBTEXT"] = "subtext";
|
|
6406
|
-
TableCellTypeEnum["IMAGE"] = "image";
|
|
6407
|
-
TableCellTypeEnum["BADGE"] = "badge";
|
|
6408
|
-
TableCellTypeEnum["INDEX"] = "index";
|
|
6409
|
-
TableCellTypeEnum["TEXT"] = "text";
|
|
6410
|
-
TableCellTypeEnum["ICON_TEXT"] = "icon-text";
|
|
6411
|
-
TableCellTypeEnum["SWAP_FUNC"] = "swap";
|
|
6412
|
-
TableCellTypeEnum["EMPTY"] = "empty";
|
|
6413
|
-
})(TableCellTypeEnum || (TableCellTypeEnum = {}));
|
|
6414
|
-
|
|
6415
|
-
// Loại select.
|
|
6416
|
-
class SelectOption {
|
|
6417
|
-
constructor(init) {
|
|
6418
|
-
this.options = [];
|
|
6419
|
-
Object.assign(this, init);
|
|
6420
|
-
}
|
|
6421
|
-
}
|
|
6422
|
-
// Loại date.
|
|
6423
|
-
class DateOptions {
|
|
6424
|
-
constructor(init) {
|
|
6425
|
-
Object.assign(this, init);
|
|
6426
|
-
}
|
|
6427
|
-
}
|
|
6428
|
-
// Gom detail vào chung ReminderOption
|
|
6429
|
-
class ReminderOption {
|
|
6430
|
-
constructor(init) {
|
|
6431
|
-
Object.assign(this, init);
|
|
6432
|
-
// Nếu cần tự động khởi tạo detail theo type
|
|
6433
|
-
if (this.type === 'select' && !(this.detail instanceof SelectOption)) {
|
|
6434
|
-
this.detail = new SelectOption(this.detail);
|
|
6435
|
-
}
|
|
6436
|
-
if (this.type === 'date' && !(this.detail instanceof DateOptions)) {
|
|
6437
|
-
this.detail = new DateOptions(this.detail);
|
|
6438
|
-
}
|
|
6439
|
-
}
|
|
6440
|
-
}
|
|
6441
|
-
|
|
6442
6401
|
/*
|
|
6443
6402
|
* Public API Surface of dynamic-form
|
|
6403
|
+
* v0.0.5 - TEST: Comment het model exports de verify loi bundle circular dependency
|
|
6444
6404
|
*/
|
|
6445
6405
|
// ==========================================
|
|
6446
|
-
//
|
|
6406
|
+
// 1. MODULE & COMPONENT & SERVICE CHINH
|
|
6407
|
+
// ==========================================
|
|
6408
|
+
// ==========================================
|
|
6409
|
+
// 4-6. MODELS - COMMENTED FOR v0.0.5 TEST
|
|
6447
6410
|
// ==========================================
|
|
6411
|
+
// export * from "./lib/shared/models/common/index";
|
|
6412
|
+
// export * from "./lib/shared/models/common/table-models";
|
|
6413
|
+
// export * from "./lib/shared/models/fields/field.model";
|
|
6414
|
+
// export * from "./lib/shared/models/fields/field-grid.model";
|
|
6415
|
+
// export * from "./lib/shared/models/fields/field-group.model";
|
|
6416
|
+
// export * from "./lib/shared/models/fields/index.model";
|
|
6417
|
+
// export * from "./lib/shared/models/fields/input/index";
|
|
6418
|
+
// export * from "./lib/shared/models/fields/textarea/textarea-field.model";
|
|
6419
|
+
// export * from "./lib/shared/models/fields/date/index";
|
|
6420
|
+
// export * from "./lib/shared/models/fields/select/select-base-field.model";
|
|
6421
|
+
// export * from "./lib/shared/models/fields/select/single-select-field.model";
|
|
6422
|
+
// export * from "./lib/shared/models/fields/select/multi-select-field.model";
|
|
6423
|
+
// export * from "./lib/shared/models/fields/select/tree-select-field.model";
|
|
6424
|
+
// export * from "./lib/shared/models/fields/upload/index";
|
|
6425
|
+
// export * from "./lib/shared/models/fields/radio/radio-base-field.model";
|
|
6426
|
+
// export * from "./lib/shared/models/fields/radio/custom/reminder-type-radio/reminder-type-radio-field.model";
|
|
6427
|
+
// export * from "./lib/shared/models/fields/radio/custom/reminder-type-radio/reminder-value.model";
|
|
6428
|
+
// export * from "./lib/shared/models/fields/radio/custom/reminder-type-radio/reminder-option.model";
|
|
6429
|
+
// export * from "./lib/shared/models/fields/radio/custom/reminder-type-radio/reminder-type.model";
|
|
6448
6430
|
|
|
6449
6431
|
/**
|
|
6450
6432
|
* Generated bundle index. Do not edit.
|
|
6451
6433
|
*/
|
|
6452
6434
|
|
|
6453
|
-
export {
|
|
6435
|
+
export { CombineDependTypeEnum, CommonValidaterEnum, ControlTypeEnum, CustomValidaterEnum, DYNAMIC_FORM_CONFIG, DateFieldTypeEnum, DatePickerOutputValueTypeEnum, DateRangeOutputValueTypeEnum, DependTypeEnum, DynamicFormComponent, DynamicFormService, FieldTypeEnum, FileSizeTypeEnum, FormConfigService, FormDataService, FormModeEnum, InputFieldTypeEnum, SelectFieldTypeEnum, SelectOutputValueTypeEnum, UploadFieldTypeEnum, UploadOutputValueTypeEnum, ViewModeEnum };
|
|
6454
6436
|
//# sourceMappingURL=ldquocc-dynamic-form.mjs.map
|