portfolio-admin/src/app/shared/dynamic-form/dynamic-form.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>