Angular 8 中的日期验证器用于比较两个日期
Date validator in Angular 8 to compare two dates
在 Angular 8
中执行此操作的最佳方法是什么
我有两个输入日期是 fromDateMin 和 fromDateMAX
我需要将这两个与 formControlName='fromctrlname' 和 formControlName='toctrlname' 进行比较
并显示错误
条件:
如果 fromDateMin 不为空,则用户不能 select 任何早于此日期的日期。如果他们这样做,日期将更改为此日期。在 error-message-span 中显示消息。
如果 fromDateMax 不为空,则用户不能 select 任何晚于此日期的日期。如果他们这样做,日期将更改为此日期。在 error-message-span 中显示消息。
fromDate 必须早于或等于toDate。 toDate 必须晚于或等于 fromDate。在 error-message-span 中显示消息。
这是我到目前为止尝试过的方法
https://stackblitz.com/edit/angular-2gdadn?file=src%2Fapp%2Fapp.component.ts
这是我的 html
<form [formGroup]='dateFilterForm'>
<label *ngIf="fromLabel != ''" for="{{componentId}}-fromDate">{{fromLabel}}</label>
<input type="date" formControlName='fromctrlname' id="{{componentId}}-fromDate" name="{{componentId}}-fromDate"
placeholder="{{fromPlaceholder}}" [(ngModel)]="fromDate" (ngModelChange)="errMsg = ''" [value]="fromDate">
<label *ngIf="toLabel != ''" for="{{componentId}}-toDate">{{toLabel}}</label>
<input type="date" formControlName='toctrlname' id="{{componentId}}-toDate" name="{{componentId}}-fromDate"
placeholder="{{toPlaceholder}}" [(ngModel)]="toDate" (ngModelChange)="errMsg = ''" [value]="toDate">
<button type="submit" (click)="submit()"
class="btn button-border white icon-rightarrow-white medium mt2 ml2 mr1 mb2 r15 fw7"
style="display:inline-block;">{{buttonLabel}}</button>
<div class="error-message mb3 red flex items-center fw7"
*ngIf="formInvalid && dateFilterForm.controls.fromctrlname.hasError('invalidfromDate')">
<i class="icon-alert s15 mr2"></i> From date should not be earlier than {{fromDateMin}}.
</div>
<div class="error-message mb3 red flex items-center fw7"
*ngIf="formInvalid && dateFilterForm.controls.fromctrlname.hasError('invalidtoDate')">
<i class="icon-alert s15 mr2"></i>To date should not be later than {{fromDateMax}}.
</div>
<span class="error-message mb3 red flex items-center fw7" *ngIf="errMsg!=''">
<i class="icon-alert s15 mr2"></i>{{errMsg}}
</span>
</form>
验证部分可以使用反应式表单和自定义验证器轻松实现,正如 Robert 所提到的。
您可以根据您的要求创建 2 个验证器,一个用于验证组内每个表单控件的最小和最大日期。该组的另一个验证器,用于验证 fromDate 是否早于 toDate。
输入控件的验证器基本上是这样的。
function dateRangeValidator(min: Date, max: Date): ValidatorFn {
return control => {
if (!control.value) return null;
const dateValue = new Date(control.value);
if (min && dateValue < min) {
return { message: 'error message' };
}
if (max && dateValue > max) {
return { message: 'error message' };
}
null;
}
}
您可以将 ValidatorFn
包裹在另一个函数周围以提供除控件之外的其他参数,从而构成一个 ValidatorFn
。在您的情况下,这将是最小和最大日期。然后通过调用函数将验证器添加到表单。
fromDate: new FormControl('', [dateRangeValidator(this.minDate, this.maxDate)])
在您的组验证器中,您比较两个子控件的值
function groupValidator(group: AbstractControl): ValidationErrors | null {
const fromCtrl = group.get('fromDate');
const toCtrl = group.get('toDate');
return new Date(fromCtrl.value) > new Date(toCtrl.value) ? { message: 'error message' } : null;
}
在这种情况下,我们不会将验证函数包装在另一个函数周围,因为我们不必配置任何东西。
完整的表单组配置如下所示:
formGroup = new FormGroup({
fromDate: new FormControl('', [dateRangeValidator(this.minDate, this.maxDate)]),
toDate: new FormControl('', [dateRangeValidator(this.minDate, this.maxDate)]),
}, [groupValidator]);
每个验证器都会将错误添加到相应的控件中。所以它们很容易在模板或其他地方找到。
这些是非常粗略的示例实现,因此仅将它们用作起点。
至于在验证期间更新值。您可以在验证器中执行此操作,因为您确实拥有可用的 AbstractControl。调用 setValue
或 patchValue
可以为您做到这一点。但这将再次触发验证并可能导致无限递归循环,因此请注意这一点。此外,您可能想要更改为在模糊时发出值更新,而不是在每次击键时发出。您可以使用 updateOn: blur
选项在每个表单控件上执行此操作。
fromDate: new FormControl('', { updateOn: 'blur', validators: [...] })
这是我用于快速原型的 stackblitz:https://stackblitz.com/edit/angular-ivy-jfes5n
在 Angular 8
中执行此操作的最佳方法是什么我有两个输入日期是 fromDateMin 和 fromDateMAX 我需要将这两个与 formControlName='fromctrlname' 和 formControlName='toctrlname' 进行比较 并显示错误
条件:
如果 fromDateMin 不为空,则用户不能 select 任何早于此日期的日期。如果他们这样做,日期将更改为此日期。在 error-message-span 中显示消息。
如果 fromDateMax 不为空,则用户不能 select 任何晚于此日期的日期。如果他们这样做,日期将更改为此日期。在 error-message-span 中显示消息。
fromDate 必须早于或等于toDate。 toDate 必须晚于或等于 fromDate。在 error-message-span 中显示消息。
这是我到目前为止尝试过的方法
https://stackblitz.com/edit/angular-2gdadn?file=src%2Fapp%2Fapp.component.ts
这是我的 html
<form [formGroup]='dateFilterForm'>
<label *ngIf="fromLabel != ''" for="{{componentId}}-fromDate">{{fromLabel}}</label>
<input type="date" formControlName='fromctrlname' id="{{componentId}}-fromDate" name="{{componentId}}-fromDate"
placeholder="{{fromPlaceholder}}" [(ngModel)]="fromDate" (ngModelChange)="errMsg = ''" [value]="fromDate">
<label *ngIf="toLabel != ''" for="{{componentId}}-toDate">{{toLabel}}</label>
<input type="date" formControlName='toctrlname' id="{{componentId}}-toDate" name="{{componentId}}-fromDate"
placeholder="{{toPlaceholder}}" [(ngModel)]="toDate" (ngModelChange)="errMsg = ''" [value]="toDate">
<button type="submit" (click)="submit()"
class="btn button-border white icon-rightarrow-white medium mt2 ml2 mr1 mb2 r15 fw7"
style="display:inline-block;">{{buttonLabel}}</button>
<div class="error-message mb3 red flex items-center fw7"
*ngIf="formInvalid && dateFilterForm.controls.fromctrlname.hasError('invalidfromDate')">
<i class="icon-alert s15 mr2"></i> From date should not be earlier than {{fromDateMin}}.
</div>
<div class="error-message mb3 red flex items-center fw7"
*ngIf="formInvalid && dateFilterForm.controls.fromctrlname.hasError('invalidtoDate')">
<i class="icon-alert s15 mr2"></i>To date should not be later than {{fromDateMax}}.
</div>
<span class="error-message mb3 red flex items-center fw7" *ngIf="errMsg!=''">
<i class="icon-alert s15 mr2"></i>{{errMsg}}
</span>
</form>
验证部分可以使用反应式表单和自定义验证器轻松实现,正如 Robert 所提到的。
您可以根据您的要求创建 2 个验证器,一个用于验证组内每个表单控件的最小和最大日期。该组的另一个验证器,用于验证 fromDate 是否早于 toDate。
输入控件的验证器基本上是这样的。
function dateRangeValidator(min: Date, max: Date): ValidatorFn {
return control => {
if (!control.value) return null;
const dateValue = new Date(control.value);
if (min && dateValue < min) {
return { message: 'error message' };
}
if (max && dateValue > max) {
return { message: 'error message' };
}
null;
}
}
您可以将 ValidatorFn
包裹在另一个函数周围以提供除控件之外的其他参数,从而构成一个 ValidatorFn
。在您的情况下,这将是最小和最大日期。然后通过调用函数将验证器添加到表单。
fromDate: new FormControl('', [dateRangeValidator(this.minDate, this.maxDate)])
在您的组验证器中,您比较两个子控件的值
function groupValidator(group: AbstractControl): ValidationErrors | null {
const fromCtrl = group.get('fromDate');
const toCtrl = group.get('toDate');
return new Date(fromCtrl.value) > new Date(toCtrl.value) ? { message: 'error message' } : null;
}
在这种情况下,我们不会将验证函数包装在另一个函数周围,因为我们不必配置任何东西。
完整的表单组配置如下所示:
formGroup = new FormGroup({
fromDate: new FormControl('', [dateRangeValidator(this.minDate, this.maxDate)]),
toDate: new FormControl('', [dateRangeValidator(this.minDate, this.maxDate)]),
}, [groupValidator]);
每个验证器都会将错误添加到相应的控件中。所以它们很容易在模板或其他地方找到。
这些是非常粗略的示例实现,因此仅将它们用作起点。
至于在验证期间更新值。您可以在验证器中执行此操作,因为您确实拥有可用的 AbstractControl。调用 setValue
或 patchValue
可以为您做到这一点。但这将再次触发验证并可能导致无限递归循环,因此请注意这一点。此外,您可能想要更改为在模糊时发出值更新,而不是在每次击键时发出。您可以使用 updateOn: blur
选项在每个表单控件上执行此操作。
fromDate: new FormControl('', { updateOn: 'blur', validators: [...] })
这是我用于快速原型的 stackblitz:https://stackblitz.com/edit/angular-ivy-jfes5n