2016-10-10 16 views
0

私は角度2反応形式を使用しており、生年月日フィールドのバリデーターを作成しました。バリデーターは働いていますが、生年月日フィールドは年、月、日の3つの新しいフィールドに分割されています。彼らはすべて自分のバリデーターを持っています。私の質問は、元の生年月日バリデータの日付が3つのフィールドで機能するように、コードを変更するにはどうすればいいですか?反応形式:複数のフィールドに1つのバリデーターを使用する

1つのフィールドをチェックするオリジナルのバリデーターです。 入力(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') }; 

}; 
3つのフィールドを持つ

新しいHTML 年々 日が入力さ 1〜31月が持っているかどうかを確認するバリデータを持ってチェックするバリデータを持っています入力が1から12の間であるかどうかを確認するバリデーター。 上記の3つのフィールドの入力を新しい文字列に結合し、元の生年月日バリデータを使用したいとします。

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; 
    } 
} 

あまり多くのことを変更するために管理することができませんでした - 私は2つの日付が(NG-ブートストラップパッケージのdatepickersに使用されるように、そのフォーマットはNgbDateStructである)と比較するためのバリデータを作成している

 <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

答えとしてここに記述するのが最も良いですが、私はこのバリデーター関数コードであなたの質問に答えると信じています。

注:コードで使用される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; 
} 
関連する問題