2016-10-10 2 views
0

Я использую угловые 2 реактивные формы и сделал валидатор для даты рождения. Валидатор работает, но, оказывается, дата рождения поля делится на три новых поля: год, месяц, день. У всех есть свои валидаторы. Мой вопрос в том, как я могу изменить свой код, чтобы мой первоначальный валидатор рождения работал на трех полях.реактивные формы: используйте один валидатор для нескольких полей

мой оригинальный валидатор, который проверяет одно поле. входа (2000/12/12) действует

export function dobValidator(control) { 
    const val = control.value; 
    const dobPattern = /^\d{4}\/\d{2}\/\d{2}$/ ; 
    const comp = val.split('/'); 
    const y = parseInt(comp[0], 10); 
    const m = parseInt(comp[1], 10); 
    const d = parseInt(comp[2], 10); 
    const jsMonth = m - 1; 
    const date = new Date(y, jsMonth, d); 
    const isStringValid = dobPattern.test(control.value); 
    const isDateValid = (date.getFullYear() === y && date.getMonth() === jsMonth && date.getDate() === d); 

    return (isStringValid && isDateValid) ? null : { invalidDob: ('Date of birth not valid') }; 

}; 

нового HTML с 3 полями года, имеет валидатор, который проверяет день года имеет валидатор, который проверяет, если вход между 1 и 31 месяца имеет валидатор, который проверяет, находится ли вход между 1 и 12. Я хочу объединить вышеуказанный ввод трех полей в новую строку и использовать мой первоначальный валидатор рождения.

 <label>Date of birth :</label> 
     <div> 
     <div class="col-xs-1"> 
     <input required type="text" formControlName="day" class="form-control" placeholder="dd" id="day"/> 
     <p *ngIf="form.controls.day.dirty && form.controls.day.errors">{{ form.controls.day.errors.invalidDay }}</p> 
     </div> 

     <div class="col-xs-1"> 
     <input required type="text" formControlName="month" class="form-control" placeholder="mm" id="month"/> 
     <p *ngIf="form.controls.month.dirty && form.controls.month.errors">{{ form.controls.month.errors.invalidMonth }}</p> 
     </div> 

     <div class="col-xs-2"> 
     <input required type="text" formControlName="year" class="form-control" placeholder="yyyy" id="year"/> 
     <p *ngIf="form.controls.year.dirty && form.controls.year.errors">{{ form.controls.year.errors.invalidYear }}</p> 
     </div> 
    </div> 


    <div> 
     <button type="submit" [disabled]="form.invalid">Submit</button> 
    </di> 

ответ

0

Я создал валидатор для сравнения двух дат (их формат NgbDateStruct - используемый в datepickers нг-самозагрузки пакета ')

import { Directive, forwardRef, Attribute } from '@angular/core'; 
import { Validator, AbstractControl, NG_VALIDATORS, ValidatorFn } from '@angular/forms'; 
import { NgbDateStruct } from "@ng-bootstrap/ng-bootstrap"; 
import { toDate } from "../helpers/toDate"; 

export function dateCompareValidator(compareToControl: string, compareToValue: NgbDateStruct, compareType: string, reverse: boolean, errorName: string = 'dateCompare'): ValidatorFn { 
    return (c: AbstractControl): { [key: string]: any } => { 

     let compare = function (self: Date, compareTo: Date): any { 
      console.log('comparing ', compareType.toLowerCase()); 
      console.log(self); 
      console.log(compareTo); 
      if (compareType.toLowerCase() === 'ge') { 
       if (self >= compareTo) { 
        return true; 
       } else { 
        return false; 
       } 
      } else if (compareType.toLowerCase() === 'le') { 
       if (self <= compareTo) { 
        return true; 
       } else { 
        return false; 
       } 
      } 

      return false; 
     }; 

     // self value 
     let v = c.value; 

     // compare vlaue 
     let compareValue: Date; 
     let e; 
     if (compareToValue) { 
      compareValue = toDate(compareToValue); 
     } else { 
      e = c.root.get(compareToControl); 
      if (e) { 
       compareValue = toDate(e.value); 
      } 
      else { 
       // OTHER CONTROL NOT FOUND YET 
       return null; 
      } 
     } 

     let controlToValidate: AbstractControl = reverse ? e : c; 

     // validate and set result 
     let error = null; 
     let result = compare(toDate(c.value), compareValue); 
     if (result === true) { 
      console.log('clearing errors', compareToControl); 
      if (controlToValidate.errors) { 
       delete controlToValidate.errors[errorName]; 
       if (!Object.keys(controlToValidate.errors).length) { 
        controlToValidate.setErrors(null); 
       } 
      } 
      else { 
       console.log('errors property not found in control', controlToValidate); 
      } 
     } else { 
      error = {}; 
      error[errorName] = false; 
      controlToValidate.setErrors(error); 
      console.log(controlToValidate.errors); 
      console.log(controlToValidate.value); 
      console.log('Error Control', controlToValidate); 
      console.log('returning errors'); 
     } 
     return reverse ? null : error; 
    } 
} 

не удавалось изменить много много чтобы лучше описать здесь как ответ, но я верю, что вы ответите на свой запрос в этом коде функции проверки.

Примечание: Функция toDate(), используемая в коде, представляет собой небольшую функцию, которую я создал для преобразования NgbDateStruct в объект даты javascript, чтобы упростить сравнение дат. Здесь идет его реализация:

import { NgbDateStruct } from "@ng-bootstrap/ng-bootstrap" 

export function toDate(ngbDate: NgbDateStruct): Date { 
    return ngbDate != null ? new Date(Date.UTC(ngbDate.year, ngbDate.month, ngbDate.day)) : null; 
} 
Смежные вопросы