Is there a way to check if a user is over 18 years of age when they have entered their date of birth using Angular Validators?
My form looks like this:
<form [formGroup]="authForm" (ngSubmit)="submitForm()">
<label>Date of birth</label>
<input formControlName="day" maxlength="2" placeholder="DD" type="text" />
<input formControlName="month" maxlength="2" placeholder="MM" type="text" />
<input formControlName="year" maxlength="4" placeholder="YYYY" type="text" />
<button [disabled]="!authForm.valid" type="submit"> Check age </button>
</form>
And then I have these validators set in the TS file:
if (this.authType === 'register') {
this.authForm.addControl('year', new FormControl('', [Validators.required, Validators.maxLength(4), Validators.minLength(4)]));
this.authForm.addControl('month', new FormControl('', [Validators.required, Validators.maxLength(2)]));
this.authForm.addControl('day', new FormControl('', [Validators.required, Validators.maxLength(2)]));
}
So if the conditions above are satisfied in the Validators, the button becomes enabled. But I also need to check that the entered date is over 18 years old before enabling it. This seems tricky as the date is entered via 3 inputs (dd, mm, yyyy). And in this case, I can't use the input date tag. Any suggestions or comments appreciated. Thanks!
P.S. Thanks for all the suggestions about using MomentJS. I'm already using it elsewhere in the app so I'll also use it here.
You need to configurate a custom validator that will be hooked to the complete FormGroup
in this case.
A momentjs based approach would look like this:
export function minimumAge(age:number): ValidatorFn {
return (fg: FormGroup): ValidationErrors => {
let result: ValidationErrors = null;
if (fg.get('year').valid && fg.get('month').valid && fg.get('day').valid) {
// carefull, moment months range is from 0 to 11
const value: { year: string, month: string, day: string } = fg.value;
const date = moment({ year: +value.year, month: (+value.month) - 1, day: +value.day }).startOf('day');
if (date.isValid()) {
// https://momentjs.com/docs/#/displaying/difference/
const now = moment().startOf('day');
const yearsDiff = date.diff(now, 'years');
if (yearsDiff > -age) {
result = {
'minimumAge': {
'requiredAge': age,
'actualAge': yearsDiff
}
};
}
}
}
return result;
};
}
export class DateEditComponent {
readonly authForm: FormGroup;
constructor(private _fb: FormBuilder) {
this.authForm = this._fb.group({
year: ['', [Validators.required, Validators.maxLength(4), Validators.minLength(4)]],
month: ['', [Validators.required, Validators.maxLength(2)]],
day: ['', [Validators.required, Validators.maxLength(2)]]
});
this.authForm.setValidators(minimumAge(18));
}
}
For a live example please check here
Notice that in this case Im not taking care of any format/range validation on the singular input fields.
No, you'd have to make your custom validator. This validator would also have to be placed on the entire FormGroup, instead of just a single FormControl as the validation needs to run whenever any of the 3 inputs value changes.
How you implement the validation is up to you since this involves dates, but I always use momentjs to work with dates.