2017-05-04 125 views
2

我正在嘗試添加驗證,以便結束日期不能在開始日期之前。不幸的是,我不知道該怎麼做,到目前爲止我還沒有在互聯網上找到有用的建議。我的形式如下:Angular 2表單驗證開始日期> =結束日期

editAndUpdateForm(tageler: Tageler) { 
    this.tageler = tageler; 
    this.tagelerForm = this.fb.group({ 
     title: [this.tageler.title, Validators.required], 
     text: this.tageler.text, 
     group: [[this.tageler.group], Validators.required], 
     date_start: new Date(this.tageler.start).toISOString().slice(0, 10), 
     date_end: new Date(this.tageler.end).toISOString().slice(0, 10), 
     ... 
    }); 
    this.tagelerForm.valueChanges 
     .subscribe(data => this.onValueChanged(data)); 
    } 

我的驗證至今:

onValueChanged(data?: any) { 
    if (!this.tagelerForm) { 
     return; 
    } 
    const form = this.tagelerForm; 

    for (const field in this.formErrors) { 

    // clear previous error message (if any) 
     this.formErrors[field] = ''; 
     const control = form.get(field); 

     if (control && control.dirty && !control.valid) { 
     const messages = this.validationMessages[field]; 
     for (const key in control.errors) { 
      this.formErrors[field] += messages[key] + ' '; 
     } 
     } 
    } 
} 

validationMessages = { 
    'title': { 
     'required': 'Geben Sie bitte einen Namen ein.', 
    }, 
    'group': { 
     'required': 'Wählen Sie bitte eine Gruppe aus.' 
    }, 
    'bringAlong': { 
     'required': 'Bitte Feld ausfüllen.' 
    }, 
    'uniform': { 
     'required': 'Bitte Feld ausfüllen.' 
    }, 
}; 

formErrors = { 
    'title': 'Geben Sie bitte einen Namen ein.', 
    'group': 'Wählen Sie bitte eine Gruppe aus.', 
    'bringAlong': 'Bitte Feld ausfüllen', 
    'uniform': 'Bitte Feld ausfüllen', 
}; 

的表單控件的DATE_START「&「DATE_END」包含「形式的日期字符串dd.MM. yyyy',我希望'date_end'大於或等於'date_start'。

我想直接顯示錯誤信息(我的HTML代碼如下所示:)

<label for="formControlName_date_end" class="col-3 col-form-label">Ende:</label> 
     <div class="col-5"> 
     <input id="formControlName_date_end" class="form-control" formControlName="date_end" type="date" value="{{tageler.end | date: 'yyyy-MM-dd'}}"> 
     </div> 
     <div *ngIf="formErrors.date_end" class="alert alert-danger"> 
     {{ formErrors.date_end }} 
     </div> 

有人能幫助我嗎?

謝謝!

回答

0

我們無法進行驗證,因爲我們需要兩個控制值,即startdate和enddate進行比較。所以,最好是兩個日期在組件

error:any={isError:false,errorMessage:''}; 

compareTwoDates(){ 
    if(new Date(this.form.controls['date_end'].value)<new Date(this.form.controls['date_start'].value)){ 
     this.error={isError:true,errorMessage:'End Date can't before start date'}; 
    } 
} 

比較在HTML

<label for="formControlName_date_end" class="col-3 col-form-label">Ende:</label> 
<div class="col-5"> 
     <input id="formControlName_date_end" class="form-control" formControlName="date_end" type="date" value="{{tageler.end | date: 'yyyy-MM-dd'}}" (blur)="compareTwoDates()"> 
</div> 
<div *ngIf="error.isError" class="alert alert-danger"> 
    {{ error.errorMessage }} 
</div> 
+0

非常感謝您sainu,這完美的作品! :) – Ramona

+0

可以請你把它標記爲答案@Ramona – sainu

+0

雖然它顯示錯誤消息表單驗證仍然返回「有效」是否有一種方法來影響真正的形式驗證? – alex

4

你也可以用反應形式去做。 FormBuilder API可讓您添加自定義驗證器。

的額外參數映射有效密鑰是驗證和asyncValidator

實施例:

import { Component } from '@angular/core'; 
import { FormGroup, FormBuilder, Validators } from '@angular/forms'; 

@Component({ 
    selector: 'reactive-form', 
    templateUrl: './reactive-form.html' 
}) 
export class ReactiveFormComponent { 

    form: FormGroup 

    constructor(private fb: FormBuilder){ 
    this.createForm(); 
    } 

    createForm() { 
    this.form = this.fb.group({ 
     dateTo: ['', Validators.required ], 
     dateFrom: ['', Validators.required ] 
    }, {validator: this.dateLessThan('dateFrom', 'dateTo')}); 
    } 

    dateLessThan(from: string, to: string) { 
    return (group: FormGroup): {[key: string]: any} => { 
    let f = group.controls[from]; 
    let t = group.controls[to]; 
    if (f.value > t.value) { 
     return { 
     dates: "Date from should be less than Date to" 
     }; 
    } 
    return {}; 
    } 
} 

} 

注意,我與比較從輸入日期的和值> ,但默認情況下,這將比較字符串。 在現場示例中,我使用angular-date-value-accessor並導入了指令useValueAsDate。

<input formControlName="dateFrom" type="date" useValueAsDate /> 

本指令group.controls [從] .value的和group.controls [於] .value的返回日期,然後我可以<他們進行比較。

Live example in plunkr

Dave's answer

6

基於santiagomaldonado的答案,我已經創建了一個通用ValidatorFn可以在多個反應形成了具有動態的返回值被使用。

export class DateValidators { 
    static dateLessThan(dateField1: string, dateField2: string, validatorField: { [key: string]: boolean }): ValidatorFn { 
     return (c: AbstractControl): { [key: string]: boolean } | null => { 
      const date1 = c.get(dateField1).value; 
      const date2 = c.get(dateField2).value; 
      if ((date1 !== null && date2 !== null) && date1 > date2) { 
       return validatorField; 
      } 
      return null; 
     }; 
    } 
} 

導入驗證器並在你的formgroup驗證器中像這樣使用它。

this.form = this.fb.group({ 
     loadDate: null, 
     deliveryDate: null, 
    }, { validator: Validators.compose([ 
     DateValidators.dateLessThan('loadDate', 'deliveryDate', { 'loaddate': true }), 
     DateValidators.dateLessThan('cargoLoadDate', 'cargoDeliveryDate', { 'cargoloaddate': true }) 
    ])}); 

現在您可以在HTML中使用驗證。

<md-error *ngIf="form.hasError('loaddate')">Load date must be before delivery date</md-error> 
相關問題