1 import { Directive, Input } from "@angular/core";
2 import { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator, ValidatorFn } from "@angular/forms";
3 import * as moment from "moment";
5 export function datesInOrderValidator(fieldNames: string[]): ValidatorFn {
6 return (control: AbstractControl): {[key: string]: any} | null => {
7 if (fieldsAreInOrder(fieldNames, control)) return null;
8 return {datesOutOfOrder: 'Dates should be in order'};
12 function fieldsAreInOrder(fieldNames: string[], control: AbstractControl): boolean {
13 if (fieldNames.length === 0) return true;
14 return fieldNames.every((field, index) => {
15 // No need to compare field[0] to the field before it
16 if (index === 0) return true;
18 const previousValue = moment(control.get(fieldNames[index - 1])?.value);
19 const currentValue = moment(control.get(field)?.value);
21 // If either field is invalid, return true -- there should be other
22 // validation that can catch that
23 if (!previousValue.isValid() || !currentValue.isValid()) return true;
25 // Check each field against its predecessor
26 return previousValue.isSameOrBefore(currentValue);
31 selector: '[egDateFieldOrderList]',
32 providers: [{ provide: NG_VALIDATORS, useExisting: DatesInOrderValidatorDirective, multi: true }]
34 export class DatesInOrderValidatorDirective implements Validator {
35 @Input('egDateFieldOrderList') dateFieldOrderList = '';
36 validate(control: AbstractControl): ValidationErrors | null {
37 if (this.dateFieldOrderList?.length > 0) {
38 return datesInOrderValidator(this.dateFieldOrderList.split(','))(control);
40 // Don't run validations if we have no fields to examine