Reputation: 113
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.
Upvotes: 0
Views: 940
Reputation: 58029
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
Upvotes: 0
Reputation: 36
I'm not sure what you meant when you say "But it should not show any error if the 'EWO' option is chosen for the 'Authority Type' dropdown.". I'll assume that it should not show any error if the 'Authority# (Alpha)' is not entered for that scenario.
There could be better solution out there but here's the approach that I use in my projects. You can put this block after form initialization so the form already has these auth type and auth number controls to access:
this.addAuthorityForm.get('authTypeName').valueChanges.subscribe((newValue) => {
const authNumber = this.addAuthorityForm.get('authNumber');
// I don't know the exact structure of the authTypeName so you can debug and change the condition if needed
if (newValue === 'EWO') {
authNumber.setValidators([Validators.required, Validators.maxLength(20), Validators.pattern(this.alphabeticRegex)]);
} else {
authNumber.setValidators([Validators.maxLength(20), Validators.pattern(this.alphabeticRegex)]);
}
authNumber.updateValueAndValidity();
})
Basically, what this does is reassign the validators for the auth number when the auth type change by adding the required validators. I use Validators.required
because it's provided out of the box but if you want to make it more custom, you can have something like this:
...
authNumber.setValidators([(c: FormControl) => {
return c.value ? null : {required: {valid: false}};
}, Validators.maxLength(20), Validators.pattern(this.alphabeticRegex)]);
...
The updateValueAndValidity
method is to revalidate the field when user switches the auth type.
Upvotes: 0