Ashok Prabhu
Ashok Prabhu

Reputation: 43

Angular cross field validation and custom validation together

I have open, close fields for 7 days. open and close parameter either can have hh:mm or the word 'Closed'. So each open and close field has regex validations to match hh:mm or 'Closed' word. Also I'm trying to add additional cross field validation to ensure one of the field in day not to be Closed. if both are closed, its ok, but not one of it.

enter image description here

Code seems working if I have either one of the validations, but if I have both of them, its not working. I try to put the sample code together in stackblitz.

https://stackblitz.com/angular/qvjapnglrrp

regex validation

validateInput(c: FormControl) {
    const hourMinpattern = /^([0-1][0-9]|[2][0-3]):([0-5][0-9])$/;
    const closedPattern = /^Closed$/;
    return hourMinpattern.test(c.value) || closedPattern.test(c.value)
      ? null
      : {
          validateInput: {
            valid: false
          }
        };
  }

cross field validation

mondayOpenCloseValidator(formGroup: FormGroup): ValidationErrors | null {
    const open = formGroup.get("mondayOpen");
    const close = formGroup.get("mondayClose");

    if (
      (open.value === "Closed" || close.value === "Closed") &&
      open.value !== close.value
    ) {
      close.setErrors({ badState: true });
      close.markAllAsTouched();
      return { badState: true };
    }

    close.setErrors(null);                
    return null;
  }

form builder

this.editForm = this.formBuilder.group(
  {
    mondayOpen: new FormControl({ value: "", disabled: false }, [
      Validators.required,
      this.validateInput
    ]),
    mondayClose: new FormControl({ value: "", disabled: false }, [
      Validators.required,
      this.validateInput
    ]),
    tuesdayOpen: new FormControl({ value: "", disabled: false }, [
      Validators.required,
      this.validateInput
    ]),
    tuesdayClose: new FormControl({ value: "", disabled: false }, [
      Validators.required,
      this.validateInput
    ])
  },
  {
    validator: [
      this.mondayOpenCloseValidator,
      this.tuesdayOpenCloseValidator
    ]
  }
);

Upvotes: 0

Views: 319

Answers (1)

Gabriel H
Gabriel H

Reputation: 1576

i think your problem is with the custom validator - at the end of validation you erase all of the errors including those of other validators -

remove this line:

close.setErrors(null);

so resulting code will look like:

ondayOpenCloseValidator(formGroup: FormGroup): ValidationErrors | null {
    const open = formGroup.get("mondayOpen");
    const close = formGroup.get("mondayClose");

    if (
      (open.value === "Closed" || close.value === "Closed") &&
      open.value !== close.value
    ) {
      close.setErrors({ badState: true });
      close.markAllAsTouched();
      return { badState: true };
    }
            
    return null;
  }

Upvotes: 1

Related Questions