How to differentiate multiple Validators.pattern

浪子不回头ぞ 提交于 2019-12-05 05:07:19

Unfortunately it is not possible to give Validators a custom identifier.

UPDATE 17.02.2018 21:00

As Dawid Zbinski mentioned in the comments that multiple errors with the same error (e.g.: 'pattern') getting override, I updated my answer.

Create a custom validator which gets passed the regex and a predefined error as an argument:

  regexValidator(regex: RegExp, error: ValidationErrors): ValidatorFn {
    return (control: AbstractControl): {[key: string]: any} => {
      if (!control.value) {
        return null;
      }
      const valid = regex.test(control.value);
      return valid ? null : error;
    };
  }

and use it like this:

  this.longitude = new FormControl('', [
    this.regexValidator(new RegExp('^[0-9]+$'), {'number': ''}),
    this.regexValidator(new RegExp('^.{5,}$'), {'precision': ''})
  ]);
  <mat-form-field class="form-field">
    <input matInput placeholder="Logitude" [formControl]="longitude">
    <mat-error *ngIf="longitude.hasError('number')">
        Longitude must be <strong>a number</strong>
    </mat-error>
    <!-- I want to be able to check patter2 for example -->
    <mat-error *ngIf="longitude.hasError('precision')">
        Longitude must have <strong>a minimum of 5 decimal numbers</strong>
    </mat-error>
</mat-form-field>

I also updated the stackblitz demo: https://stackblitz.com/edit/angular-dvwcj3?file=app%2Fhello.component.ts

OLD ANSWER:

But the PatternValidators are returning unique ValidatonErrorObjects.

When you check out the source code from the pattern validator at the official angular repo you can see they always return the regex inside the error object.

return (control: AbstractControl): ValidationErrors | null => {
  if (isEmptyInputValue(control.value)) {
    return null;  // don't validate empty values to allow optional controls
  }
  const value: string = control.value;
  return regex.test(value) ? null :
                             {'pattern': {'requiredPattern': regexStr, 'actualValue': value}};
};

With this in mind you can easily create two getter methods inside your component.ts file. And they differ between the two regular expressions. In this example they simply check if an unique substring matches the regular expression. For sure they are other ways to handle this.

  get numberError() {
    if (this.longitude && this.longitude.hasError('pattern')) {
      return this.longitude.getError('pattern').requiredPattern.indexOf('(\d+)') !== -1
    }
    return false;
  }

  get preciseError() {
    if (this.longitude && this.longitude.hasError('pattern')) {
      return this.longitude.getError('pattern').requiredPattern.indexOf('(\-{0,1})') !== -1
    }
    return false;
  }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!