back

Conditional Form Design Pattern

home

AngularTypeScriptDesignPattern
code

Description

A design pattern I created to solve the problem of showing conditional form elements when certain options were selected based on the data populating the form.

Angular


Favorite Sci-Fi Universes

Code


<div class="mat-app-background layout">
<mat-card class="form-card">
<mat-card-header>
<mat-card-title>Favorite Sci-Fi Universes</mat-card-title>
</mat-card-header>
<mat-card-content>
<form [formGroup]="universesForm">
<mat-form-field appearance="outline">
<mat-label>Universes</mat-label>
<mat-select #universes formControlName="universes" name="universes" multiple>
<mat-select-trigger>
{{universes.value?.[0]?.name || ''}}
@if ((universes.value?.length || 0) > 1) {
<span class="example-additional-selection">
({{(universes.value?.length || 0)}} selected)
</span>
}
</mat-select-trigger>
@for (universe of universeList; track universe) {
<mat-option [value]="universe">{{universe.name}}</mat-option>
}
</mat-select>
</mat-form-field>
@if (subUniverses.length > 0) {
<mat-card appearance="outlined" class="conditional-form-card">
<mat-card-content formArrayName="subUniverses">
@for (subUniverse of subUniverses.controls; track subUniverse; let i = $index) {
<mat-form-field appearance="outline">
<mat-label>{{ selectedSubUniverses[i]?.name }}</mat-label>
<mat-select [formControlName]="i">
<mat-option
[value]="{ key: selectedSubUniverses[i].key, name: selectedSubUniverses[i].name, sub: {key: 'all', name: 'All'} }">All</mat-option>
@for (sub of selectedSubUniverses[i].sub; track sub; let j = $index) {
<mat-option
[value]="{ key: selectedSubUniverses[i].key, name: selectedSubUniverses[i].name, sub: [sub] }">{{sub.name}}</mat-option>
}
</mat-select>
</mat-form-field>
}
</mat-card-content>
<mat-card-footer></mat-card-footer>
</mat-card>
}
</form>
</mat-card-content>
<mat-card-footer>
<mat-card-actions align="end">
<button mat-flat-button (click)="openSnackBar()">Open SnackBar</button>
</mat-card-actions>
</mat-card-footer>
</mat-card>
</div>

React

coming soon

VueJS

coming soon

Future Plans

In the future, I plan to add state management (which will also be brought to its own page to represent each library) and other versions of this example in various frameworks/libraries (starting with React and VueJS)