1

2 つの Angular 2 Bootstrap によって入力される 2 つの入力がありますdatepickers。after (not before or equal to)の場合、に対応するボタンをFormGroup無効にします。現在、送信ボタンより後の を選択すると、有効なままになります。しかし、2 番目のカレンダー ボタンをクリックして 2 番目のカレンダー ボタンをクリックすると、送信ボタンが無効になります (実際に を選択する必要はありません)。コンソールで確認し、、、およびはすべて、エラーなしで正しい時間に正しい値に変更および変更されています。「タイミング」がずれているのは、送信ボタンを無効にするだけです。startDateendDatestartDateendDatedatepickerendDatestartDateendDateerror

<form class="form-inline">
<div>
<div class="form-group" [ngClass]="{'has-error':!secondForm.controls['startDate'].valid && secondForm.controls['startDate'].touched}">
  <label>Start Date:</label>
  <input style="width:250px" [value]="getDate('start')" class="form-control" type="text" [formControl]="secondForm.controls['startDate']">
</div>
<div style="display:inline-block">
  <ngb-datepicker id="special" *ngIf="startCheck;" [(ngModel)]="startDate" (ngModelChange)="showDatePick(0)" [ngModelOptions]="{standalone: true}"></ngb-datepicker>
</div>
<button type="button" class="btn icon-calendar" (click)="showDatePick(0)"></button>
<div class="form-group" [ngClass]="{'has-error':!secondForm.controls['endDate'].valid && secondForm.controls['endDate'].touched}">
  <label>End Date:</label>
  <input style="width:250px" [value]="getDate('end')" class="form-control" type="text" [formControl]="secondForm.controls['endDate']">
</div>
<div style="display:inline-block">
  <ngb-datepicker id="special" *ngIf="endCheck;" [(ngModel)]="endDate" (ngModelChange)="showDatePick(1)" [ngModelOptions]="{standalone: true}"></ngb-datepicker>
</div>
<button type="button" class="btn icon-calendar" (click)="showDatePick(1)"></button>
<button type="submit" class="btn icon-search" [disabled]="!secondForm.valid || error==true"></button>
</div>
</form>

対応する Typescript:

import { Component } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import {NgbDateStruct} from '@ng-bootstrap/ng-bootstrap';
import {DatePipe} from "@angular/common";
import * as moment from 'moment';

@Component({
selector: 'calendar-pick',
styleUrls: ['../app.component.css'],
templateUrl: './calendarpick.component.html',
providers: [DatePipe]
})

export class CalendarPickComponent {
public error: boolean = false;
public dt: NgbDateStruct;
public dt2: NgbDateStruct;
public startCheck: boolean = false;
public endCheck: boolean = false;
secondForm : FormGroup;

public constructor(fb: FormBuilder, private datePipe: DatePipe) {
this.secondForm = fb.group({
  'startDate' : [this.dt, Validators.required],
  'endDate' : [this.dt2, Validators.required]
})
this.secondForm.valueChanges.subscribe( (form: any) => {
    console.log('form changed to:', form);
  }
);
}

public getDate(dateName: string) {
let workingDateName = dateName + 'Date';
let timestamp = this[workingDateName] != null ? new Date(this[workingDateName].year, this[workingDateName].month-1, this[workingDateName].day).getTime() : new Date().getTime();
this.secondForm.controls[dateName + 'Date'].setValue(this.datePipe.transform(timestamp, 'longDate'));
}

public showDatePick(selector):void {
if(selector === 0) {
  this.startCheck = !this.startCheck
} else {
  this.endCheck = !this.endCheck;
}
this.periodValidator(this.secondForm);
}

periodValidator(formGroup:FormGroup) {
let s = new Date(formGroup.value.startDate);
let e = new Date(formGroup.value.endDate);
let stDt = moment(s);
let endDt = moment(e);
if (stDt > endDt) {
  this.error = true;
}else {
  this.error = false;
}
}

}
4

2 に答える 2

4

次のように、カスタム バリデータを定義してフォーム グループ全体に割り当てることができます。

endDateAfterOrEqualValidator(formGroup): any {
    var startDateTimestamp, endDateTimestamp;
    for(var controlName in formGroup.controls) {
      if(controlName.indexOf("startDate") !== -1) {
        startDateTimestamp = Date.parse(formGroup.controls[controlName].value);
      }
      if(controlName.indexOf("endDate") !== -1) {
        endDateTimestamp = Date.parse(formGroup.controls[controlName].value);
      }
    }
    return (endDateTimestamp < startDateTimestamp) ? { endDateLessThanStartDate: true } : null;
  }

これにより、コントロールのタイムスタンプがチェックされ、有効でない場合は何かが返され、有効な場合は null が返されます。

this.secondForm = fb.group({
    'startDate' : ['', Validators.required],
    'endDate'  : ['', Validators.required]
  },
  {validator: this.endDateAfterOrEqualValidator});

追加のコントロールを追加するつもりがない場合は、必要な値のコントロールをチェックする代わりに、タイムスタンプの割り当てをハードコーディングできると思います。

プランカー: http://plnkr.co/edit/Yow6DMd2soBXwJ2oGOFu?p=preview

于 2016-11-07T18:31:40.637 に答える