141 lines
6.5 KiB
HTML
141 lines
6.5 KiB
HTML
<form [formGroup]="form">
|
|
|
|
@for (f of config.fields; track f) {
|
|
|
|
<ng-container *ngIf="f.type !== 'array' && f.type !== 'hidden'">
|
|
@if (f.type === 'text') {
|
|
<mat-form-field appearance="outline" class="full-width">
|
|
<mat-label>{{ f.label }}</mat-label>
|
|
<input matInput [id]="f.name" [formControlName]="f.name" />
|
|
<mat-hint *ngIf="f.placeholder">{{ f.placeholder }}</mat-hint>
|
|
<mat-error *ngIf="form.get(f.name)?.invalid && (form.get(f.name)?.touched || form.get(f.name)?.dirty)">
|
|
This field is required.
|
|
</mat-error>
|
|
</mat-form-field>
|
|
}
|
|
|
|
@if (f.type === 'textarea') {
|
|
<mat-form-field appearance="outline" class="full-width">
|
|
<mat-label>{{ f.label }}</mat-label>
|
|
<textarea matInput [id]="f.name" cdkTextareaAutosize cdkAutosizeMinRows="3" cdkAutosizeMaxRows="6" [formControlName]="f.name"></textarea>
|
|
<mat-hint *ngIf="f.placeholder">{{ f.placeholder }}</mat-hint>
|
|
<mat-error *ngIf="form.get(f.name)?.invalid && (form.get(f.name)?.touched || form.get(f.name)?.dirty)">
|
|
This field is required.
|
|
</mat-error>
|
|
</mat-form-field>
|
|
}
|
|
|
|
@if (f.type === 'number') {
|
|
<mat-form-field appearance="outline" class="full-width">
|
|
<mat-label>{{ f.label }}</mat-label>
|
|
<input matInput [id]="f.name" type="number" [formControlName]="f.name" />
|
|
<mat-error *ngIf="form.get(f.name)?.invalid && (form.get(f.name)?.touched || form.get(f.name)?.dirty)">
|
|
Please enter a valid number.
|
|
</mat-error>
|
|
</mat-form-field>
|
|
}
|
|
|
|
@if (f.type === 'select') {
|
|
<mat-form-field appearance="outline" class="full-width">
|
|
<mat-label>{{ f.label }}</mat-label>
|
|
<mat-select [id]="f.name" [formControlName]="f.name">
|
|
@for (opt of f.options; track opt) {
|
|
<mat-option [value]="opt.value">{{ opt.label }}</mat-option>
|
|
}
|
|
</mat-select>
|
|
<mat-error *ngIf="form.get(f.name)?.invalid && (form.get(f.name)?.touched || form.get(f.name)?.dirty)">
|
|
Please select a value.
|
|
</mat-error>
|
|
</mat-form-field>
|
|
}
|
|
|
|
@if (f.type === 'year') {
|
|
<mat-form-field appearance="outline" class="full-width">
|
|
<mat-label>{{ f.label }}</mat-label>
|
|
<mat-select [id]="f.name" [formControlName]="f.name" [compareWith]="compareYearValues">
|
|
@if (f.yearRange?.allowPresent) {
|
|
<mat-option value="Present">Present</mat-option>
|
|
}
|
|
@for (yr of getYearOptions(f); track yr) {
|
|
<mat-option [value]="yr">{{ yr }}</mat-option>
|
|
}
|
|
</mat-select>
|
|
<mat-error *ngIf="form.get(f.name)?.invalid && (form.get(f.name)?.touched || form.get(f.name)?.dirty)">
|
|
Please select a year.
|
|
</mat-error>
|
|
</mat-form-field>
|
|
}
|
|
|
|
@if (f.type === 'date') {
|
|
<mat-form-field appearance="outline" class="full-width">
|
|
<mat-label>{{ f.label }}</mat-label>
|
|
<input matInput [matDatepicker]="picker" [id]="f.name" [formControlName]="f.name" [placeholder]="f.placeholder || ''" />
|
|
<mat-datepicker-toggle matIconSuffix [for]="picker"></mat-datepicker-toggle>
|
|
<mat-datepicker #picker></mat-datepicker>
|
|
<mat-error *ngIf="form.get(f.name)?.invalid && (form.get(f.name)?.touched || form.get(f.name)?.dirty)">
|
|
Please select a date.
|
|
</mat-error>
|
|
</mat-form-field>
|
|
}
|
|
|
|
@if (f.type === 'file') {
|
|
<div>
|
|
<label [for]="f.name">{{ f.label }}</label>
|
|
<input [id]="f.name" type="file" (change)="onFileChange($event, f.name)" />
|
|
</div>
|
|
}
|
|
</ng-container>
|
|
|
|
<ng-container *ngIf="f.type === 'array'">
|
|
<div>
|
|
<h3>{{ f.label }}</h3>
|
|
<div [formArrayName]="f.name">
|
|
@for (item of getArrayControls(f.name); track item; let i = $index) {
|
|
<div [formGroupName]="i" class="array-item">
|
|
<div class="array-item-fields">
|
|
@for (sub of f.itemConfig; track sub) {
|
|
@if (sub.type !== 'hidden') {
|
|
@if (sub.type === 'date') {
|
|
<mat-form-field appearance="outline" class="full-width">
|
|
<mat-label>{{ sub.label }}</mat-label>
|
|
<input matInput [matDatepicker]="subPicker" [id]="sub.name + '_' + i" [formControlName]="sub.name" [placeholder]="sub.placeholder || ''" />
|
|
<mat-datepicker-toggle matIconSuffix [for]="subPicker"></mat-datepicker-toggle>
|
|
<mat-datepicker #subPicker></mat-datepicker>
|
|
</mat-form-field>
|
|
} @else if (sub.type === 'year') {
|
|
<mat-form-field appearance="outline" class="full-width">
|
|
<mat-label>{{ sub.label }}</mat-label>
|
|
<mat-select [id]="sub.name + '_' + i" [formControlName]="sub.name" [compareWith]="compareYearValues">
|
|
@if (sub.yearRange?.allowPresent) {
|
|
<mat-option value="Present">Present</mat-option>
|
|
}
|
|
@for (yr of getYearOptions(sub); track yr) {
|
|
<mat-option [value]="yr">{{ yr }}</mat-option>
|
|
}
|
|
</mat-select>
|
|
</mat-form-field>
|
|
} @else {
|
|
<mat-form-field appearance="outline" class="full-width">
|
|
<mat-label>{{ sub.label }}</mat-label>
|
|
<input matInput [id]="sub.name + '_' + i" [formControlName]="sub.name" [placeholder]="sub.placeholder || ''" />
|
|
</mat-form-field>
|
|
}
|
|
}
|
|
}
|
|
</div>
|
|
<div class="array-item-actions">
|
|
<button type="button" class="remove-link" (click)="removeArrayItem(f, i)">
|
|
<i class="fa-solid fa-trash-can"></i> Remove
|
|
</button>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
<button type="button" class="add-btn" (click)="addArrayItem(f)">
|
|
<i class="fa-solid fa-plus"></i> Add Item
|
|
</button>
|
|
</div>
|
|
</ng-container>
|
|
}
|
|
|
|
</form> |