LP1879517: Surveys shouldn't end before they begin
[evergreen-equinox.git] / Open-ILS / src / eg2 / src / app / share / validators / dates_in_order_validator.directive.ts
1 import { Directive, Input } from "@angular/core";
2 import { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator, ValidatorFn } from "@angular/forms";
3 import * as moment from "moment";
4
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'};
9     };
10 }
11
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;
17
18         const previousValue = moment(control.get(fieldNames[index - 1])?.value);
19         const currentValue = moment(control.get(field)?.value);
20
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;
24
25         // Check each field against its predecessor
26         return previousValue.isSameOrBefore(currentValue);
27     });
28 }
29
30 @Directive({
31     selector: '[egDateFieldOrderList]',
32     providers: [{ provide: NG_VALIDATORS, useExisting: DatesInOrderValidatorDirective, multi: true }]
33   })
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);
39       } else {
40         // Don't run validations if we have no fields to examine
41         return () => {null}
42       }
43     }
44   }