我有一个用于选择日期的输入字段。我想应用一个简单的验证,如果这个字段是空的,那么提交按钮应该被禁用,当它被填充时,它应该是同步的。
日期字段有一些问题,当我通过ng-valid检查时,它应该在日期字段中没有输入任何内容时给出false,但是从单词go开始它就给出true。
我创建了一个简单的例子,使用StackBlitz有一个单一的输入日期,现在我需要在输入字段为空时禁用它,并在输入填充时激活它。
https://stackblitz.com/edit/ngx-daterangepicker-material-for-angular8-5ikovy?file=src/app/app.component.html
这是由于日期选择器部分的实现不佳。默认情况下,他们将控件的值设置为{start: null, end: null}
。https://stackblitz.com/edit/ngx-daterangepicker-material-for-angular8-fa73zq?file=src/app/app.component.html
默认的required
验证器检查controlValue == null
和被库设置为控件的对象是否不为空。如果您需要使用这个库,您需要编写您的自定义验证器,它将检查start
和end
是否为空,如果是,它应该返回一个错误。
您可以在这里查看如何操作:https://angular.io/guide/form-validation#adding-custom-validators-to-template-driven-forms
默认情况下,当输入日期为空时,其值为{ "start": null, "end": null }
。所以"要求"验证器不会使该值无效,因为这是一个有效的对象。
一个简单的修复方法:
<button
[disabled]="!(date.value.start && date.value.end)"
>...</button>
正如其他人提到的,这是由于值为{ start: null, end: null }
。你可以通过创建一个自定义验证器来解决这个问题——这样做的好处是你的表单的有效状态将是正确的。
你可以定义一个验证器作为一个指令,如下(可能有一个接口已经存在于你的日期选择器包,所以可能不需要那部分):
interface DateRange {
start: Moment | null;
end: Moment | null;
}
@Directive({
selector: '[appDateRange]',
providers: [
{
provide: NG_VALIDATORS,
useExisting: DateRangeValidatorDirective,
multi: true,
},
],
})
export class DateRangeValidatorDirective implements Validator {
validate(control: AbstractControl): ValidationErrors | null {
return this.dateRangeValidator(control);
}
dateRangeValidator: ValidatorFn = (
control: AbstractControl
): ValidationErrors | null => {
if (!control.value) return null;
const dateRange = control.value as DateRange;
console.log('VALIDATE', dateRange);
return dateRange.start && dateRange.end ? null : { dateRange: true };
};
}
确保在你的模块中也定义了这个:
@NgModule({
declarations: [
...
DateRangeValidatorDirective
]
...
})
然后您可以使用它,就像使用指令选择器(appDateRange
)在输入上使用required
验证器一样:
<input ... appDateRange>
所以你可以在按钮上加上:
<button ... [disabled]="date.errors?.required && date.errors?.dateRange"> ...
如果你想了解更多,这里有一个很好的例子https://angular.io/guide/form-validation, forbiddenNameValidator在页面上。