I have a dropdown and two text-boxes in Angular HTML. I would like to implement a functionality where, if the 'payable_frequency' dropdown is selected, then either of the 'payable_commission' fields(min or max) becomes required and able to display a mat-error message. Otherwise, both payable_commission fields are not required. I attempted to use (selectionChange)="customFunction($event.value)"
and min_payable_commission:['',[customValidatorFunction]],
but neither approach worked. Kindly provide a solution to this issue. I prefer not to directly use [Validator.required] in the .ts file or the "required" keyword in the .html file.
ngOnInit(): void {
this.couauiChargesForm = this.formBuilder.group({
id: [''],
payable_frequency_ref_id:[''],
min_payable_commission:[''],
max_payable_commission:[''],
});
}
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12">
<mat-label>Payable Frequency</mat-label>
<mat-form-field class="example-full-width" appearance="outline">
<mat-select formControlName="payable_frequency_ref_id">
<mat-option value="" >Select Payable Frequency</mat-option>
<mat-option [value]="data.id" *ngFor="let data of billingFrequencyData">{{ data.master_key }}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12">
<div class="form-group">
<mat-label>Min Payable Commission</mat-label>
<mat-form-field class="example-full-width" appearance="outline">
<input matInput formControlName="min_payable_commission" type="number" placeholder="0">
<mat-error *ngIf="couauiChargesForm.get('min_payable_commission')">This Field is required!</mat-error>
</mat-form-field>
</div>
</div>
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12">
<div class="form-group">
<mat-label>Max Payable Commission</mat-label>
<mat-form-field class="example-full-width" appearance="outline">
<input matInput formControlName="max_payable_commission" type="number" min="0" placeholder="0">
<mat-error *ngIf="couauiChargesForm.get('max_payable_commission')">This Field is required!</mat-error>
</mat-form-field>
</div>
</div>
There are a couple of ways to do this.
The method I prefer is to define a custom validator function that checks the value of payable_frequency_ref_id and just returns null if is not set. https://angular.io/guide/form-validation#defining-custom-validators.
So, something like this:
// I'm not familiar with the Form Builder, so I wrote it out.
public couauiChargesForm: FormGroup = new FormGroup({
id: new FormControl(''),
min_payable_commission: new FormControl('', this.commissionValidator),
max_payable_commission: new FormControl('', this.commissionValidator)
});
private commissionValidator(control: FormControl) {
const refId = this.couauiChargesForm.controls.payable_frequency_ref_id.value;
if (refId) {
if (!control.value) {
return {required: 'this field is required'};
}
}
return null;
}
Another method is to programmatically add and remove validators from your min and max controls, when reacting to form control value changes. You have to subscribe to payable_frequency_ref_id's valueChange event (remember to unsubscribe in onDestroy!), then you can add and remove validators from your other controls. Then call each control's UpdateValueAndValidity() method. Not my preferred approach however.