The typescript for the component is:
export class EtcAddAuthorityComponent implements OnInit {
addAuthorityForm: FormGroup;
authTypes: any[] = [];
loading = false;
numericRegex = /^[0-9]*$/;
alphabeticRegex = /^[a-zA-Z]*$/;
constructor(
private readonly dialogRef: MatDialogRef<EtcAddAuthorityComponent>,
private readonly fb: FormBuilder,
private readonly toastr: ToastrService,
private readonly ecmService: EcmService,
private readonly ecmToolChangeService: EcmToolChangeService,
private readonly cgpAlertDialogService: CgpAlertDialogService,
@Inject(MAT_DIALOG_DATA) public readonly selectedTool: any
) {
this.addAuthorityForm = this.fb.group({
authNumber: ['', [Validators.maxLength(20), Validators.pattern(this.alphabeticRegex)]],
authNumberN: ['', [Validators.required, Validators.maxLength(20), Validators.pattern(this.numericRegex)]],
authTypeName: ['', [Validators.required, Validators.maxLength(10)]],
authDescription: ['', [Validators.maxLength(500)]]
});
}
ngOnInit() {
this.loading = true;
this.ecmService.getAuthTypeCriteria()
.subscribe({
next: (res) => {
if (res) {
this.authTypes = res;
}
},
complete: () => this.loading = false
});
}
onCancelClick() {
this.dialogRef.close();
}
onAddClick() {
const authNFieldifAuthTypeName = this.authFieldCheck();
if (authNFieldifAuthTypeName === true) {
return;
}
else {
const body = {
...this.addAuthorityForm.value,
partChangeId: this.selectedTool.partChangeId,
toolChangeId: this.selectedTool.toolChangeId
};
this.loading = true;
this.ecmToolChangeService.addAuthority(body)
.subscribe({
next: (res) => {
this.cgpAlertDialogService.showAlertDialog({
title: 'Add Authority',
message: 'Authority was added successfully!',
alert: cgpAlertTypes.success,
closeLabel: 'OK'
}).afterClosed().subscribe(() => this.dialogRef.close({ reload: true }));
},
error: (err) => {
this.loading = false;
this.cgpAlertDialogService.showAlertDialog({
title: 'Add Authority',
message: 'Authority could not be added. Please try again!',
alert: cgpAlertTypes.danger,
closeLabel: 'OK'
});
},
complete: () => this.loading = false
});
}
}
authFieldCheck(): boolean {
const matched: boolean = (this.addAuthorityForm.controls.authTypeName.value === 'EWO') && (!this.addAuthorityForm.controls.authNumber.value);
if (matched) {
this.addAuthorityForm.controls.authTypeName.setErrors({
notFilled: true
});
}
else {
this.addAuthorityForm.controls.authTypeName.setErrors({ notMatched: false });
}
return matched;
}
}
The html code is:
<h1 mat-dialog-title>Add Authority</h1>
<div mat-dialog-content>
<form class="flex-dialog-container" [formGroup]="addAuthorityForm">
<mat-form-field>
<mat-label>Authority #(alpha)</mat-label>
<input matInput autocomplete="off" formControlName="authNumber" #authNumber>
<mat-error *ngIf="authNumber.value?.length > 20">Cannot exceed 20 characters.</mat-error>
</mat-form-field>
<mat-form-field>
<mat-label>Authority #(numeric)</mat-label>
<input matInput autocomplete="off" formControlName="authNumberN" #authNumberN>
<mat-error *ngIf="addAuthorityForm.controls.authNumberN.hasError('required')">Required</mat-error>
<mat-error *ngIf="authNumberN.value?.length > 20">Cannot exceed 20 characters.</mat-error>
</mat-form-field>
<mat-form-field>
<mat-label>Authority Type</mat-label>
<mat-select formControlName="authTypeName">
<mat-option *ngFor="let at of authTypes" [value]="at.authTypeName">
{{at.authTypeName}}
</mat-option>
</mat-select>
<mat-error *ngIf="addAuthorityForm.controls.authTypeName.hasError('required')">Required</mat-error>
<mat-error *ngIf=" this.addAuthorityForm.controls.authTypeName.hasError('notFilled')">Authority #(alpha) required</mat-error>
</mat-form-field>
<mat-form-field>
<mat-label>Authority Description</mat-label>
<input matInput autocomplete="off" formControlName="authDescription" #authDescription>
<mat-error *ngIf="authDescription.value?.length > 500">Cannot exceed 500 characters.</mat-error>
</mat-form-field>
</form>
</div>
<div mat-dialog-actions class="mat-dialog-actions-end no-margin">
<button mat-raised-button mat-dialog-close cdkFocusInitial (click)="onCancelClick()"
(keypress.enter)="onCancelClick()">Cancel</button>
<button mat-raised-button color="primary" (click)="onAddClick()" (keypress.enter)="onAddClick()" [disabled]="addAuthorityForm.invalid">Add</button>
</div>
This is my add dialog box: The Add dialog box
How to add a custom validation so that if 'EWO' option is chosen for the 'Authority Type' dropdown, it would show an error if the 'Authority# (Alpha)' is not entered. But it should not show any error if the 'EWO' option is chosen for the 'Authority Type' dropdown.
You can disable the "Authority" if you don't choose EWO, so Angular not check if is required or not. To disable/enable you need use the methods disable and enable
You can use a directive to disable/enable the control, subscribe to valueChanges or, as you're using a mat-select, use the event selectionChange like (*):
<mat-select formControlName="authTypeName"
(selectionChange)="addAuthorityForm.get('authDescription')
[$event.value=='EWO'?'enable':'disable']()">
<mat-option *ngFor="let at of authTypes" [value]="at.authTypeName">
{{at.authTypeName}}
</mat-option>
</mat-select>
I make a simple stackblitz
(*) don't forget, when create the formgroup, create the control enabled or disabled
Update if we don't want disable the control, really we need create a custom Form control Validation.
We can make a custom form Control Validation over a FormControl, a FormGroup or a FormArray. In this case we choose make it over a FromControl. But we need take account that, is we change the authTypeName
, we need indicate to Angular that check if the authDescription
is validate or not
<mat-select formControlName="authTypeName"
(selectionChange)="form.get('authDescription').updateValueAndValidity()">
...
</mat-select>
Well, our custom Form validation. As we has the "control", in control.parent" we has the "form", so it's so easy like
requiredIf(requiredValue:string){
return (control:FormControl)=>{
const form=control.parent;
if (form)
{
//really we need decalre controlDescription, it's the
//same of "control"
const controlDescription=form.get('authDescription')
const controlTypeName=form.get('authTypeName')
if (controlTypeName && controlDescription &&
controlTypeName.value==requiredValue && !controlDescription.value)
return {required:true}
}
return null
}
}
And we can write
form=new FormGroup({
authDescription:new FormControl(null,this.requiredIf('EWO')),
authTypeName:new FormControl('EWO')
})
See that the value 'EWO' is fixed when declare the formGroup
the new stackblitz