Angular 9中FormBuilder日期验证双提示无法区分的问题
Angular日期输入框:区分必填与无效日期的验证提示方案
问题描述
使用Angular FormBuilder为日期输入框设置验证时,原生date输入框会自动校验日期合法性:
- 若输入非法日期(如2023-02-30),表单控件值会被置为
null - 这会导致
Validators.required触发,无法区分「未填写日期」和「填写了无效日期」两种场景,无法分别展示对应的错误提示
解决方案
通过自定义验证器结合输入框的原始输入值,判断无效日期的场景,从而添加独立的错误标识,实现两种提示的区分。
步骤1:编写自定义日期有效性验证器
创建一个验证器函数,通过获取输入框的原始字符串值,判断是否为无效日期导致的null值:
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms'; import { ElementRef } from '@angular/core'; // 自定义验证器工厂函数,接收输入框元素引用 export function validDateValidator(inputElement: ElementRef<HTMLInputElement>): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { const controlValue = control.value; const rawInputValue = inputElement.nativeElement.value; // 若原始输入不为空,但控件值为null,说明是无效日期 if (rawInputValue && !controlValue) { return { invalidDate: true }; } return null; }; }
步骤2:更新表单配置
在表单创建时,同时添加Validators.required和自定义验证器:
import { Component, ViewChild, ElementRef, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import * as dateFormat from "dateformat"; import { validDateValidator } from './validators'; @Component({ selector: 'app-date-form', templateUrl: './date-form.component.html' }) export class DateFormComponent implements OnInit { updateForm: FormGroup; submitted = false; @ViewChild('dateInput') dateInput!: ElementRef<HTMLInputElement>; constructor(private fb: FormBuilder) { } ngOnInit(): void { this.createForm(); } createForm() { const now = new Date(); this.updateForm = this.fb.group({ date: [ dateFormat(now, "yyyy-mm-dd"), [Validators.required, validDateValidator(this.dateInput)] ] }); } get f() { return this.updateForm.controls; } onSubmit() { this.submitted = true; if (this.updateForm.invalid) { return; } // 处理表单提交逻辑 console.log('合法日期:', this.updateForm.value.date); } }
步骤3:修改模板展示对应错误提示
在模板中根据错误类型分别展示必填提示和无效日期提示:
<form [formGroup]="updateForm" (ngSubmit)="onSubmit()"> <input #dateInput type="date" class="form-control input is-primary" formControlName="date" [ngClass]="{ 'is-invalid': submitted && f.date.errors }" cdkFocusInitial /> <div *ngIf="submitted && f.date.errors" class="help is-danger"> <div *ngIf="f.date.errors.required">日期为必填项</div> <div *ngIf="f.date.errors.invalidDate">输入的日期无效,请检查格式或日期合法性</div> </div> <button type="submit">提交</button> </form>
原理说明
原生date输入框在检测到非法日期时,会将表单控件值置为null,但输入框的原始字符串值仍会保留。自定义验证器通过对比原始输入值和控件值,判断是否为无效日期场景,添加invalidDate错误标识,从而与required错误区分开,实现不同提示的展示。
内容的提问来源于stack exchange,提问作者any-1507
相关产品推荐
相关产品推荐

