我试图添加验证,使得结束日期不能早于开始日期。不幸的是我不知道该怎么做,到目前为止我还没有在互联网上找到任何有用的建议。我的表格如下:
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 :(得分:24)
根据santiagomaldonado的回答,我创建了一个通用的ValidatorFn,可以在具有动态返回值的多个Reactive Forms中使用。
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;
};
}
}
导入验证器并在表格组验证器中使用它。
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>
答案 1 :(得分:10)
您也可以使用Reactive Forms执行此操作。 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 {};
}
}
}
请注意,我将输入日期的值与来自&gt;的值进行比较,但默认情况下这将是比较字符串。 在实例中,我使用angular-date-value-accessor并导入指令useValueAsDate。
<input formControlName="dateFrom" type="date" useValueAsDate />
使用此指令group.controls [from] .value和group.controls [to] .value返回Date,然后我可以将它们与&lt;。
进行比较。 的信用答案 2 :(得分:2)
我们无法在验证中执行此操作,因为我们需要两个控制值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>
答案 3 :(得分:1)
创建表单组。让控件成为表单组的一部分。
new FormGroup({
startDate: this.fb.group({
dateInput: [{value: ""}, startDateValidator()]
}),
endDate: this.fb.group({
dateInput: ["", endDateValidator()]
})
}, startDateCannotBeLessThanEndDateValidator());
startDateCannotBeLessThanEndDateValidator(formGroup: FormGroup) {
let startDate = formGroup.get("startDate");
let endDate = formGroup.get("endDate");
// compare 2 dates
}
答案 4 :(得分:0)
我使用时刻,在角度7中比较和验证日期,我使用此功能:
datesValidator(date1: any, date2: any): {[key:string]:any} | null {
return (group: FormGroup): { [key: string]: any } | null => {
let start = group.controls[date1].value;
let end = group.controls[date2].value;
let datum1 = _moment(start).startOf('day');
let datum2 = _moment(end).startOf('day');
if (_moment(datum1).isSameOrAfter(datum2)) {
this.alert.red("Error: wrong period!"); //popup message
return { 'error': 'Wrong period!' };
}
return null; //period is ok, return null
};
}
答案 5 :(得分:0)
我的是有角的7 + ngprime(用于日历)
(*如果您不希望ngprime只是将日历部分替换为其他部分。)
请参考以下代码进行日期验证。
我的代码还有其他验证 选择开始日期后,我会在结束数据的日历中屏蔽前几天 因此结束日期总是会晚于该日期。
如果您不想阻止日期,请删除[minDate]部分。 它也在工作。
>组件
export class test implements OnInit {
constructor() { }
defaultDate: Date = new Date();
checkDate = true;
form: FormGroup;
today: Date = new Date(); //StartDate for startDatetime
startDate: Date = new Date(); //StartDate for endDatetime
initFormControls(): void {
this.today.setDate(this.today.getDate());
this.startDate.setDate(this.today.getDate()); //or start date + 1 day
this.form = new FormGroup({
startDatetime: new FormControl('', [Validators.required]),
endDatetime: new FormControl('', [Validators.required])
},
{ validators: this.checkDateValidation });
}
checkDateValidation: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
try {
let startingDatefield = control.get('startDatetime').value;
this.startDate = new Date(startingDatefield); //new Date(startingDatefield).getDate()
let endingDatefield = control.get('endDatetime').value;
if (this.today >= startingDatefield) { //compare to current date
console.log("Please set a Start Date that is on or after Current Date and Time.");
return { 'effectiveStartDatetime': false };
} else
if (startingDatefield > endingDatefield && endingDatefield) {
console.log("Please set an End Date and Time that is after the Start Date and Time.");
return {};
} else {
return {};
}
} catch (err) {
}
};
onSubmit() {
//if form is not valid
if (!this.form.valid) {
console.log(" Please fill in all the mandatory fields");
// do sth
return;
}
//if form is valid
//do sth
}
ngOnInit() {
this.initFormControls();
}
> HTML
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<div>
<div>
<p-button type="submit" label="submit"></p-button>
</div>
</div>
<div>
<p>Start Date/Time"</p>
<div>
<p-calendar formControlName="startDatetime" appendTo="body" showTime="true" hourFormat="24" stepMinute="30"
showSeconds="false" dateFormat="yy-mm-dd" [minDate]="today"></p-calendar>
<div
*ngIf="form.get('startDatetime').invalid && (form.get('startDatetime').dirty || form.get('startDatetime').touched)">
<div *ngIf="form.get('startDatetime').hasError('required')">
</div>
</div>
</div>
<p>End Date/Time</p>
<div>
<p-calendar formControlName="endDatetime" appendTo="body" showTime="true" hourFormat="24" stepMinute="30"
showSeconds="false" dateFormat="yy-mm-dd" [minDate]="startDate"></p-calendar>
<div *ngIf="form.get('endDatetime').invalid && (form.get('endDatetime').dirty || form.get('endDatetime').touched)">
<div *ngIf="!checkDate || form.get('endDatetime').hasError('required')">
</div>
</div>
</div>
</div>
</form>