0

私はAngular 2リアクティブフォームを使用しており、生年月日フィールドのバリデーターを作成しました。バリデーターは機能していますが、生年月日フィールドが 3 つの新しいフィールド (年、月、日) に分割されていることがわかりました。それらはすべて独自のバリデーターを持っています。私の質問は、元の生年月日バリデーターが 3 つのフィールドで機能するようにコードを変更するにはどうすればよいかということです。

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

};

new html with 3 fields year 年をチェックするバリデーターがあります day 入力が 1 から 31 の間であるかどうかをチェックするバリデーターを持っています month 入力が 1 から 12 の間であるかどうかをチェックするバリデーターを持っています。 3 つのフィールドを新しい文字列に変換し、元の生年月日バリデーターを使用します。

     <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>
4

1 に答える 1

0

2 つの日付を比較するためのバリデーターを作成しました (その形式は NgbDateStruct です - ng-bootstrap パッケージの日付ピッカーで使用されています)。

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;
}
于 2016-10-26T22:31:07.707 に答える