I have one reactive form in angular 7 which has three fields email, phone and pager. My requirement is that at least one of them should be filled out by user otherwise we should throw error like this "Please specify one of the notifications (Email, SMS or Pager)."
I have tried writing a custom notification but its not working. Could you please help me that where I am going wrong.
Below is my HTML code:
<form class="form-horizontal" [formGroup]="editorForm">
<div class="form-group" required>
<label for="emailAdressInput">Email Addresses</label>
<input type="text" id="emailAdressInput" formControlName="emailAdresses">
</div>
<div class="form-group" required>
<label for="phoneNumberInput">Email Addresses</label>
<input type="text" id="phoneNumberInput" formControlName="phoneNumber">
</div>
<div class="form-group" required>
<label for="pagerNumberInput">Email Addresses</label>
<input type="text" id="pagerNumberInput" formControlName="pagerNumber">
</div>
</form>
Below is component.ts code:
this.editorForm = this._formBuilder.group({
displayLabel: ['', Validators.required],
emailAdresses: [''],
phoneNumber: [''],
notification: this._formBuilder.group({
pagerNumber: [''],
phoneNumber: [''],
emailAdresses: ['']
}, this.atLeastOneValidator()),
pagerNumber: [''],
});
public atLeastOneValidator = () => {
return (controlGroup) => {
let controls = controlGroup.controls;
if ( controls ) {
let theOne = Object.keys(controls).find(key=> controls[key].value!=='');
if ( !theOne ) {
return {
atLeastOneRequired : {
text : 'At least one should be selected'
}
}
}
}
return null;
};
};
I have solved it in stackblitz : https://stackblitz.com/edit/angular-j3i4yg
export class AppComponent {
name = 'Angular';
editorForm: FormGroup;
// _formBuilder: FormBuilder = new FormBuilder();
constructor(private _formBuilder: FormBuilder) {
this.editorForm = this._formBuilder.group({
displayLabel: ['', Validators.required],
emailAdresses: [''],
phoneNumber: [''],
notification: this._formBuilder.group({
pagerNumber: [''],
phoneNumber: [''],
emailAdresses: ['']
}, { validators: this.atLeastOneValidator }),
pagerNumber: [''],
});
}
public atLeastOneValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
let controls = control.controls;
console.log(controls);
if (controls) {
let theOne = Object.keys(controls).findIndex(key => controls[key].value !== '');
if (theOne === -1) {
console.log(theOne);
return {
atLeastOneRequired: {
text: 'At least one should be selected'
}
}
}
};
}
}
Template :
<form class="form-horizontal" [formGroup]="editorForm">
<fieldset formGroupName="notification">
<div class="form-group" required>
<label for="emailAdressInput">Email Addresses</label>
<input type="text" id="emailAdressInput" formControlName="emailAdresses">
</div>
<div class="form-group" required>
<label for="phoneNumberInput">Email Addresses</label>
<input type="text" id="phoneNumberInput" formControlName="phoneNumber">
</div>
<div class="form-group" required>
<label for="pagerNumberInput">Email Addresses</label>
<input type="text" id="pagerNumberInput" formControlName="pagerNumber">
</div>
</fieldset>
{{editorForm.get('notification')?.errors| json}}
<br>
<br>
<span *ngIf="editorForm.get('notification')?.errors?.atLeastOneRequired"> {{editorForm.get('notification')?.errors?.atLeastOneRequired.text}}</span>
</form>
Check and let me know if you have any doubts.