I'm using Angular Material stepper and it works fine as a whole code in 1 component. But stepper will be used in ~10 different components. There are 7 different types of form like input, select, name, table, etc. So I figured out that I will divide stepper into separate components where each component is a step.
So, I decided to make a template for form app-step-form
<form [formGroup]="myForm">
<mat-vertical-stepper [linear]="isLinear" #stepper>
<ng-content></ng-content>
</mat-vertical-stepper>
</form>
Than creating different steps just like that in app-table-select
<mat-step [stepControl]="tableControl">
<ng-template matStepLabel>Table </ng-template>
<mat-form-field appearance="fill">
<mat-label>Choose table</mat-label>
<mat-select [formControl]="tableControl">
<mat-option *ngFor="let table of tables" [value]="table.value">
{{table.viewValue}}
</mat-option>
</mat-select>
</mat-form-field>
<div>
<button mat-button matStepperNext>Next</button>
</div>
</mat-step>
and than insert components as steps like that
<app-step-from>
<app-table-select>
</app-table-select>
<app-name-input>
</app-name-input>
</app-step-from>
So I would have template for form to use in different components just not to create one by one each time.
But the problem I am facing is if I use step component like showed above it is not visible in app-step-form
. Making small change in app-step-form
and extracting <mat-step></mat-step>
to this
<form [formGroup]="myForm">
<mat-vertical-stepper [linear]="isLinear" #stepper>
<mat-step>
<ng-content></ng-content>
</mat-step>
</mat-vertical-stepper>
</form>
and removing mat-step
from and putting it in <ng-template>
like this
<ng-template>
<ng-template matStepLabel>Table </ng-template>
<mat-form-field appearance="fill">
<mat-label>Choose table</mat-label>
<mat-select>
<mat-option *ngFor="let table of tables" [value]="table.value">
{{table.viewValue}}
</mat-option>
</mat-select>
</mat-form-field>
</ng-template>
makes this step visible in app-step-form
but cannot pass step component label from
<ng-template matStepLabel>Table </ng-template>
and this label is not visible or using @Input()
neither.
I've spent 2 days trying to crack this up, seeking for an answear but so far not so godd and lost idea how to overcome this problem to make my stepper reusable.
Does anyone have any idea how to make this idea work? Or is it not possible to make the way I figured it?
Also any ideas how to make those inputs act like part of 1 form? Subforms merged to 1 form or what?
For whom it may concern - I did not find any workaround of this issue.
I've tried to create 1 reusable component with every possible input in it and display each input in it via *ngIf directive depending on path where it is located, for example:
<app-step-form [path]='/your-path'></app-step-from>
and each path having each possible inputs but it turned out that it has lot's of unexpected vulnerables. Many fields, that were not required made empty insert to database unnecessarily(where You could and should avoid), so...I've decided to create each form separately using each independent components by:
Each input as component had provided validators in it so no worries about validation pf field in each form. Example:
parentForm in parent component:
parentForm: FormGroup
in child component:
@Input() parentForm: FormGroup;
And that's it. It could be done with 1 form displaying inputs depending on parameters or path but it makes more sense to create separate form via
FormBuilder
rather than having 1 form for every place that requires it.