Reputation: 1064
Consider I have two forms on the page, and implemented a wizard like stepper, and have put each of my forms on the stepper's each steps. Now I want to make a field on second form required, if certain value in first form selected.
see below code, the rechargeCode in second form, is related to the operator which is selected in first form. and if some specific operator selected, the rechargeCode should be mandatory.
<mat-vertical-stepper class="mat-elevation-z4" [linear]="true">
<mat-step [stepControl]="verticalStepperStep1">
<div fxLayout="row" fxLayoutAlign="center">
<form fxLayout="column" [formGroup]="verticalStepperStep1" fxFlex="50">
<ng-template matStepLabel>operator select</ng-template>
<div fxFlex="1 1 auto" fxLayout="column">
<mat-form-field appearance="" class="right-align" fxFlex="100">
<mat-label>operator</mat-label>
<mat-select formControlName="operator" (selectionChange)="operatorChanged()" required>
<mat-option *ngFor="let item of operatorList" value="{{item.value}}">
{{item.name}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div fxLayout="row" fxLayoutAlign="center center">
<button fxFlex="20" fxFlex.lt-md="50" mat-raised-button matStepperNext type="button" color="accent">
next
</button>
</div>
</form>
</div>
</mat-step>
<mat-step [stepControl]="verticalStepperStep2">
<div fxLayout="row" fxLayoutAlign="center">
<form fxLayout="column" [formGroup]="verticalStepperStep2" fxFlex="50">
<ng-template matStepLabel>mobile number</ng-template>
<div fxFlex="1 0 auto" fxLayout="row" fxLayoutAlign="center">
<mat-form-field appearance="" class="right-align" fxFlex="100">
<mat-label>mobile number</mat-label>
<input matInput type="tel" formControlName="msisdn" required>
</mat-form-field>
<mat-form-field class="right-align" fxFlex="100">
<mat-select formControlName="rechargeCode">
<mat-option *ngFor="let item of rechargeCodeList" value="{{item.value}}">
{{item.name}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div fxLayout="row" fxLayoutAlign="center center">
<button fxFlex="20" fxFlex.lt-md="50" mat-raised-button matStepperPrevious type="button" color="accent">
previous
</button>
<button fxFlex="20" fxFlex.lt-md="50" mat-raised-button matStepperNext type="button" color="accent">
next
</button>
</div>
</form>
</div>
</mat-step>
<mat-step>
<ng-template matStepLabel>final step</ng-template>
<div class="h2 m-16" fxLayout="row" fxLayoutAlign="center center">
<div class="card-preview">
<div class="fuse-card">
<div class="p-16">
<div class="h1">final</div>
</div>
<div class="card-divider"></div>
<div class="p-16 pt-4">
<div class="mb-12" fxLayout="row" fxLayoutAlign="space-between center">
<div>
<div *ngIf="this.verticalStepperStep2.get('msisdn')" class="h2 secondary-text">شماره موبایل: {{this.verticalStepperStep2.get('msisdn').value}}</div>
</div>
</div>
<div class="mb-12" fxLayout="row" fxLayoutAlign="space-between center">
<div>
<div *ngIf="this.verticalStepperStep1.get('amount')" class="h2 secondary-text">مبلغ قابل پرداخت: {{this.verticalStepperStep1.get('amount').value}} ريال</div>
</div>
</div>
</div>
</div>
</div>
</div>
</mat-step>
what can I do?
Upvotes: 1
Views: 732
Reputation: 2966
there are many options, for example
you can check first form's field and use setVAlidataors
for second form to assign new validator, for example
if (this.firstForm.get('formControlThatYouNeed').value) {
this.secondForm.get('formControlYouNeedToUpdate').setValidators([Validator.required]);
}
don't forget to include other validators(if you have for this control) in setVAlidataors
array as this method removes old validators.
Also you can create custom Validator for example
customValidator(firstFormFieldValue: any): ValidatorFn {
return (control: AbstractControl | null) => {
if (firstFormFieldValue.notSelected) {
return null;
}
const error = Validators.required(control);
if (error) {
const firstError = Object.keys(error)[0];
return { [firstError]: { message } };
}
return null;
}
}
and use it like so
this.fb.group({
field: ['fieldValue', [this.customValidator(this.firstFormFieldValue)]],
}));
Upvotes: 1