简体   繁体   English

如何在 Angular 2+ formbuilder 中比较两个字段的值以进行验证

[英]how can I compare values of two fields for validation in angular 2+ formbuilder

I am learning angular ionic and currently attempting to use the angular forms, FormGroup, and FormBuilder features to validate some form data.我正在学习 angular ionic,目前正在尝试使用 angular forms、FormGroup 和 FormBuilder 功能来验证一些表单数据。

I have four fields that I would like to validate in relation to one another, but I am not sure how to write a validator that can see the value of other fields.我有四个字段要相互验证,但我不确定如何编写一个可以查看其他字段值的验证器。

The relevant fields are:相关领域是:

startDate, startTime, endDate, endTime.

Because these are ionic datetime inputs, they are always going to be in "ISO 8601" format.因为这些是离子日期时间输入,所以它们总是采用“ISO 8601”格式。 So example values might be:所以示例值可能是:

startDate: "2018-03-28"
startTime: "18:52"

My goal is to validate each of these so that they are valid if the start time and date is before the end time and date.我的目标是验证其中的每一个,以便在开始时间和日期在结束时间和日期之前它们是有效的。 For example all four fields are valid when:例如,所有四个字段在以下情况下均有效:

startDate is "2018-03-28",
startTime is "14:30",
endDate is "2018-03-28", and
endTime is "18:00"

And all four fields are invalid when, for example:并且所有四个字段都无效,例如:

startDate is "2018-03-28",
startTime is "14:30",
endDate is "2018-02-24", and
endTime is "23:00"

How can I go about comparing the values of these fields using the angular form features?如何使用角度形式功能比较这些字段的值?

Any help would be greatly appreciated!任何帮助将不胜感激!

The solution was to create a sub FormGroup and nest it inside the main FormGroup (with FormBuilder). 解决方案是创建一个子FormGroup并将其嵌套在主FormGroup中(使用FormBuilder)。

The code in my .ts file looked like this: 我的.ts文件中的代码如下所示:

  this.timingSubForm = new FormGroup({
    startDate: new FormControl('', Validators.compose([Validators.required])),
    startTime: new FormControl('', Validators.compose([Validators.required])),
    endDate: new FormControl('', Validators.compose([Validators.required])),
    endTime: new FormControl('', Validators.compose([Validators.required]))
  },
    (formGroup: FormGroup) => {
      return TimeValidator.validateTimes(formGroup);
    }
  );


  this.createItemForm = formBuilder.group({
    itemTitle:  ['', Validators.compose([Validators.minLength(4),Validators.maxLength(100), Validators.required])],
    itemDescription: ['', Validators.compose([Validators.minLength(10),Validators.maxLength(10000), Validators.required])],
    timingSubForm: this.timingSubForm
  });

And the template file looks like this: 模板文件如下所示:

<form [formGroup]="createItemForm">
    .. some input fields ..
    <div formGroupName="timingSubForm">
        .. date specific input fields ..
    </div>
    .. some more input fields ..
</form>

The code in my .ts file looked like this:我的 .ts 文件中的代码如下所示:

 this.form = this.formBuilder.group({
        startDate: [null, [Validators.required, DateTimeCompareValidator.DateCompareWithToday()]],
        endDate: [null, [Validators.required, DateTimeCompareValidator.DateCompareWithToday()]],
        startTime: [null, [Validators.required]],
        endTime: [null, [Validators.required]]

    }, {
        validator: Validators.compose([
            DateTimeCompareValidator.TwoDateCompare('startDate', 'endDate'),
            DateTimeCompareValidator.TimeCompare('startTime', 'endTime')
        ])
    });

And the template file looks like this:模板文件如下所示:

