¿Cómo agregar un patrón de validación de formulario en Angular 2?


Tengo un formulario simple que necesita validar si el principio y el final de la entrada no es espacio.

En HTML5, haré esto:

<input type="text" pattern="^(?!\s|.*\s$).*$">

¿Cuál es la propiedad correcta para el patrón de validación en la nueva directiva Angular 2 ngControl? La API Beta oficial todavía carece de documentación sobre este tema.

Author: Matheus Lacerda, 2016-01-01

5 answers

Ahora, no necesitas usar FormBuilder y todas estas complicadas cosas angulares de valiación. Puse más detalles de esto (Angular 2.0.8-3march2016): https://github.com/angular/angular/commit/38cb526

Ejemplo de repo:

<input [ngControl]="fullName" pattern="[a-zA-Z ]*">

Lo pruebo y funciona:) - aquí está mi código:

<form (ngSubmit)="onSubmit(room)" #roomForm='ngForm'  >
...
<input 
  id='room-capacity' 
  type="text" 
  class="form-control" 
  [(ngModel)]='room.capacity' 
  ngControl="capacity" 
  required
  pattern="[0-9]+" 
  #capacity='ngForm'>

ACTUALIZACIÓN de junio de 2017

Solo quiero decir que actualmente, cuando tengo más experiencia, normalmente uso un enfoque "barato" para los datos validación:

La validación es SOLO en el lado del servidor (¡no en angular en absoluto!) y si algo está mal, entonces el servidor (Restful API) devuelve algún código de error, por ejemplo HTTP 400 y el siguiente objeto json en el cuerpo de respuesta (que en angular pongo a err variable):

this.err = { 
    "capacity" : "too_small"
    "filed_name" : "error_name", 
    "field2_name" : "other_error_name",
    ... 
}

(si el servidor devuelve un error de validación en un formato diferente, generalmente puede mapearlo fácilmente a la estructura anterior)

En la plantilla html uso una etiqueta separada (div / span / small, etc.)

<input [(ngModel)]='room.capacity' ...>
<small *ngIf="err.capacity" ...>{{ translate(err.capacity) }}</small>

As usted ve, cuando hay algún error en' capacidad ' entonces la etiqueta con la traducción del error (al idioma del usuario) será visible. Este enfoque tiene las siguientes ventajas:

  • es muy simple
  • en angular no duplicamos el código de validación que está (y debe estar) en el servidor (en caso de validación de expresiones regulares esto puede prevenir o complicar Rehacer ataques)
  • tenemos control total sobre la forma en que se mostrará el error al usuario (aquí como egzample en <small> tag)
  • debido a que en la respuesta del servidor devolvemos error_name (en lugar de mensaje de error directo), podemos cambiar fácilmente el mensaje de error (o traducirlo) modificando solo el código frontend-angular (o archivos con traducciones). Así que en ese caso no necesitamos tocar el código backend / server.

Por supuesto a veces (si esto es necesario-por ejemplo. Campo retypePassword que nunca se envía al servidor) Hago excepciones del enfoque anterior y hago alguna validación en angular (pero uso similar "this.err " mecanismo para mostrar errores (así que no uso el atributo pattern directamente en la etiqueta input sino que hago la validación de expresiones regulares en algún método de componente después de que el usuario genere el evento adecuado como input-change o save) .

 46
Author: Kamil Kiełczewski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-20 12:42:45

Desde la versión 2.0.0-beta.8 (2016-03-02), Angular ahora incluye un Validators.pattern validador de expresiones regulares.

Ver la LISTA DE CAMBIOS

 9
Author: Chris Snowden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-30 06:38:13

Puede construir su formulario usando FormBuilder, ya que le permite una forma más flexible de configurar el formulario.

export class MyComp {
  form: ControlGroup;

  constructor(@Inject()fb: FormBuilder) {  
    this.form = fb.group({  
      foo: ['', MyValidators.regex(/^(?!\s|.*\s$).*$/)]  
    });  
  }

Luego en tu plantilla:

<input type="text" ngControl="foo" />
<div *ngIf="!form.foo.valid">Please correct foo entry !</div> 

También puede personalizar la clase CSS ng-invalid.

Como en realidad no hay validadores para regex, tienes que escribir el tuyo propio. Es una función simple que toma un control en input, y devuelve null si es válido o un StringMap si no es válido.

export class MyValidators {
  static regex(pattern: string): Function {
    return (control: Control): {[key: string]: any} => {
      return control.value.match(pattern) ? null : {pattern: true};
    };
  }
}

Espero que te ayude.

 8
Author: gentiane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-31 00:03:42

validación personalizada paso a paso

Plantilla html

  <form [ngFormModel]="demoForm">
  <input  
  name="NotAllowSpecialCharacters"    
  type="text"                      
  #demo="ngForm"
  [ngFormControl] ="demoForm.controls['spec']"
  >

 <div class='error' *ngIf="demo.control.touched">
   <div *ngIf="demo.control.hasError('required')"> field  is required.</div>
   <div *ngIf="demo.control.hasError('invalidChar')">Special Characters are not Allowed</div>
 </div>
  </form>

Aplicación de componentes.ts

import {Control, ControlGroup, FormBuilder, Validators, NgForm, NgClass} from 'angular2/common';
import {CustomValidator} from '../../yourServices/validatorService';

Bajo clase definir

 demoForm: ControlGroup;
constructor( @Inject(FormBuilder) private Fb: FormBuilder ) {
    this.demoForm = Fb.group({
       spec: new Control('', Validators.compose([Validators.required,   CustomValidator.specialCharValidator])),
      })
}

En {../../yourServices / validatorService.ts }

export class CustomValidator {
    static specialCharValidator(control: Control): { [key: string]: any } {
   if (control.value) {
       if (!control.value.match(/[-!$%^&*()_+|~=`{}\[\]:";#@'<>?,.\/]/)) {            
           return null;
       }
       else {            
           return { 'invalidChar': true };
       }
   }

 }

 }
 5
Author: mani R,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-21 07:09:34

Mi solución con Angular 4.0.1: Solo muestra la interfaz de usuario para la entrada CVC requerida, donde el CVC debe tener exactamente 3 dígitos:

    <form #paymentCardForm="ngForm">         
...
        <md-input-container align="start">
            <input #cvc2="ngModel" mdInput type="text" id="cvc2" name="cvc2" minlength="3" maxlength="3" placeholder="CVC" [(ngModel)]="paymentCard.cvc2" [disabled]="isBusy" pattern="\d{3}" required />
            <md-hint *ngIf="cvc2.errors && (cvc2.touched || submitted)" class="validation-result">
                <span [hidden]="!cvc2.errors.required && cvc2.dirty">
                    CVC is required.
                </span>
                <span [hidden]="!cvc2.errors.minlength && !cvc2.errors.maxlength && !cvc2.errors.pattern">
                    CVC must be 3 numbers.
                </span>
            </md-hint>
        </md-input-container>
...
<button type="submit" md-raised-button color="primary" (click)="confirm($event, paymentCardForm.value)" [disabled]="isBusy || !paymentCardForm.valid">Confirm</button>
</form>
 1
Author: mkaj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-10 02:42:32