Last active
August 21, 2020 14:06
-
-
Save kmaida/9fc502c722ed36fca2aa09ecfce46d1e to your computer and use it in GitHub Desktop.
Angular Date Validator - directive and factory - validates strings m/d/yyyy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// MM/DD/YYYY, M/D/YYYY | |
const DATE_REGEX = new RegExp(/^(\d{2}|\d{1})\/(\d{2}|\d{1})\/\d{4}$/); | |
export { DATE_REGEX }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<input | |
id="endDate" | |
name="endDate" | |
type="text" | |
class="form-control" | |
#endDate="ngModel" | |
appDateField | |
required | |
[(ngModel)]="form.endDate"> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Directive } from '@angular/core'; | |
import { NG_VALIDATORS, Validator, ValidatorFn, FormControl } from '@angular/forms'; | |
import { dateValidator } from './validateDate.factory'; | |
@Directive({ | |
selector: '[appDateField]', | |
providers: [ | |
{ provide: NG_VALIDATORS, useExisting: ValidateDateDirective, multi: true } | |
] | |
}) | |
export class ValidateDateDirective implements Validator { | |
private _valFn: ValidatorFn; | |
constructor() { | |
this._valFn = dateValidator(); | |
} | |
validate(control: FormControl) { | |
return this._valFn(control); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { AbstractControl, ValidatorFn } from '@angular/forms'; | |
import { DATE_REGEX } from './formUtils.factory'; | |
export function dateValidator(): ValidatorFn { | |
return (control: AbstractControl): {[key: string]: any} => { | |
const dateStr = control.value; | |
// Length of months (will update for leap years) | |
const monthLength = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]; | |
// Object to return if date is invalid | |
const invalidObj = { 'date': true }; | |
// First check for m/d/yyyy or mm/dd/yyyy format | |
// If the pattern is wrong, don't validate dates yet | |
if (!DATE_REGEX.test(dateStr)) { | |
return null; | |
} | |
// Parse the date input to integers | |
const parts = dateStr.split('/'); | |
const month = parseInt(parts[0], 10); | |
const day = parseInt(parts[1], 10); | |
const year = parseInt(parts[2], 10); | |
// Make sure date is in range | |
if (year < 2000 || year > 3000 || month === 0 || month > 12) { | |
return invalidObj; | |
} | |
// Adjust for leap years | |
if (year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0)) { | |
monthLength[1] = 29; | |
} | |
// Check the range of the day | |
if (!(day > 0 && day <= monthLength[month - 1])) { | |
return invalidObj; | |
}; | |
return null; | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment