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