如何以角度验证开始日期和结束日期?

时间:2017-11-17 19:10:34

标签: angular validation date

我正在以角度构建组件,我希望开始日期大于结束日期。我想知道我需要在HTML和TS代码中做出哪些更改才能完成。我正在使用的HTML和TS代码片段是:

HTML:

<form class="unavailability-form" [formGroup]="unavailabilityForm" *ngIf="loaded">
<div class="component-title" matDialogTitle>
   {{'PORTAL.TEXTUNAVAILABILITY' | translate}}
</div>
<mat-toolbar>
   <div class="container"
      fxLayout="row"
      fxLayout.xs="column"
      fxLayoutGap.xs="0">
      <div>
         <h1>{{componentTitle}}</h1>
      </div>
   </div>
</mat-toolbar>
<mat-dialog-content>
   <div class="container" fxLayout="row" fxLayout.xs="column" fxLayoutGap.xs="0" fxLayoutGap="10px">
      <div class="item item-1" fxFlex="50%" fxFlexOrder="1">
         <mat-form-field>
            <input matInput [matDatepicker]="picker" placeholder="{{'PORTALSTARTDATE' | translate}}"  type="text" formControlName="startDate" [(ngModel)]="availability.startDate" [readonly]="!componentPermission.writePermission">
            <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
            <mat-datepicker #picker></mat-datepicker>
         </mat-form-field>
      </div>
      <div class="item item-2" fxFlex="50%" fxFlexOrder="1">
         <mat-form-field>
            <input matInput [matDatepicker]="picker" placeholder="{{'PORTAL.ENDDATE' | translate}}"  type="text" formControlName="endDate" [(ngModel)]="availability.endDate" [readonly]="!componentPermission.writePermission">
            <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
            <mat-datepicker #picker></mat-datepicker>
         </mat-form-field>
      </div>
   </div>
   <div class="item item-1" fxFlex="50%" fxFlexOrder="1">
      <mat-form-field>
         <input matInput placeholder="{{'PORTAL.UNAVAILABILITYREASON' | translate}}" type="text" formControlName="unavailabilityReason" [(ngModel)]="availability.unavailabilityReason" [readonly]="!componentPermission.writePermission">
      </mat-form-field>
   </div>
</mat-dialog-content>
<mat-dialog-actions>
   <div class="container" fxLayout="row" fxLayout.xs="column" fxLayoutGap.xs="0">
      <div class="item item-1" fxFlex="100%">
         <button mat-raised-button color="primary" [disabled]="!locationForm.valid || !componentPermission.writePermission" (click)="onSave()">{{'PORTAL.CONFIRM' | translate}}</button>
         <button mat-raised-button [matDialogClose]="canceled" color="primary">{{'PORTAL.CANCEL' | translate}}</button>
      </div>
   </div>
</mat-dialog-actions>
</form>

TS:

  validateForm() {
    this.unavailabilityForm = this.formBuilder.group({
      'startDate': [''],
      'endDate': [''],
      'unavailabilityReason': ['']
    });
  }

在上面的代码中,{{PORTAL .___}}文本是指数据库中的值。

3 个答案:

答案 0 :(得分:1)

请注意,您无法在表单中使用ngModel。您必须使用数据从组件中提供表单。以下是已移除ngModel的表单:

<mat-dialog-content>
   <form [formGroup]="unavailabilityForm " novalidate fxFlex>
      <div class="container" fxLayout="row" fxLayout.xs="column" fxLayoutGap.xs="0" fxLayoutGap="10px">
         <div class="item item-1" fxFlex="50%" fxFlexOrder="1">
            <mat-form-field>
               <input matInput [matDatepicker]="picker" placeholder="{{'PORTALSTARTDATE' | translate}}"  type="text" formControlName="startDate" [readonly]="!componentPermission.writePermission">
               <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
               <mat-datepicker #picker></mat-datepicker>
            </mat-form-field>
         </div>
         <div class="item item-2" fxFlex="50%" fxFlexOrder="1">
            <mat-form-field>
               <input matInput [matDatepicker]="picker" placeholder="{{'PORTAL.ENDDATE' | translate}}"  type="text" formControlName="endDate" [readonly]="!componentPermission.writePermission">
               <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
               <mat-datepicker #picker></mat-datepicker>
            </mat-form-field>
         </div>
      </div>
      <div class="item item-1" fxFlex="50%" fxFlexOrder="1">
         <mat-form-field>
            <input matInput placeholder="{{'PORTAL.UNAVAILABILITYREASON' | translate}}" type="text" formControlName="unavailabilityReason"  [readonly]="!componentPermission.writePermission">
         </mat-form-field>
      </div>
   </form>
</mat-dialog-content>

然后,您需要初始化表单并将FormGroup级别验证程序添加到您的组。我也将数据提供给您的表单:

initForm() {
    this.unavailabilityForm = this.formBuilder.group({
      'startDate': [availability.startDate],
      'endDate': [availability.endDate],
      'unavailabilityReason': [availability.unavailabilityReason]
    }, validateDate);
  }

FormGroup中的自定义验证程序功能为validateDate

自定义验证器功能应如下所示:

function validateDate(group: FormGroup) {
  ///TODO: Implement some better validation logic
  const invalid = group.get('startDate').value > group.get('endDate').value;

  ///TODO: Implement some logic to mark controls dirty if is necessary.

  return invalid ? { 'invalidDate': true } : null;
}

FormGroup级别的自定义验证程序中,您可以访问该组中的所有控件并执行验证。请注意,表单的值将为字符串,因此,如果您使用的是Date,则需要更好的逻辑来比较日期。

另外请注意,组级验证器可能不会显示验证反馈,因此如果需要,您需要手动将控件标记为脏。

答案 1 :(得分:0)

使用反应形式,这是我的方法。

  deploymentSignOffDatesValidator(g: FormGroup) {
      return g.get('dateOfSignOff').value > g.get('dateOfDeployment').value ? null : {'unsequencial': true};
    }

  createEditUserForm(item: SaveUser) {
    if (!item) {
      item = {
        dateOfDeployment: '',
        dateOfSignOff: '',
      }
    }
this.userEditForm = this.fb.group({
      dateOfDeployment: [item.dateOfDeployment, Validators.required],
      dateOfSignOff: [item.dateOfSignOff]
    }, {validator: this.deploymentSignOffDatesValidator});

<div class="col-xl-3 col-lg-6 col-md-12">
                                <fieldset class="form-group">
                                    <label for="dateOfSignOff">Date of SignOff:</label>
                                    <input
                                        class="form-control"
                                        placeholder="Date of SignOff"
                                        bsDatepicker
                                        formControlName="dateOfSignOff"
                                        [bsConfig]="{ dateInputFormat: 'YYYY-MM-DD', containerClass: 'theme-dark-blue' }"
                                        [ngClass]="{'is-invalid': userEditForm.get('dateOfSignOff').errors && (formDir.submitted || userEditForm.get('dateOfSignOff').touched) || userEditForm.hasError('unsequencial') && userEditForm.get('dateOfSignOff').touched}">
                                        <div class="" *ngIf="userEditForm.hasError('unsequencial') && userEditForm.get('dateOfSignOff').touched">The Deploymnet Date must be less than Sign Off Date</div>
                                </fieldset>                                
                            </div>

答案 2 :(得分:0)

您可以检出我的库ng-swiss-army-knife,该库内部具有此表单验证器(以及许多其他有用的javascript / typescript / angular内容) https://github.com/nickwinger/ng-swiss-army-knife