<form [formGroup]="form" (ngSubmit)="onSubmit()" class="form-horizontal">
<div class="form-group row">
    <label class="col-md-2 col-form-label" for="startDate">Batch Start Date</label>
    <div class="col-md-4">
        <input type="text" class="form-control mb-3" placeholder="DD-MM-YYYY" [bsConfig]="{ dateInputFormat: 'DD-MM-YYYY' }" bsDatepicker formControlName="startDate" [ngClass]="{ 'is-invalid': submitted && f.startDate.errors }" [minDate]="minStartDate" />
        <div *ngIf="submitted && f.startDate.errors" class="invalid-feedback">
            <div *ngIf="f.startDate.errors.required">Batch Start Date is required.</div>
            <div *ngIf="f.startDate.errors.dateMinThanToday">Batch Start date should be grater than today.</div>
        </div>
    </div>
    <label class="col-md-2 col-form-label" for="endDate">Batch End Date</label>
    <div class="col-md-4">
        <input type="text" class="form-control mb-3" placeholder="DD-MM-YYYY" [bsConfig]="{ dateInputFormat: 'DD-MM-YYYY' }" [minDate]="f.startDate.value" bsDatepicker formControlName="endDate" [ngClass]="{ 'is-invalid': submitted && f.endDate.errors }" />
        <div *ngIf="submitted && f.endDate.errors" class="invalid-feedback">
            <div *ngIf="f.endDate.errors.required">Batch End Date is required</div>
            <div *ngIf="f.endDate.errors.dateMinThanToday">Batch End date should be grater than today.</div>
            <div *ngIf="f.endDate.errors.dateMinThanField">Batch End date should be grater than start date.</div>
        </div>
    </div>
</div>

<div class="form-group row">
    <label class="col-md-2 col-form-label" for="startTime">Start Time</label>
    <div class="col-md-4">
        <timepicker formControlName="startTime" [ngClass]="{ 'is-invalid': submitted && f.startTime.errors }"></timepicker>
        <div *ngIf="submitted && f.startTime.errors" class="invalid-feedback">
            <div *ngIf="f.startTime.errors.required">Batch Start time is required</div>
        </div>
    </div>
    <label class="col-md-2 col-form-label" for="endTime">End ime</label>
    <div class="col-md-4">
        <timepicker formControlName="endTime" [ngClass]="{ 'is-invalid': submitted && f.endTime.errors }"></timepicker>
        <div *ngIf="submitted && f.endTime.errors" class="invalid-feedback">
            <div *ngIf="f.endTime.errors.required">Batch End time is required</div>
            <div *ngIf="f.endTime.errors.timeMinThanField">Batch End time should be grater than start time.</div>
        </div>
    </div>
</div>

The validator file:验证器文件:

import { AbstractControl, ValidatorFn, Validators } from "@angular/forms";

export class DateTimeCompareValidator {导出类 DateTimeCompareValidator {

static DateCompareWithToday(): ValidatorFn {
    return (control: AbstractControl): { [key: string]: boolean } | null => {
        const date1 = new Date();
        const date2 = control.value;
        if ((date1 !== null && date2 !== null) && date1 > date2) {
            //console.log("Today= " + date1 + " and controlDate= " + date2);
            return { dateMinThanToday: true };
        }
        return null;
    };
}

static TwoDateCompare(fromDateField: string, toDateField: string, errorKey: string = null): ValidatorFn {
    return (control: AbstractControl): { [key: string]: boolean } | null => {
        const date1 = control.get(fromDateField).value;
        const date2 = control.get(toDateField).value;
        if ((date1 !== null && date2 !== null) && date1 > date2) {
            //console.log("ControlOneDate= " + date1 + " and ControlTwoDate= " + date2);
            if (errorKey === null) {
                control.get(toDateField).setErrors({ 'dateMinThanField': true });
                return { dateMinThanField: true };
            }
            else {
                control.get(toDateField).setErrors({ errorKey: true });
                return { errorKey: true };
            }
        }
        return null;
    };
}

static TimeCompare(fromTimeField: string, toTimeField: string): ValidatorFn {
    return (control: AbstractControl): { [key: string]: boolean } | null => {
        const time1 = control.get(fromTimeField).value;
        const time2 = control.get(toTimeField).value;
        if ((time1 !== null && time2 !== null) && time1 > time2) {
            console.log("ControlOneTime= " + time1 + " and ControlTwoTime= " + time2);
            control.get(toTimeField).setErrors({ 'timeMinThanField': true });
            return { dateMinThanField: true };
        }
        return null;
    };
}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM