TikChiku
TikChiku

Reputation: 413

Error messages according to the validation patterns in Angular

I would like to divide the error messages according to the validation patterns,for example, in below, there are 2 patterns

Validators.pattern(/[^ +]/), Validators.pattern(/^[ +|a-zA-Z0-9]+$/),

but only one message can be set.

<md-error *ngIf="locaCd.errors?.pattern"> onny blank is unacceptable AND must be filled by a~z,A~Z or number. </md-error>

Is there anyway to divide into each witout making CustomValidation??

enter image description here

enter image description here

Upvotes: 8

Views: 26457

Answers (4)

Akim Zadeh
Akim Zadeh

Reputation: 1

export function patternValidator(pattern: string | RegExp, errorMessage: string): ValidatorFn {
  const patternValidator = Validators.pattern(pattern);

  return (control: AbstractControl): ValidationErrors | null => {
    const validationResult = patternValidator(control);

    if (validationResult) {
      return { pattern: errorMessage };
    }
    return null;
  };
}
// Usage
this.myForm = this.fb.group({
      name: ['', [
        Validators.required,
        patternValidator(/^[a-z0-9][a-z0-9-_]*$/, 'Name can only contain lowercase letters, numbers, hyphens, and underscores, and must start with a letter or number')
      ]]
    });

Upvotes: 0

kctang
kctang

Reputation: 11202

Here is ValidatorFn that delegates validation to Validators.pattern but returns an object with message key on validation error.

const patternWithMessage = (pattern: string | RegExp, message: string): ValidatorFn => {
    const delegateFn = Validators.pattern(pattern)
    return control => delegateFn(control) === null ? null : { message }
}

With this, template can show value of message on validation error.

e.g. patternWithMessage(/^[a-zA-Z_][a-zA-Z_0-9]*$/, 'Invalid value for key')

Upvotes: 2

John
John

Reputation: 11429

You could use the same pattern expression inside your md-error, and separate them into two different div-elements, matching one and the other

EDIT after testing myselv, I found that you need to execute the matching using a regepx from typescript (at least thats how I made it work)

in your component, define yout regexp

emptyRegExp = new RegExp(/[^ +]/);
letterNumberRegExp = new RegExp(/^[ +|a-zA-Z0-9]+$/);

then use those expressions in your html to display the desired error message.

<md-error *ngIf="locaCd.errors?.pattern">
   <div *ngIf="emptyRegExp.exec(locaCd?.value)"> Blank is unacceptable.</div>
   <div *ngIf="letterNumberRegExp.exec(locaCd?.value))">Must be filled by a~z,A~Z or number.</div>
</md-error>

Upvotes: 0

mayur
mayur

Reputation: 3618

By default Validators.pattern() accepts parameter as pattern: string | RegExp so i will better suggest you to create you custom validation which handle a single method can handle dynamically for you.

For example demo.component.ts

import { FormGroup, FormControl, Validators, ValidatorFn } from '@angular/forms';

this.form = new FormGroup({
   email: new FormControl('', [
    this.customPatternValid({ pattern: /[A-Z]/, msg: 'Small characters not allowed' }),
    this.customPatternValid({ pattern: /^([^0-9]*)$/, msg: 'Numbers is not allowed' })
   ]),
   password: new FormControl('', [
    Validators.required
   ])
});

// Create our customPatternValid function 

public customPatternValid(config: any): ValidatorFn {
    return (control: FormControl) => {
      let urlRegEx: RegExp = config.pattern;
      if (control.value && !control.value.match(urlRegEx)) {
        return {
          invalidMsg: config.msg
        };
      } else {
        return null;
      }
    };
}

For example demo.component.html

<form [formGroup]="form">
  <input type="email" placeholder="Email" formControlName="email"/>

  <div *ngIf="!form.controls.email.valid && (form.controls.email.dirty ||form.controls.email.touched)" class="error">
    <div *ngIf="form.controls.email.errors.invalidMsg">
      {{form.controls.email.errors.invalidMsg}}
    </div>
  </div>
</form>

Upvotes: 9

Related Questions