@bsachref/ng-form 1.0.2
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/LICENSE +21 -0
- package/README.md +143 -0
- package/app/default-forms/default-forms.component.d.ts +22 -0
- package/app/file-upload-accessor.directive.d.ts +13 -0
- package/app/formControlConfig.d.ts +203 -0
- package/app/material-form/material-form.component.d.ts +19 -0
- package/app/prime-form/prime-form.component.d.ts +23 -0
- package/app/validation-messages/validation-messages.component.d.ts +12 -0
- package/esm2022/app/default-forms/default-forms.component.mjs +163 -0
- package/esm2022/app/file-upload-accessor.directive.mjs +52 -0
- package/esm2022/app/formControlConfig.mjs +2 -0
- package/esm2022/app/material-form/material-form.component.mjs +176 -0
- package/esm2022/app/prime-form/prime-form.component.mjs +210 -0
- package/esm2022/app/validation-messages/validation-messages.component.mjs +29 -0
- package/esm2022/bsachref-ng-form.mjs +5 -0
- package/esm2022/public-api.mjs +5 -0
- package/fesm2022/bsachref-ng-form.mjs +615 -0
- package/fesm2022/bsachref-ng-form.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/package.json +62 -0
- package/public-api.d.ts +4 -0
@@ -0,0 +1,615 @@
|
|
1
|
+
import * as i2 from '@angular/common';
|
2
|
+
import { CommonModule } from '@angular/common';
|
3
|
+
import * as i0 from '@angular/core';
|
4
|
+
import { Component, Input, input, output, ChangeDetectionStrategy, forwardRef, Directive } from '@angular/core';
|
5
|
+
import * as i1 from '@angular/forms';
|
6
|
+
import { Validators, ReactiveFormsModule, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
7
|
+
import { BehaviorSubject } from 'rxjs';
|
8
|
+
import * as i3 from '@angular/material/input';
|
9
|
+
import { MatInputModule } from '@angular/material/input';
|
10
|
+
import * as i5 from '@angular/material/select';
|
11
|
+
import { MatSelectModule } from '@angular/material/select';
|
12
|
+
import * as i7 from '@angular/material/checkbox';
|
13
|
+
import { MatCheckboxModule } from '@angular/material/checkbox';
|
14
|
+
import * as i8 from '@angular/material/radio';
|
15
|
+
import { MatRadioModule } from '@angular/material/radio';
|
16
|
+
import * as i9 from '@angular/material/button';
|
17
|
+
import { MatButtonModule } from '@angular/material/button';
|
18
|
+
import * as i10 from '@angular/material/datepicker';
|
19
|
+
import { MatDatepickerModule } from '@angular/material/datepicker';
|
20
|
+
import * as i4 from '@angular/material/form-field';
|
21
|
+
import { MatFormFieldModule } from '@angular/material/form-field';
|
22
|
+
import * as i6 from '@angular/material/core';
|
23
|
+
import { provideNativeDateAdapter } from '@angular/material/core';
|
24
|
+
import * as i3$1 from 'primeng/inputtext';
|
25
|
+
import { InputTextModule } from 'primeng/inputtext';
|
26
|
+
import * as i4$1 from 'primeng/multiselect';
|
27
|
+
import { MultiSelectModule } from 'primeng/multiselect';
|
28
|
+
import * as i5$1 from 'primeng/textarea';
|
29
|
+
import { TextareaModule } from 'primeng/textarea';
|
30
|
+
import * as i6$1 from 'primeng/checkbox';
|
31
|
+
import { CheckboxModule } from 'primeng/checkbox';
|
32
|
+
import * as i7$1 from 'primeng/radiobutton';
|
33
|
+
import { RadioButtonModule } from 'primeng/radiobutton';
|
34
|
+
import * as i9$1 from 'primeng/togglebutton';
|
35
|
+
import { ToggleButtonModule } from 'primeng/togglebutton';
|
36
|
+
import * as i1$1 from 'primeng/fileupload';
|
37
|
+
import { FileUploadModule } from 'primeng/fileupload';
|
38
|
+
import * as i10$1 from 'primeng/slider';
|
39
|
+
import { SliderModule } from 'primeng/slider';
|
40
|
+
import * as i11 from 'primeng/button';
|
41
|
+
import { ButtonModule } from 'primeng/button';
|
42
|
+
import * as i8$1 from 'primeng/datepicker';
|
43
|
+
import { DatePickerModule } from 'primeng/datepicker';
|
44
|
+
import * as i12 from 'primeng/select';
|
45
|
+
import { SelectModule } from 'primeng/select';
|
46
|
+
|
47
|
+
class ValidationMessagesComponent {
|
48
|
+
control; // The form control to validate
|
49
|
+
controlName; // The name of the control (for displaying in messages)
|
50
|
+
config; // The configuration for the control
|
51
|
+
getValidatorValue(validatorName, key) {
|
52
|
+
return this.control?.errors?.[validatorName]?.[key];
|
53
|
+
}
|
54
|
+
getCustomErrorMessage() {
|
55
|
+
if (this.control?.errors?.['custom']) {
|
56
|
+
return this.control.errors['custom'].message ?? 'Invalid input';
|
57
|
+
}
|
58
|
+
return null;
|
59
|
+
}
|
60
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ValidationMessagesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
61
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ValidationMessagesComponent, isStandalone: true, selector: "validation-messages", inputs: { control: "control", controlName: "controlName", config: "config" }, ngImport: i0, template: "@if (control?.invalid && control?.touched) {\n <section class=\"error-messages\" style=\"color: red\">\n @if (control?.errors?.[\"required\"]) {\n <small>{{ controlName }} is required</small>\n }\n @if (control?.errors?.[\"minlength\"]) {\n <small\n >Minimum length:\n {{ getValidatorValue(\"minlength\", \"requiredLength\") }}</small\n >\n }\n @if (control?.errors?.[\"maxlength\"]) {\n <small\n >Maximum length:\n {{ getValidatorValue(\"maxlength\", \"requiredLength\") }}</small\n >\n }\n @if (control?.errors?.[\"pattern\"]) {\n <small>Invalid format</small>\n }\n @if (control?.errors?.[\"email\"]) {\n <small>Invalid email address</small>\n }\n @if (control?.errors?.[\"min\"]) {\n <small\n >Value must be at least {{ getValidatorValue(\"min\", \"min\") }}</small\n >\n }\n @if (control?.errors?.[\"max\"]) {\n <small>Value must not exceed {{ getValidatorValue(\"max\", \"max\") }}</small>\n }\n @if (control?.errors?.[\"custom\"]) {\n <small>{{ getCustomErrorMessage() }}</small>\n }\n </section>\n}\n", styles: [""] });
|
62
|
+
}
|
63
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ValidationMessagesComponent, decorators: [{
|
64
|
+
type: Component,
|
65
|
+
args: [{ selector: 'validation-messages', standalone: true, imports: [], template: "@if (control?.invalid && control?.touched) {\n <section class=\"error-messages\" style=\"color: red\">\n @if (control?.errors?.[\"required\"]) {\n <small>{{ controlName }} is required</small>\n }\n @if (control?.errors?.[\"minlength\"]) {\n <small\n >Minimum length:\n {{ getValidatorValue(\"minlength\", \"requiredLength\") }}</small\n >\n }\n @if (control?.errors?.[\"maxlength\"]) {\n <small\n >Maximum length:\n {{ getValidatorValue(\"maxlength\", \"requiredLength\") }}</small\n >\n }\n @if (control?.errors?.[\"pattern\"]) {\n <small>Invalid format</small>\n }\n @if (control?.errors?.[\"email\"]) {\n <small>Invalid email address</small>\n }\n @if (control?.errors?.[\"min\"]) {\n <small\n >Value must be at least {{ getValidatorValue(\"min\", \"min\") }}</small\n >\n }\n @if (control?.errors?.[\"max\"]) {\n <small>Value must not exceed {{ getValidatorValue(\"max\", \"max\") }}</small>\n }\n @if (control?.errors?.[\"custom\"]) {\n <small>{{ getCustomErrorMessage() }}</small>\n }\n </section>\n}\n" }]
|
66
|
+
}], propDecorators: { control: [{
|
67
|
+
type: Input
|
68
|
+
}], controlName: [{
|
69
|
+
type: Input
|
70
|
+
}], config: [{
|
71
|
+
type: Input
|
72
|
+
}] } });
|
73
|
+
|
74
|
+
/**
|
75
|
+
* @component DefaultFormsComponent
|
76
|
+
* @description
|
77
|
+
* The `DefaultFormsComponent` is an Angular standalone component that provides a dynamic form generation
|
78
|
+
* based on the provided configuration. It uses reactive forms to handle form controls and their validations.
|
79
|
+
* The component is designed to be highly configurable and supports various types of form validators.
|
80
|
+
*
|
81
|
+
* @selector default-forms
|
82
|
+
* @standalone true
|
83
|
+
* @imports
|
84
|
+
* - ReactiveFormsModule
|
85
|
+
* - CommonModule
|
86
|
+
* - FormsModule
|
87
|
+
* - ValidationMessagesComponent
|
88
|
+
* @templateUrl ./default-forms.component.html
|
89
|
+
* @styleUrl ./default-forms.component.css
|
90
|
+
* @changeDetection ChangeDetectionStrategy.OnPush
|
91
|
+
*
|
92
|
+
* @input
|
93
|
+
* - `formName: string` - The name of the form.
|
94
|
+
* - `controls: FormControlConfig[]` - An array of form control configurations.
|
95
|
+
*
|
96
|
+
* @output
|
97
|
+
* - `formSubmit: EventEmitter<Record<string, any>>` - Emits the form value when the form is submitted.
|
98
|
+
*
|
99
|
+
* @class DefaultFormsComponent
|
100
|
+
* @implements OnInit
|
101
|
+
*
|
102
|
+
* @property {string} formName - The name of the form.
|
103
|
+
* @property {FormControlConfig[]} controls - The configuration for the form controls.
|
104
|
+
* @property {EventEmitter<Record<string, any>>} formSubmit - Event emitter for form submission.
|
105
|
+
* @property {FormGroup} form - The reactive form group instance.
|
106
|
+
* @property {BehaviorSubject<boolean>} formChanges$ - A subject to track form changes.
|
107
|
+
*
|
108
|
+
* @constructor
|
109
|
+
* @param {FormBuilder} fb - Angular's FormBuilder service to create form controls.
|
110
|
+
* @param {ChangeDetectorRef} cdr - Angular's ChangeDetectorRef service to manually trigger change detection.
|
111
|
+
*
|
112
|
+
* @method ngOnInit
|
113
|
+
* @description Lifecycle hook that is called after the component's view has been initialized. It initializes the form.
|
114
|
+
*
|
115
|
+
* @method initializeForm
|
116
|
+
* @description Initializes the form by creating form controls based on the provided configuration and sets up value change subscriptions.
|
117
|
+
*
|
118
|
+
* @method getValidators
|
119
|
+
* @param {FormControlConfig} control - The configuration for a form control.
|
120
|
+
* @returns {ValidatorFn[]} An array of validators for the form control.
|
121
|
+
* @description Generates an array of validators based on the provided control configuration.
|
122
|
+
*
|
123
|
+
* @method updateValidators
|
124
|
+
* @param {AbstractControl} control - The form control to update validators for.
|
125
|
+
* @param {any} value - The current value of the form control.
|
126
|
+
* @description Updates the validators for a form control based on its current value.
|
127
|
+
*
|
128
|
+
* @method shouldRequireValidation
|
129
|
+
* @param {any} value - The value to check for validation requirement.
|
130
|
+
* @returns {boolean} Whether the value requires validation.
|
131
|
+
* @description Determines if a value should require validation.
|
132
|
+
*
|
133
|
+
* @method onSubmit
|
134
|
+
* @description Handles the form submission. Marks the form as touched and dirty, validates the form, emits the form value if valid, and resets the form.
|
135
|
+
*/
|
136
|
+
class DefaultFormsComponent {
|
137
|
+
fb;
|
138
|
+
cdr;
|
139
|
+
formName = input.required();
|
140
|
+
controls = input.required();
|
141
|
+
formSubmit = output();
|
142
|
+
form;
|
143
|
+
formChanges$ = new BehaviorSubject(false);
|
144
|
+
constructor(fb, cdr) {
|
145
|
+
this.fb = fb;
|
146
|
+
this.cdr = cdr;
|
147
|
+
}
|
148
|
+
ngOnInit() {
|
149
|
+
this.initializeForm();
|
150
|
+
}
|
151
|
+
initializeForm() {
|
152
|
+
const formControls = {};
|
153
|
+
this.controls().forEach((control) => {
|
154
|
+
formControls[control.name] = [
|
155
|
+
control.value ?? '',
|
156
|
+
this.getValidators(control),
|
157
|
+
];
|
158
|
+
});
|
159
|
+
this.form = this.fb.group(formControls);
|
160
|
+
this.controls().forEach((control) => {
|
161
|
+
const formControl = this.form.get(control.name);
|
162
|
+
if (formControl) {
|
163
|
+
formControl.valueChanges.subscribe((value) => {
|
164
|
+
this.updateValidators(formControl, value);
|
165
|
+
});
|
166
|
+
}
|
167
|
+
});
|
168
|
+
this.formChanges$.subscribe(() => this.cdr.markForCheck());
|
169
|
+
}
|
170
|
+
getValidators(control) {
|
171
|
+
const validators = [];
|
172
|
+
if (control.validators) {
|
173
|
+
control.validators.forEach((validator) => {
|
174
|
+
if (validator.required)
|
175
|
+
validators.push(Validators.required);
|
176
|
+
if (validator.minlength)
|
177
|
+
validators.push(Validators.minLength(validator.minlength));
|
178
|
+
if (validator.maxlength)
|
179
|
+
validators.push(Validators.maxLength(validator.maxlength));
|
180
|
+
if (validator.pattern)
|
181
|
+
validators.push(Validators.pattern(validator.pattern));
|
182
|
+
if (validator.email)
|
183
|
+
validators.push(Validators.email);
|
184
|
+
if (validator.custom)
|
185
|
+
validators.push(validator.custom);
|
186
|
+
});
|
187
|
+
}
|
188
|
+
return validators;
|
189
|
+
}
|
190
|
+
updateValidators(control, value) {
|
191
|
+
if (this.shouldRequireValidation(value)) {
|
192
|
+
control.addValidators(Validators.required);
|
193
|
+
}
|
194
|
+
else {
|
195
|
+
control.removeValidators(Validators.required);
|
196
|
+
}
|
197
|
+
control.updateValueAndValidity();
|
198
|
+
this.formChanges$.next(true);
|
199
|
+
}
|
200
|
+
shouldRequireValidation(value) {
|
201
|
+
return value !== null && value !== '';
|
202
|
+
}
|
203
|
+
onSubmit() {
|
204
|
+
this.form.markAllAsTouched();
|
205
|
+
this.form.markAsDirty();
|
206
|
+
this.form.updateValueAndValidity();
|
207
|
+
if (this.form.valid) {
|
208
|
+
this.formSubmit.emit(this.form.value);
|
209
|
+
this.form.reset();
|
210
|
+
}
|
211
|
+
else {
|
212
|
+
console.error('Form Invalid');
|
213
|
+
}
|
214
|
+
this.formChanges$.next(true);
|
215
|
+
}
|
216
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DefaultFormsComponent, deps: [{ token: i1.FormBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
217
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: DefaultFormsComponent, isStandalone: true, selector: "default-forms", inputs: { formName: { classPropertyName: "formName", publicName: "formName", isSignal: true, isRequired: true, transformFunction: null }, controls: { classPropertyName: "controls", publicName: "controls", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { formSubmit: "formSubmit" }, ngImport: i0, template: "<form [formGroup]=\"form\" [attr.name]=\"formName()\" (ngSubmit)=\"onSubmit()\">\n @for (control of controls(); track $index) {\n @if (control.uiFramework === \"default\" || !control.uiFramework) {\n @if (form.get(control.name)) {\n <section [ngClass]=\"control.class\" [ngStyle]=\"control.style\">\n @if (control.label) {\n <label\n [attr.for]=\"control.name\"\n [ngClass]=\"control.labelClass\"\n [ngStyle]=\"control.labelStyle\"\n >\n {{ control.label }}\n </label>\n }\n\n @if (control.type === \"input\") {\n <input\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n type=\"text\"\n />\n }\n @if (control.type === \"select\") {\n <select [formControlName]=\"control.name\" [id]=\"control.name\">\n @for (option of control.options; track $index) {\n <option [value]=\"option\">{{ option }}</option>\n }\n </select>\n }\n @if (control.type === \"textarea\") {\n <textarea\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n ></textarea>\n }\n @if (control.type === \"checkbox\") {\n <input\n type=\"checkbox\"\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n />\n }\n @if (control.type === \"radio\") {\n @for (option of control.options ?? []; track $index) {\n <div>\n <input\n type=\"radio\"\n [formControlName]=\"control.name\"\n [id]=\"control.name + '-' + option\"\n [value]=\"option\"\n />\n <label [for]=\"control.name + '-' + option\">{{ option }}</label>\n </div>\n }\n }\n\n <validation-messages\n [control]=\"form.get(control.name)\"\n [controlName]=\"control.name\"\n [config]=\"control\"\n ></validation-messages>\n </section>\n }\n }\n }\n <button type=\"submit\" [disabled]=\"form.invalid\">Submit</button>\n</form>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: ValidationMessagesComponent, selector: "validation-messages", inputs: ["control", "controlName", "config"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
218
|
+
}
|
219
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DefaultFormsComponent, decorators: [{
|
220
|
+
type: Component,
|
221
|
+
args: [{ selector: 'default-forms', standalone: true, imports: [
|
222
|
+
ReactiveFormsModule,
|
223
|
+
CommonModule,
|
224
|
+
FormsModule,
|
225
|
+
ValidationMessagesComponent,
|
226
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<form [formGroup]=\"form\" [attr.name]=\"formName()\" (ngSubmit)=\"onSubmit()\">\n @for (control of controls(); track $index) {\n @if (control.uiFramework === \"default\" || !control.uiFramework) {\n @if (form.get(control.name)) {\n <section [ngClass]=\"control.class\" [ngStyle]=\"control.style\">\n @if (control.label) {\n <label\n [attr.for]=\"control.name\"\n [ngClass]=\"control.labelClass\"\n [ngStyle]=\"control.labelStyle\"\n >\n {{ control.label }}\n </label>\n }\n\n @if (control.type === \"input\") {\n <input\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n type=\"text\"\n />\n }\n @if (control.type === \"select\") {\n <select [formControlName]=\"control.name\" [id]=\"control.name\">\n @for (option of control.options; track $index) {\n <option [value]=\"option\">{{ option }}</option>\n }\n </select>\n }\n @if (control.type === \"textarea\") {\n <textarea\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n ></textarea>\n }\n @if (control.type === \"checkbox\") {\n <input\n type=\"checkbox\"\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n />\n }\n @if (control.type === \"radio\") {\n @for (option of control.options ?? []; track $index) {\n <div>\n <input\n type=\"radio\"\n [formControlName]=\"control.name\"\n [id]=\"control.name + '-' + option\"\n [value]=\"option\"\n />\n <label [for]=\"control.name + '-' + option\">{{ option }}</label>\n </div>\n }\n }\n\n <validation-messages\n [control]=\"form.get(control.name)\"\n [controlName]=\"control.name\"\n [config]=\"control\"\n ></validation-messages>\n </section>\n }\n }\n }\n <button type=\"submit\" [disabled]=\"form.invalid\">Submit</button>\n</form>\n" }]
|
227
|
+
}], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i0.ChangeDetectorRef }] });
|
228
|
+
|
229
|
+
/**
|
230
|
+
* @component
|
231
|
+
* @name MaterialFormsComponent
|
232
|
+
* @description
|
233
|
+
* A standalone Angular component that renders a dynamic form using Angular Material components.
|
234
|
+
* The form configuration is provided via inputs, and the form submission is handled via an output event.
|
235
|
+
*
|
236
|
+
* @selector material-forms
|
237
|
+
* @standalone true
|
238
|
+
* @imports
|
239
|
+
* - CommonModule
|
240
|
+
* - ReactiveFormsModule
|
241
|
+
* - MatInputModule
|
242
|
+
* - MatSelectModule
|
243
|
+
* - MatCheckboxModule
|
244
|
+
* - MatRadioModule
|
245
|
+
* - MatButtonModule
|
246
|
+
* - ValidationMessagesComponent
|
247
|
+
* - MatDatepickerModule
|
248
|
+
* - MatFormFieldModule
|
249
|
+
* @providers provideNativeDateAdapter
|
250
|
+
* @templateUrl ./material-form.component.html
|
251
|
+
* @styleUrl ./material-form.component.css
|
252
|
+
* @changeDetection ChangeDetectionStrategy.OnPush
|
253
|
+
*
|
254
|
+
* @inputs
|
255
|
+
* @property {string} formName - The name of the form.
|
256
|
+
* @property {FormControlConfig[]} controls - The configuration for the form controls.
|
257
|
+
*
|
258
|
+
* @outputs
|
259
|
+
* @property {EventEmitter<Record<string, any>>} formSubmit - Event emitted when the form is submitted.
|
260
|
+
*
|
261
|
+
* @class
|
262
|
+
* @name MaterialFormsComponent
|
263
|
+
* @description
|
264
|
+
* This class defines the MaterialFormsComponent which initializes the form based on the provided controls configuration,
|
265
|
+
* handles form submission, and provides validation for the form controls.
|
266
|
+
*
|
267
|
+
* @constructor
|
268
|
+
* @param {FormBuilder} fb - Angular FormBuilder service to create form groups and controls.
|
269
|
+
* @param {ChangeDetectorRef} cdr - Angular ChangeDetectorRef service to manually trigger change detection.
|
270
|
+
*
|
271
|
+
* @method
|
272
|
+
* @name ngOnInit
|
273
|
+
* @description
|
274
|
+
* Lifecycle hook that is called after the component's view has been initialized. It initializes the form.
|
275
|
+
*
|
276
|
+
* @method
|
277
|
+
* @name initializeForm
|
278
|
+
* @description
|
279
|
+
* Initializes the form controls based on the provided configuration. Supports datepicker range controls.
|
280
|
+
*
|
281
|
+
* @method
|
282
|
+
* @name getValidators
|
283
|
+
* @description
|
284
|
+
* Returns an array of Angular validators based on the provided control configuration.
|
285
|
+
* @param {FormControlConfig} control - The configuration for the form control.
|
286
|
+
* @returns {Validators[]} - An array of Angular validators.
|
287
|
+
*
|
288
|
+
* @method
|
289
|
+
* @name onSubmit
|
290
|
+
* @description
|
291
|
+
* Handles the form submission. Marks all controls as touched and dirty, updates the form's validity,
|
292
|
+
* emits the form values if the form is valid, and resets the form. Triggers change detection.
|
293
|
+
*/
|
294
|
+
class MaterialFormsComponent {
|
295
|
+
fb;
|
296
|
+
cdr;
|
297
|
+
formName = input.required();
|
298
|
+
controls = input.required();
|
299
|
+
formSubmit = output();
|
300
|
+
form;
|
301
|
+
constructor(fb, cdr) {
|
302
|
+
this.fb = fb;
|
303
|
+
this.cdr = cdr;
|
304
|
+
}
|
305
|
+
ngOnInit() {
|
306
|
+
this.initializeForm();
|
307
|
+
}
|
308
|
+
initializeForm() {
|
309
|
+
const formControls = {};
|
310
|
+
this.controls().forEach((control) => {
|
311
|
+
if (control.type === 'datepicker' && control.datePickerMode === 'range') {
|
312
|
+
formControls[`${control.name}_Start`] = [
|
313
|
+
control.value?.start ?? '',
|
314
|
+
this.getValidators(control),
|
315
|
+
];
|
316
|
+
formControls[`${control.name}_End`] = [
|
317
|
+
control.value?.end ?? '',
|
318
|
+
this.getValidators(control),
|
319
|
+
];
|
320
|
+
}
|
321
|
+
else {
|
322
|
+
formControls[control.name] = [
|
323
|
+
control.value ?? '',
|
324
|
+
this.getValidators(control),
|
325
|
+
];
|
326
|
+
}
|
327
|
+
});
|
328
|
+
this.form = this.fb.group(formControls);
|
329
|
+
}
|
330
|
+
getValidators(control) {
|
331
|
+
const validators = [];
|
332
|
+
if (control.validators) {
|
333
|
+
control.validators.forEach((validator) => {
|
334
|
+
if (validator.required)
|
335
|
+
validators.push(Validators.required);
|
336
|
+
if (validator.minlength)
|
337
|
+
validators.push(Validators.minLength(validator.minlength));
|
338
|
+
if (validator.maxlength)
|
339
|
+
validators.push(Validators.maxLength(validator.maxlength));
|
340
|
+
if (validator.pattern)
|
341
|
+
validators.push(Validators.pattern(validator.pattern));
|
342
|
+
if (validator.email)
|
343
|
+
validators.push(Validators.email);
|
344
|
+
if (validator.custom)
|
345
|
+
validators.push(validator.custom);
|
346
|
+
});
|
347
|
+
}
|
348
|
+
return validators;
|
349
|
+
}
|
350
|
+
onSubmit() {
|
351
|
+
this.form.markAllAsTouched();
|
352
|
+
this.form.markAsDirty();
|
353
|
+
this.form.updateValueAndValidity();
|
354
|
+
if (this.form.valid) {
|
355
|
+
this.formSubmit.emit(this.form.value);
|
356
|
+
this.form.reset();
|
357
|
+
}
|
358
|
+
else {
|
359
|
+
console.error('Form Invalid');
|
360
|
+
}
|
361
|
+
this.cdr.markForCheck();
|
362
|
+
}
|
363
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MaterialFormsComponent, deps: [{ token: i1.FormBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
364
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: MaterialFormsComponent, isStandalone: true, selector: "material-forms", inputs: { formName: { classPropertyName: "formName", publicName: "formName", isSignal: true, isRequired: true, transformFunction: null }, controls: { classPropertyName: "controls", publicName: "controls", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { formSubmit: "formSubmit" }, providers: [provideNativeDateAdapter()], ngImport: i0, template: "<form [formGroup]=\"form\" [attr.name]=\"formName()\" (ngSubmit)=\"onSubmit()\">\n @for (control of controls(); track $index) {\n @if (control.uiFramework === \"material\" || !control.uiFramework) {\n @if (form.get(control.name)) {\n <section [ngClass]=\"control.class\" [ngStyle]=\"control.style\">\n @if (control.type === \"input\") {\n <mat-form-field appearance=\"outline\">\n @if (control.label) {\n <mat-label>{{ control.label }}</mat-label>\n }\n <input\n matInput\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n type=\"text\"\n />\n </mat-form-field>\n }\n @if (control.type === \"select\") {\n <mat-form-field appearance=\"outline\">\n @if (control.label) {\n <mat-label>{{ control.label }}</mat-label>\n }\n <mat-select [formControlName]=\"control.name\" [id]=\"control.name\">\n @for (option of control.options ?? []; track $index) {\n <mat-option [value]=\"option\">{{ option }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n @if (control.type === \"checkbox\") {\n <mat-checkbox [formControlName]=\"control.name\" [id]=\"control.name\">\n {{ control.label }}\n </mat-checkbox>\n }\n @if (control.type === \"radio\") {\n @for (option of control.options ?? []; track $index) {\n <mat-radio-group [formControlName]=\"control.name\">\n <mat-radio-button\n [id]=\"control.name + '-' + option\"\n [value]=\"option\"\n >\n {{ option }}\n </mat-radio-button>\n </mat-radio-group>\n }\n }\n @if (control.type === \"datepicker\") {\n @if (control.datePickerMode === \"single\") {\n <mat-form-field appearance=\"outline\">\n <mat-label>Choose a date</mat-label>\n <input\n matInput\n [matDatepicker]=\"datepicker\"\n [formControlName]=\"control.name\"\n />\n <mat-datepicker-toggle\n matIconSuffix\n [for]=\"datepicker\"\n ></mat-datepicker-toggle>\n <mat-datepicker #datepicker></mat-datepicker>\n </mat-form-field>\n } @else if (control.datePickerMode === \"range\") {\n <mat-form-field>\n <mat-label>Enter a date range</mat-label>\n <mat-date-range-input\n [rangePicker]=\"picker\"\n [formGroup]=\"form\"\n ]\n >\n <input\n matStartDate\n formControlName=\"{{ control.name }}_Start\"\n placeholder=\"Start date\"\n />\n <input\n matEndDate\n formControlName=\"{{ control.name }}_End\"\n placeholder=\"End date\"\n />\n </mat-date-range-input>\n <mat-datepicker-toggle\n matIconSuffix\n [for]=\"picker\"\n ></mat-datepicker-toggle>\n <mat-date-range-picker #picker></mat-date-range-picker>\n\n <!-- @if (form.controls.start.hasError('matStartDateInvalid')) {\n <mat-error>Invalid start date</mat-error>\n }\n @if (form.controls.end.hasError('matEndDateInvalid')) {\n <mat-error>Invalid end date</mat-error>\n } -->\n </mat-form-field>\n }\n }\n\n <validation-messages\n [control]=\"form.get(control.name)\"\n [controlName]=\"control.name\"\n [config]=\"control\"\n ></validation-messages>\n </section>\n }\n }\n }\n <button\n mat-raised-button\n color=\"primary\"\n type=\"submit\"\n [disabled]=\"form.invalid\"\n >\n Submit\n </button>\n</form>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i3.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i7.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i8.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i8.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i9.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: ValidationMessagesComponent, selector: "validation-messages", inputs: ["control", "controlName", "config"] }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i10.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i10.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i10.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i10.MatDateRangeInput, selector: "mat-date-range-input", inputs: ["rangePicker", "required", "dateFilter", "min", "max", "disabled", "separator", "comparisonStart", "comparisonEnd"], exportAs: ["matDateRangeInput"] }, { kind: "directive", type: i10.MatStartDate, selector: "input[matStartDate]", outputs: ["dateChange", "dateInput"] }, { kind: "directive", type: i10.MatEndDate, selector: "input[matEndDate]", outputs: ["dateChange", "dateInput"] }, { kind: "component", type: i10.MatDateRangePicker, selector: "mat-date-range-picker", exportAs: ["matDateRangePicker"] }, { kind: "ngmodule", type: MatFormFieldModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
365
|
+
}
|
366
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MaterialFormsComponent, decorators: [{
|
367
|
+
type: Component,
|
368
|
+
args: [{ selector: 'material-forms', standalone: true, imports: [
|
369
|
+
CommonModule,
|
370
|
+
ReactiveFormsModule,
|
371
|
+
MatInputModule,
|
372
|
+
MatSelectModule,
|
373
|
+
MatCheckboxModule,
|
374
|
+
MatRadioModule,
|
375
|
+
MatButtonModule,
|
376
|
+
ValidationMessagesComponent,
|
377
|
+
MatDatepickerModule,
|
378
|
+
MatFormFieldModule,
|
379
|
+
], providers: [provideNativeDateAdapter()], changeDetection: ChangeDetectionStrategy.OnPush, template: "<form [formGroup]=\"form\" [attr.name]=\"formName()\" (ngSubmit)=\"onSubmit()\">\n @for (control of controls(); track $index) {\n @if (control.uiFramework === \"material\" || !control.uiFramework) {\n @if (form.get(control.name)) {\n <section [ngClass]=\"control.class\" [ngStyle]=\"control.style\">\n @if (control.type === \"input\") {\n <mat-form-field appearance=\"outline\">\n @if (control.label) {\n <mat-label>{{ control.label }}</mat-label>\n }\n <input\n matInput\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n type=\"text\"\n />\n </mat-form-field>\n }\n @if (control.type === \"select\") {\n <mat-form-field appearance=\"outline\">\n @if (control.label) {\n <mat-label>{{ control.label }}</mat-label>\n }\n <mat-select [formControlName]=\"control.name\" [id]=\"control.name\">\n @for (option of control.options ?? []; track $index) {\n <mat-option [value]=\"option\">{{ option }}</mat-option>\n }\n </mat-select>\n </mat-form-field>\n }\n @if (control.type === \"checkbox\") {\n <mat-checkbox [formControlName]=\"control.name\" [id]=\"control.name\">\n {{ control.label }}\n </mat-checkbox>\n }\n @if (control.type === \"radio\") {\n @for (option of control.options ?? []; track $index) {\n <mat-radio-group [formControlName]=\"control.name\">\n <mat-radio-button\n [id]=\"control.name + '-' + option\"\n [value]=\"option\"\n >\n {{ option }}\n </mat-radio-button>\n </mat-radio-group>\n }\n }\n @if (control.type === \"datepicker\") {\n @if (control.datePickerMode === \"single\") {\n <mat-form-field appearance=\"outline\">\n <mat-label>Choose a date</mat-label>\n <input\n matInput\n [matDatepicker]=\"datepicker\"\n [formControlName]=\"control.name\"\n />\n <mat-datepicker-toggle\n matIconSuffix\n [for]=\"datepicker\"\n ></mat-datepicker-toggle>\n <mat-datepicker #datepicker></mat-datepicker>\n </mat-form-field>\n } @else if (control.datePickerMode === \"range\") {\n <mat-form-field>\n <mat-label>Enter a date range</mat-label>\n <mat-date-range-input\n [rangePicker]=\"picker\"\n [formGroup]=\"form\"\n ]\n >\n <input\n matStartDate\n formControlName=\"{{ control.name }}_Start\"\n placeholder=\"Start date\"\n />\n <input\n matEndDate\n formControlName=\"{{ control.name }}_End\"\n placeholder=\"End date\"\n />\n </mat-date-range-input>\n <mat-datepicker-toggle\n matIconSuffix\n [for]=\"picker\"\n ></mat-datepicker-toggle>\n <mat-date-range-picker #picker></mat-date-range-picker>\n\n <!-- @if (form.controls.start.hasError('matStartDateInvalid')) {\n <mat-error>Invalid start date</mat-error>\n }\n @if (form.controls.end.hasError('matEndDateInvalid')) {\n <mat-error>Invalid end date</mat-error>\n } -->\n </mat-form-field>\n }\n }\n\n <validation-messages\n [control]=\"form.get(control.name)\"\n [controlName]=\"control.name\"\n [config]=\"control\"\n ></validation-messages>\n </section>\n }\n }\n }\n <button\n mat-raised-button\n color=\"primary\"\n type=\"submit\"\n [disabled]=\"form.invalid\"\n >\n Submit\n </button>\n</form>\n" }]
|
380
|
+
}], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i0.ChangeDetectorRef }] });
|
381
|
+
|
382
|
+
class FileUploadValueAccessor {
|
383
|
+
host;
|
384
|
+
constructor(host) {
|
385
|
+
this.host = host;
|
386
|
+
}
|
387
|
+
writeValue(value) {
|
388
|
+
if (value) {
|
389
|
+
this.host.files = value;
|
390
|
+
}
|
391
|
+
else {
|
392
|
+
this.host.clear();
|
393
|
+
}
|
394
|
+
}
|
395
|
+
registerOnChange(fn) {
|
396
|
+
this.host.onUpload.subscribe((event) => {
|
397
|
+
fn(event.files);
|
398
|
+
});
|
399
|
+
}
|
400
|
+
registerOnTouched(fn) {
|
401
|
+
// this.host.onBlur.subscribe(fn);
|
402
|
+
}
|
403
|
+
setDisabledState(isDisabled) {
|
404
|
+
this.host.disabled = isDisabled;
|
405
|
+
}
|
406
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FileUploadValueAccessor, deps: [{ token: i1$1.FileUpload }], target: i0.ɵɵFactoryTarget.Directive });
|
407
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: FileUploadValueAccessor, isStandalone: true, selector: "p-fileUpload[formControlName], p-fileUpload[formControl], p-fileUpload[ngModel]", providers: [
|
408
|
+
{
|
409
|
+
provide: NG_VALUE_ACCESSOR,
|
410
|
+
useExisting: forwardRef(() => FileUploadValueAccessor),
|
411
|
+
multi: true,
|
412
|
+
},
|
413
|
+
], ngImport: i0 });
|
414
|
+
}
|
415
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: FileUploadValueAccessor, decorators: [{
|
416
|
+
type: Directive,
|
417
|
+
args: [{
|
418
|
+
standalone: true,
|
419
|
+
selector: 'p-fileUpload[formControlName], p-fileUpload[formControl], p-fileUpload[ngModel]',
|
420
|
+
providers: [
|
421
|
+
{
|
422
|
+
provide: NG_VALUE_ACCESSOR,
|
423
|
+
useExisting: forwardRef(() => FileUploadValueAccessor),
|
424
|
+
multi: true,
|
425
|
+
},
|
426
|
+
],
|
427
|
+
}]
|
428
|
+
}], ctorParameters: () => [{ type: i1$1.FileUpload }] });
|
429
|
+
|
430
|
+
/**
|
431
|
+
* PrimeNgFormsComponent is a standalone Angular component that dynamically generates
|
432
|
+
* a form based on the provided configuration. It leverages PrimeNG UI components
|
433
|
+
* and Angular Reactive Forms for form creation and validation.
|
434
|
+
*
|
435
|
+
* @selector primeng-forms
|
436
|
+
* @standalone true
|
437
|
+
* @imports [
|
438
|
+
* CommonModule,
|
439
|
+
* FormsModule,
|
440
|
+
* ReactiveFormsModule,
|
441
|
+
* ValidationMessagesComponent,
|
442
|
+
* InputTextModule,
|
443
|
+
* MultiSelectModule,
|
444
|
+
* TextareaModule,
|
445
|
+
* CheckboxModule,
|
446
|
+
* RadioButtonModule,
|
447
|
+
* DatePickerModule,
|
448
|
+
* ToggleButtonModule,
|
449
|
+
* FileUploadModule,
|
450
|
+
* SliderModule,
|
451
|
+
* ButtonModule,
|
452
|
+
* SelectModule,
|
453
|
+
* FileUploadValueAccessor
|
454
|
+
* ]
|
455
|
+
* @templateUrl ./prime-form.component.html
|
456
|
+
* @styleUrl ./prime-form.component.css
|
457
|
+
* @changeDetection ChangeDetectionStrategy.OnPush
|
458
|
+
*
|
459
|
+
* @property {string} formName - The name of the form.
|
460
|
+
* @property {FormControlConfig[]} controls - The configuration for the form controls.
|
461
|
+
* @property {EventEmitter<Record<string, any>>} formSubmit - Event emitter for form submission.
|
462
|
+
* @property {FormGroup} form - The reactive form group.
|
463
|
+
* @property {BehaviorSubject<boolean>} formChanges$ - Observable to track form changes.
|
464
|
+
*
|
465
|
+
* @constructor
|
466
|
+
* @param {FormBuilder} fb - FormBuilder service to create form controls.
|
467
|
+
* @param {ChangeDetectorRef} cdr - ChangeDetectorRef to manually trigger change detection.
|
468
|
+
*
|
469
|
+
* @method ngOnInit - Lifecycle hook that initializes the form.
|
470
|
+
* @method initializeForm - Initializes the form controls and sets up value change subscriptions.
|
471
|
+
* @method getValidators - Returns an array of validators for a given form control configuration.
|
472
|
+
* @param {FormControlConfig} control - The configuration for a form control.
|
473
|
+
* @returns {ValidatorFn[]} - An array of validator functions.
|
474
|
+
* @method updateValidators - Updates the validators for a form control based on its value.
|
475
|
+
* @param {AbstractControl} control - The form control to update.
|
476
|
+
* @param {any} value - The current value of the form control.
|
477
|
+
* @method shouldRequireValidation - Determines if a form control should require validation.
|
478
|
+
* @param {any} value - The current value of the form control.
|
479
|
+
* @returns {boolean} - True if validation is required, false otherwise.
|
480
|
+
* @method onFileSelect - Handles file selection for file upload controls.
|
481
|
+
* @param {any} event - The file selection event.
|
482
|
+
* @param {string} controlName - The name of the form control.
|
483
|
+
* @method onSubmit - Handles form submission, validates the form, and emits the form value.
|
484
|
+
*/
|
485
|
+
class PrimeNgFormsComponent {
|
486
|
+
fb;
|
487
|
+
cdr;
|
488
|
+
formName = input.required();
|
489
|
+
controls = input.required();
|
490
|
+
formSubmit = output();
|
491
|
+
form;
|
492
|
+
formChanges$ = new BehaviorSubject(false);
|
493
|
+
constructor(fb, cdr) {
|
494
|
+
this.fb = fb;
|
495
|
+
this.cdr = cdr;
|
496
|
+
}
|
497
|
+
ngOnInit() {
|
498
|
+
this.initializeForm();
|
499
|
+
}
|
500
|
+
initializeForm() {
|
501
|
+
const formControls = {};
|
502
|
+
this.controls().forEach((control) => {
|
503
|
+
formControls[control.name] = [
|
504
|
+
control.value ?? null,
|
505
|
+
this.getValidators(control),
|
506
|
+
];
|
507
|
+
});
|
508
|
+
this.form = this.fb.group(formControls);
|
509
|
+
this.controls().forEach((control) => {
|
510
|
+
const formControl = this.form.get(control.name);
|
511
|
+
if (formControl) {
|
512
|
+
formControl.valueChanges.subscribe((value) => {
|
513
|
+
this.updateValidators(formControl, value);
|
514
|
+
});
|
515
|
+
}
|
516
|
+
});
|
517
|
+
this.formChanges$.subscribe(() => this.cdr.markForCheck());
|
518
|
+
}
|
519
|
+
getValidators(control) {
|
520
|
+
const validators = [];
|
521
|
+
if (control.validators) {
|
522
|
+
control.validators.forEach((validator) => {
|
523
|
+
if (validator.required)
|
524
|
+
validators.push(Validators.required);
|
525
|
+
if (validator.minlength)
|
526
|
+
validators.push(Validators.minLength(validator.minlength));
|
527
|
+
if (validator.maxlength)
|
528
|
+
validators.push(Validators.maxLength(validator.maxlength));
|
529
|
+
if (validator.pattern)
|
530
|
+
validators.push(Validators.pattern(validator.pattern));
|
531
|
+
if (validator.email)
|
532
|
+
validators.push(Validators.email);
|
533
|
+
if (validator.custom)
|
534
|
+
validators.push(validator.custom);
|
535
|
+
});
|
536
|
+
}
|
537
|
+
return validators;
|
538
|
+
}
|
539
|
+
updateValidators(control, value) {
|
540
|
+
if (this.shouldRequireValidation(value)) {
|
541
|
+
control.addValidators(Validators.required);
|
542
|
+
}
|
543
|
+
else {
|
544
|
+
control.removeValidators(Validators.required);
|
545
|
+
}
|
546
|
+
control.updateValueAndValidity();
|
547
|
+
this.formChanges$.next(true);
|
548
|
+
}
|
549
|
+
shouldRequireValidation(value) {
|
550
|
+
return value !== null && value !== '';
|
551
|
+
}
|
552
|
+
onFileSelect(event, controlName) {
|
553
|
+
const file = event.files[0]; // Getting the first selected file
|
554
|
+
if (file) {
|
555
|
+
console.log(`Selected file for ${controlName}:`, file);
|
556
|
+
console.log(this.form.get(controlName)?.value);
|
557
|
+
this.form.get(controlName)?.setValue(file);
|
558
|
+
console.log(this.form.get(controlName)?.value);
|
559
|
+
this.form.get(controlName)?.updateValueAndValidity(); // Update the form control's validity
|
560
|
+
// Emit the onUpload event if defined
|
561
|
+
const controlConfig = this.controls().find(control => control.name === controlName);
|
562
|
+
if (controlConfig?.events?.onUpload) {
|
563
|
+
controlConfig.events.onUpload(event);
|
564
|
+
}
|
565
|
+
}
|
566
|
+
}
|
567
|
+
onSubmit() {
|
568
|
+
this.form.markAllAsTouched();
|
569
|
+
this.form.markAsDirty();
|
570
|
+
this.form.updateValueAndValidity();
|
571
|
+
if (this.form.valid) {
|
572
|
+
this.formSubmit.emit(this.form.value);
|
573
|
+
this.form.reset();
|
574
|
+
// Clear the file input
|
575
|
+
const fileInput = document.querySelector('input[type="file"]');
|
576
|
+
if (fileInput) {
|
577
|
+
fileInput.value = '';
|
578
|
+
}
|
579
|
+
}
|
580
|
+
else {
|
581
|
+
console.error('Form Invalid');
|
582
|
+
}
|
583
|
+
this.formChanges$.next(true);
|
584
|
+
}
|
585
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrimeNgFormsComponent, deps: [{ token: i1.FormBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
586
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: PrimeNgFormsComponent, isStandalone: true, selector: "primeng-forms", inputs: { formName: { classPropertyName: "formName", publicName: "formName", isSignal: true, isRequired: true, transformFunction: null }, controls: { classPropertyName: "controls", publicName: "controls", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { formSubmit: "formSubmit" }, ngImport: i0, template: "<form [formGroup]=\"form\" [attr.name]=\"formName()\" (ngSubmit)=\"onSubmit()\">\n @for (control of controls(); track $index) {\n @if (control.uiFramework === \"primeng\" || !control.uiFramework) {\n @if (form.get(control.name)) {\n <section [ngClass]=\"control.class\" [ngStyle]=\"control.style\">\n @if (control.label) {\n <label\n [attr.for]=\"control.name\"\n [ngClass]=\"control.labelClass\"\n [ngStyle]=\"control.labelStyle\"\n >\n {{ control.label }}\n </label>\n }\n\n @switch (control.type) {\n @case (\"text\") {\n <input\n pInputText\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n (change)=\"control.events?.onChange?.($event)\"\n (focus)=\"control.events?.onFocus?.($event)\"\n (blur)=\"control.events?.onBlur?.($event)\"\n (keyup)=\"control.events?.onKeyUp?.($event)\"\n (keydown)=\"control.events?.onKeyDown?.($event)\"\n (paste)=\"control.events?.onPaste?.($event)\"\n />\n }\n @case (\"number\") {\n <input\n pInputText\n type=\"number\"\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n (change)=\"control.events?.onChange?.($event)\"\n (focus)=\"control.events?.onFocus?.($event)\"\n (blur)=\"control.events?.onBlur?.($event)\"\n (keyup)=\"control.events?.onKeyUp?.($event)\"\n (keydown)=\"control.events?.onKeyDown?.($event)\"\n (paste)=\"control.events?.onPaste?.($event)\"\n />\n }\n @case (\"password\") {\n <input\n pInputText\n type=\"password\"\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n (change)=\"control.events?.onChange?.($event)\"\n (focus)=\"control.events?.onFocus?.($event)\"\n (blur)=\"control.events?.onBlur?.($event)\"\n (keyup)=\"control.events?.onKeyUp?.($event)\"\n (keydown)=\"control.events?.onKeyDown?.($event)\"\n (paste)=\"control.events?.onPaste?.($event)\"\n />\n }\n @case (\"email\") {\n <input\n pInputText\n type=\"email\"\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n (change)=\"control.events?.onChange?.($event)\"\n (focus)=\"control.events?.onFocus?.($event)\"\n (blur)=\"control.events?.onBlur?.($event)\"\n (keyup)=\"control.events?.onKeyUp?.($event)\"\n (keydown)=\"control.events?.onKeyDown?.($event)\"\n (paste)=\"control.events?.onPaste?.($event)\"\n />\n }\n @case (\"select\") {\n <p-select\n [options]=\"control.options\"\n [formControlName]=\"control.name\"\n (onChange)=\"control.events?.onChange?.($event)\"\n (onFocus)=\"control.events?.onFocus?.($event)\"\n (onBlur)=\"control.events?.onBlur?.($event)\"\n />\n }\n @case (\"multi-select\") {\n <p-multiSelect\n [options]=\"control.options\"\n [formControlName]=\"control.name\"\n (onChange)=\"control.events?.onChange?.($event)\"\n (onFocus)=\"control.events?.onFocus?.($event)\"\n (onBlur)=\"control.events?.onBlur?.($event)\"\n ></p-multiSelect>\n }\n @case (\"textarea\") {\n <textarea\n pTextarea\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n (change)=\"control.events?.onChange?.($event)\"\n (focus)=\"control.events?.onFocus?.($event)\"\n (blur)=\"control.events?.onBlur?.($event)\"\n (keyup)=\"control.events?.onKeyUp?.($event)\"\n (keydown)=\"control.events?.onKeyDown?.($event)\"\n (paste)=\"control.events?.onPaste?.($event)\"\n ></textarea>\n }\n @case (\"checkbox\") {\n <p-checkbox\n [binary]=\"true\"\n [formControlName]=\"control.name\"\n (onChange)=\"control.events?.onChange?.($event)\"\n (onFocus)=\"control.events?.onFocus?.($event)\"\n (onBlur)=\"control.events?.onBlur?.($event)\"\n ></p-checkbox>\n }\n @case (\"radio\") {\n @for (option of control.options ?? []; track $index) {\n <div>\n <p-radioButton\n [name]=\"control.name\"\n [formControlName]=\"control.name\"\n [value]=\"option\"\n [inputId]=\"'radio-' + option\"\n (onChange)=\"control.events?.onChange?.($event)\"\n (onFocus)=\"control.events?.onFocus?.($event)\"\n (onBlur)=\"control.events?.onBlur?.($event)\"\n ></p-radioButton>\n <label [for]=\"'radio-' + option\">{{ option }}</label>\n </div>\n }\n }\n @case (\"date\") {\n <p-datepicker\n [formControlName]=\"control.name\"\n (onSelect)=\"control.events?.onSelect?.($event)\"\n (onFocus)=\"control.events?.onFocus?.($event)\"\n (onBlur)=\"control.events?.onBlur?.($event)\"\n />\n }\n @case (\"toggle\") {\n <p-toggleButton\n [formControlName]=\"control.name\"\n (onChange)=\"control.events?.onChange?.($event)\"\n (onFocus)=\"control.events?.onFocus?.($event)\"\n (onBlur)=\"control.events?.onBlur?.($event)\"\n ></p-toggleButton>\n }\n <!-- @case (\"file\") {\n <p-fileUpload \n [customUpload]=\"true\"\n [formControlName]=\"control.name\"\n (onSelect)=\"control.events?.onSelect?.($event)\"\n (onClear)=\"control.events?.onClear?.($event)\"\n (onRemove)=\"control.events?.onRemove?.($event)\"\n (onError)=\"control.events?.onError?.($event)\"\n (onBeforeUpload)=\"control.events?.onBeforeUpload?.($event)\"\n (onProgress)=\"control.events?.onProgress?.($event)\"\n (onUpload)=\"control.events?.onUpload?.($event)\"\n >\n\n <p-fileUpload\n [customUpload]=\"true\"\n (onUpload)=\"onFileSelect($event, control.name)\"\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n [chooseLabel]=\"control.primeng?.chooseLabel\"\n [uploadLabel]=\"control.primeng?.uploadLabel\"\n [cancelLabel]=\"control.primeng?.cancelLabel\"\n [auto]=\"control.primeng?.auto\"\n [url]=\"control.primeng?.url\"\n [withCredentials]=\"control.primeng?.withCredentials\"\n [multiple]=\"control.primeng?.multiple\"\n [maxFileSize]=\"control.primeng?.maxFileSize\"\n [customUpload]=\"control.primeng?.customUpload\"\n [showUploadButton]=\"control.primeng?.showUploadButton\"\n [showCancelButton]=\"control.primeng?.showCancelButton\"\n [accept]=\"control.primeng?.accept\"\n [mode]=\"control.primeng?.mode\"\n [previewWidth]=\"control.primeng?.previewWidth\"\n (onSelect)=\"control.events?.onSelect?.($event)\"\n (onClear)=\"control.events?.onClear?.($event)\"\n (onRemove)=\"control.events?.onRemove?.($event)\"\n (onError)=\"control.events?.onError?.($event)\"\n (onBeforeUpload)=\"control.events?.onBeforeUpload?.($event)\"\n (onProgress)=\"control.events?.onProgress?.($event)\"\n (onUpload)=\"control.events?.onUpload?.($event)\"\n >\n <ng-template pTemplate=\"content\">\n <p-button label=\"Choose File\" icon=\"pi pi-upload\"></p-button>\n </ng-template>\n </p-fileUpload>\n } -->\n @case (\"slider\") {\n <p-slider\n [formControlName]=\"control.name\"\n (onChange)=\"control.events?.onChange?.($event)\"\n (onSlideEnd)=\"control.events?.onSlideEnd?.($event)\"\n ></p-slider>\n }\n }\n\n <validation-messages\n [control]=\"form.get(control.name)\"\n [controlName]=\"control.name\"\n [config]=\"control\"\n ></validation-messages>\n </section>\n }\n }\n }\n <button\n pButton\n type=\"submit\"\n [disabled]=\"form.invalid\"\n label=\"Submit\"\n ></button>\n</form>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: ValidationMessagesComponent, selector: "validation-messages", inputs: ["control", "controlName", "config"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$1.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i4$1.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "style", "styleClass", "panelStyle", "panelStyleClass", "inputId", "disabled", "fluid", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "variant", "appendTo", "dataKey", "name", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "size", "showClear", "autofocus", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "defaultLabel", "placeholder", "options", "filterValue", "itemSize", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i5$1.Textarea, selector: "[pTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i6$1.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: i7$1.RadioButton, selector: "p-radioButton, p-radiobutton, p-radio-button", inputs: ["value", "formControlName", "name", "disabled", "variant", "size", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "autofocus", "binary"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DatePickerModule }, { kind: "component", type: i8$1.DatePicker, selector: "p-datePicker, p-datepicker, p-date-picker", inputs: ["iconDisplay", "style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "fluid", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "variant", "size", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale", "view", "defaultDate"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "ngmodule", type: ToggleButtonModule }, { kind: "component", type: i9$1.ToggleButton, selector: "p-toggleButton, p-togglebutton, p-toggle-button", inputs: ["onLabel", "offLabel", "onIcon", "offIcon", "ariaLabel", "ariaLabelledBy", "disabled", "style", "styleClass", "inputId", "tabindex", "size", "iconPos", "autofocus", "allowEmpty"], outputs: ["onChange"] }, { kind: "ngmodule", type: FileUploadModule }, { kind: "ngmodule", type: SliderModule }, { kind: "component", type: i10$1.Slider, selector: "p-slider", inputs: ["animate", "disabled", "min", "max", "orientation", "step", "range", "style", "styleClass", "ariaLabel", "ariaLabelledBy", "tabindex", "autofocus"], outputs: ["onChange", "onSlideEnd"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i11.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i12.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
587
|
+
}
|
588
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrimeNgFormsComponent, decorators: [{
|
589
|
+
type: Component,
|
590
|
+
args: [{ selector: 'primeng-forms', standalone: true, imports: [
|
591
|
+
CommonModule,
|
592
|
+
FormsModule,
|
593
|
+
ReactiveFormsModule,
|
594
|
+
ValidationMessagesComponent,
|
595
|
+
InputTextModule,
|
596
|
+
MultiSelectModule,
|
597
|
+
TextareaModule,
|
598
|
+
CheckboxModule,
|
599
|
+
RadioButtonModule,
|
600
|
+
DatePickerModule,
|
601
|
+
ToggleButtonModule,
|
602
|
+
FileUploadModule,
|
603
|
+
SliderModule,
|
604
|
+
ButtonModule,
|
605
|
+
SelectModule,
|
606
|
+
FileUploadValueAccessor
|
607
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<form [formGroup]=\"form\" [attr.name]=\"formName()\" (ngSubmit)=\"onSubmit()\">\n @for (control of controls(); track $index) {\n @if (control.uiFramework === \"primeng\" || !control.uiFramework) {\n @if (form.get(control.name)) {\n <section [ngClass]=\"control.class\" [ngStyle]=\"control.style\">\n @if (control.label) {\n <label\n [attr.for]=\"control.name\"\n [ngClass]=\"control.labelClass\"\n [ngStyle]=\"control.labelStyle\"\n >\n {{ control.label }}\n </label>\n }\n\n @switch (control.type) {\n @case (\"text\") {\n <input\n pInputText\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n (change)=\"control.events?.onChange?.($event)\"\n (focus)=\"control.events?.onFocus?.($event)\"\n (blur)=\"control.events?.onBlur?.($event)\"\n (keyup)=\"control.events?.onKeyUp?.($event)\"\n (keydown)=\"control.events?.onKeyDown?.($event)\"\n (paste)=\"control.events?.onPaste?.($event)\"\n />\n }\n @case (\"number\") {\n <input\n pInputText\n type=\"number\"\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n (change)=\"control.events?.onChange?.($event)\"\n (focus)=\"control.events?.onFocus?.($event)\"\n (blur)=\"control.events?.onBlur?.($event)\"\n (keyup)=\"control.events?.onKeyUp?.($event)\"\n (keydown)=\"control.events?.onKeyDown?.($event)\"\n (paste)=\"control.events?.onPaste?.($event)\"\n />\n }\n @case (\"password\") {\n <input\n pInputText\n type=\"password\"\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n (change)=\"control.events?.onChange?.($event)\"\n (focus)=\"control.events?.onFocus?.($event)\"\n (blur)=\"control.events?.onBlur?.($event)\"\n (keyup)=\"control.events?.onKeyUp?.($event)\"\n (keydown)=\"control.events?.onKeyDown?.($event)\"\n (paste)=\"control.events?.onPaste?.($event)\"\n />\n }\n @case (\"email\") {\n <input\n pInputText\n type=\"email\"\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n (change)=\"control.events?.onChange?.($event)\"\n (focus)=\"control.events?.onFocus?.($event)\"\n (blur)=\"control.events?.onBlur?.($event)\"\n (keyup)=\"control.events?.onKeyUp?.($event)\"\n (keydown)=\"control.events?.onKeyDown?.($event)\"\n (paste)=\"control.events?.onPaste?.($event)\"\n />\n }\n @case (\"select\") {\n <p-select\n [options]=\"control.options\"\n [formControlName]=\"control.name\"\n (onChange)=\"control.events?.onChange?.($event)\"\n (onFocus)=\"control.events?.onFocus?.($event)\"\n (onBlur)=\"control.events?.onBlur?.($event)\"\n />\n }\n @case (\"multi-select\") {\n <p-multiSelect\n [options]=\"control.options\"\n [formControlName]=\"control.name\"\n (onChange)=\"control.events?.onChange?.($event)\"\n (onFocus)=\"control.events?.onFocus?.($event)\"\n (onBlur)=\"control.events?.onBlur?.($event)\"\n ></p-multiSelect>\n }\n @case (\"textarea\") {\n <textarea\n pTextarea\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n (change)=\"control.events?.onChange?.($event)\"\n (focus)=\"control.events?.onFocus?.($event)\"\n (blur)=\"control.events?.onBlur?.($event)\"\n (keyup)=\"control.events?.onKeyUp?.($event)\"\n (keydown)=\"control.events?.onKeyDown?.($event)\"\n (paste)=\"control.events?.onPaste?.($event)\"\n ></textarea>\n }\n @case (\"checkbox\") {\n <p-checkbox\n [binary]=\"true\"\n [formControlName]=\"control.name\"\n (onChange)=\"control.events?.onChange?.($event)\"\n (onFocus)=\"control.events?.onFocus?.($event)\"\n (onBlur)=\"control.events?.onBlur?.($event)\"\n ></p-checkbox>\n }\n @case (\"radio\") {\n @for (option of control.options ?? []; track $index) {\n <div>\n <p-radioButton\n [name]=\"control.name\"\n [formControlName]=\"control.name\"\n [value]=\"option\"\n [inputId]=\"'radio-' + option\"\n (onChange)=\"control.events?.onChange?.($event)\"\n (onFocus)=\"control.events?.onFocus?.($event)\"\n (onBlur)=\"control.events?.onBlur?.($event)\"\n ></p-radioButton>\n <label [for]=\"'radio-' + option\">{{ option }}</label>\n </div>\n }\n }\n @case (\"date\") {\n <p-datepicker\n [formControlName]=\"control.name\"\n (onSelect)=\"control.events?.onSelect?.($event)\"\n (onFocus)=\"control.events?.onFocus?.($event)\"\n (onBlur)=\"control.events?.onBlur?.($event)\"\n />\n }\n @case (\"toggle\") {\n <p-toggleButton\n [formControlName]=\"control.name\"\n (onChange)=\"control.events?.onChange?.($event)\"\n (onFocus)=\"control.events?.onFocus?.($event)\"\n (onBlur)=\"control.events?.onBlur?.($event)\"\n ></p-toggleButton>\n }\n <!-- @case (\"file\") {\n <p-fileUpload \n [customUpload]=\"true\"\n [formControlName]=\"control.name\"\n (onSelect)=\"control.events?.onSelect?.($event)\"\n (onClear)=\"control.events?.onClear?.($event)\"\n (onRemove)=\"control.events?.onRemove?.($event)\"\n (onError)=\"control.events?.onError?.($event)\"\n (onBeforeUpload)=\"control.events?.onBeforeUpload?.($event)\"\n (onProgress)=\"control.events?.onProgress?.($event)\"\n (onUpload)=\"control.events?.onUpload?.($event)\"\n >\n\n <p-fileUpload\n [customUpload]=\"true\"\n (onUpload)=\"onFileSelect($event, control.name)\"\n [formControlName]=\"control.name\"\n [id]=\"control.name\"\n [chooseLabel]=\"control.primeng?.chooseLabel\"\n [uploadLabel]=\"control.primeng?.uploadLabel\"\n [cancelLabel]=\"control.primeng?.cancelLabel\"\n [auto]=\"control.primeng?.auto\"\n [url]=\"control.primeng?.url\"\n [withCredentials]=\"control.primeng?.withCredentials\"\n [multiple]=\"control.primeng?.multiple\"\n [maxFileSize]=\"control.primeng?.maxFileSize\"\n [customUpload]=\"control.primeng?.customUpload\"\n [showUploadButton]=\"control.primeng?.showUploadButton\"\n [showCancelButton]=\"control.primeng?.showCancelButton\"\n [accept]=\"control.primeng?.accept\"\n [mode]=\"control.primeng?.mode\"\n [previewWidth]=\"control.primeng?.previewWidth\"\n (onSelect)=\"control.events?.onSelect?.($event)\"\n (onClear)=\"control.events?.onClear?.($event)\"\n (onRemove)=\"control.events?.onRemove?.($event)\"\n (onError)=\"control.events?.onError?.($event)\"\n (onBeforeUpload)=\"control.events?.onBeforeUpload?.($event)\"\n (onProgress)=\"control.events?.onProgress?.($event)\"\n (onUpload)=\"control.events?.onUpload?.($event)\"\n >\n <ng-template pTemplate=\"content\">\n <p-button label=\"Choose File\" icon=\"pi pi-upload\"></p-button>\n </ng-template>\n </p-fileUpload>\n } -->\n @case (\"slider\") {\n <p-slider\n [formControlName]=\"control.name\"\n (onChange)=\"control.events?.onChange?.($event)\"\n (onSlideEnd)=\"control.events?.onSlideEnd?.($event)\"\n ></p-slider>\n }\n }\n\n <validation-messages\n [control]=\"form.get(control.name)\"\n [controlName]=\"control.name\"\n [config]=\"control\"\n ></validation-messages>\n </section>\n }\n }\n }\n <button\n pButton\n type=\"submit\"\n [disabled]=\"form.invalid\"\n label=\"Submit\"\n ></button>\n</form>\n" }]
|
608
|
+
}], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i0.ChangeDetectorRef }] });
|
609
|
+
|
610
|
+
/**
|
611
|
+
* Generated bundle index. Do not edit.
|
612
|
+
*/
|
613
|
+
|
614
|
+
export { DefaultFormsComponent, MaterialFormsComponent, PrimeNgFormsComponent };
|
615
|
+
//# sourceMappingURL=bsachref-ng-form.mjs.map
|