Angular 中的日期和货币验证 (4)
Date and Currency validation in Angular (4)
我是 Angular 的新手。我正在使用 angular 4 种反应形式,并弄清楚了如何执行自定义验证。以下是我对 numeric
的实现
function numberValidator(c: AbstractControl): { [key: string]: boolean } | null {
if (c.pristine) {
return null;
}
if (c.value.match(/.*[^0-9].*/)) {
return { 'numeric': true };
}
return null;
}
phoneControl: ['', [Validators.required, Validators.minLength(10), Validators.maxLength(10), numberValidator]],
我正在尝试了解如何执行货币(带或不带两位小数)以及最重要的日期字段。
请原谅我是否在其他地方回答了这个问题,但我找不到 angular(4)
的任何示例
感谢您的宝贵时间
您需要什么样的日期验证?只是该值是有效日期?如果您在输入元素上设置 type="date"
,浏览器将确保只输入有效日期。
对于您显示的数字验证器和任何货币验证器都是一样的。您应该能够在输入元素上设置 type="number"
,并且不需要验证器。
如果您仍然 想要执行自己的验证,您可以像示例中那样使用正则表达式。
只需查找货币和日期的正则表达式。对于日期,是这样的:Javascript - Regex to validate date format
创建了一个自定义验证器来处理格式 MM/DD/YYYY 和 MMDDYYYY
function dateValidator(c: AbstractControl): { [key: string]: boolean } | null {
if (c.pristine) {
return null;
}
if ((c.value !== undefined && c.value !== '' && c.value != null)) {
var month = null;
var day = null;
var year = null;
var currentTaxYear = Number(new Date().getFullYear() - 1);
if (c.value.indexOf('/') > -1) {
var res = c.value.split("/");
if (res.length > 1) {
month = res[0];
day = res[1]
year = res[2];
}
}
else {
if (c.value.length == 8) {
month = c.value.substring(0, 2);
day = c.value.substring(2, 4);
year = c.value.substring(4, 8);
}
}
if (isNaN(month) || isNaN(day) || isNaN(year)) {
return { 'dateInvalid': true };
}
month = Number(month);
day = Number(day);
year = Number(year);
if (month < 1 || month > 12) { // check month range
return { 'dateInvalid': true };
}
if (day < 1 || day > 31) {
return { 'dateInvalid': true };
}
if ((month === 4 || month === 6 || month === 9 || month === 11) && day === 31) {
return { 'dateInvalid': true };
}
if (month == 2) { // check for february 29th
var isleap = (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0));
if (day > 29 || (day === 29 && !isleap)) {
return { 'dateInvalid': true };
}
}
if (year !== currentTaxYear) {
return { 'dateYearGreaterThanTaxYear': true };
}
}
return null;
}
这是使用自定义验证器的另一种选择
import { FormControl } from '@angular/forms';
export class DateValidator {
static ptDate(control: FormControl): { [key: string]: any } {
let ptDatePattern = /^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g;
if (!control.value.match(ptDatePattern))
return { "ptDate": true };
return null;
}
static usDate(control: FormControl): { [key: string]: any } {
let usDatePattern = /^02\/(?:[01]\d|2\d)\/(?:19|20)(?:0[048]|[13579][26]|[2468][048])|(?:0[13578]|10|12)\/(?:[0-2]\d|3[01])\/(?:19|20)\d{2}|(?:0[469]|11)\/(?:[0-2]\d|30)\/(?:19|20)\d{2}|02\/(?:[0-1]\d|2[0-8])\/(?:19|20)\d{2}$/;
if (!control.value.match(usDatePattern))
return { "usDate": true };
return null;
}
}
并以这种方式用于 "dd/mm/yyyy" 格式:
this.formDetail = this.formBuilder.group({
date: ['', DateValidator.ptDate],
});
并以这种方式用于 "mm/dd/yyyy" 格式:
this.formDetail = this.formBuilder.group({
date: ['', DateValidator.usDate],
});
希望对您有所帮助!
这是我的解决方案:
import {AbstractControl} from "@angular/forms";
export class MyValidators {
// validate MM/DD/YYYY
static date(c: AbstractControl): { [key: string]: boolean } {
let value = c.value;
if (value && typeof value === "string") {
let match = value.match(/^([0-9]{1,2})\/([0-9]{1,2})\/([0-9]{4})$/);
if (!match) {
return {'dateInvalid': true};
}
let date = new Date(`${match[3]}-${match[1]}-${match[2]}`);
if (isNaN(date.getTime())) {
return {'dateInvalid': true};
}
}
return null;
}
}
如果您使用的是 Angular Material,您可以使用 MatDatepicker 与 Moment.js 的集成来使用 FormControl 验证自定义日期格式,如下所示:
https://material.angular.io/components/datepicker/overview#customizing-the-parse-and-display-formats
HTML:
<input matInput [matDatepicker]="dp" placeholder="Verbose datepicker" [formControl]="date">
TS:
export const MY_FORMATS = {
parse: {
dateInput: 'LL',
},
display: {
dateInput: 'LL',
monthYearLabel: 'MMM YYYY',
dateA11yLabel: 'LL',
monthYearA11yLabel: 'MMMM YYYY',
},
};
@Component({
selector: 'datepicker-formats-example',
templateUrl: 'datepicker-formats-example.html',
styleUrls: ['datepicker-formats-example.css'],
providers: [
{provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE]},
{provide: MAT_DATE_FORMATS, useValue: MY_FORMATS},
],
})
export class DatepickerFormatsExample {
date = new FormControl(moment());
}
如果您使用反应式表单,您可以编写自定义验证器,见下文
dateValidator(c: AbstractControl): { [key: string]: boolean } {
let value = c.value;
if (value && typeof value === "string") {
let match = value.match(/^([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))/);
if (!match) {
return { 'dateInvalid': true };
} else if (match && match[0] !== value) {
return { 'dateInvalid': true };
}
}
return null;
}
创建控件时,您需要将此验证器与其他验证器一起添加,如下所示,
const group = this.fb.group({
DateType: ['', [Validators.required, this.dateValidator]],
})
这是 (imo) 更好的日期验证函数:
function date(c: AbstractControl): { [key: string]: boolean } {
let value = new Date(c.value);
return isNaN(value.getTime()) || value <= new Date('01/01/1753') ? {'dateInvalid': true} : undefined;
}
这个解决方案对我有效并且满足以下条件
- 开始日期 < 结束日期
- 开始日期 >= 今天
- 结束日期 >= 今天
app.component.html
<form [formGroup]="addContract>
<div class="form-group">
<label>Start Date *</label>
<input type="date" name="startDate" formControlName="startDate"
class="form-control" placeholder="Arrival *"
[ngClass]="{ 'is-invalid': submitted && f.startDate.errors}"/>
<div *ngIf="f.startDate.touched">
<small *ngIf="f.startDate.errors?.required"
class="text-danger">Required</small>
<small *ngIf="addContract.errors?.invaineFrom" class="text-danger">
Select a date Over today</small>
</div>
</div>
<div class="form-group">
<label>End Date*</label>
<input type="date" name="endDate" formControlName="endDate"
class="form-control" placeholder="Departure *"
[class.is-invalid]="endDate.invalid && endDate.touched"/>
<div *ngIf="f.endDate.touched">
<small *ngIf="endDate.errors?.required &&
endDate.touched ">Required</small>
<small *ngIf="addContract.errors?.invaineTo" class="text-danger">
choose a date over today</small>
<small *ngIf="addContract.errors?.dates" class="text-danger">
End Date should be grater than start Date</small>
</div>
</div>
</div>
</form>
app.component.ts
import { DateValidator} from '../shared/date-validator';
export class AppComponent implements OnInit {
addContract: FormGroup;
ngOnInit() {
this.addContract = this.fb.group({
startDate: ['', [Validators.required]],
endDate: ['', [Validators.required]]
}, {validator: DateValidator});
get f() { return this.addContract.controls; }
get endDate() {
return this.addContract.get('endDate');
}
get startDate() {
return this.addContract.get('startDate');
}
}
日期-validator.ts
import {AbstractControl} from '@angular/forms';
export function DateValidator(control: AbstractControl): { [ key: string]: boolean} | null {
let from = control.get('startDate');
let to = control.get('endDate');
let c= new Date();
if(new Date(from.value)< c )
{
return {
invaineFrom:true
}
}
if(new Date(to.value) < c )
{
return {
invaineTo:true
}
}
if (from.value > to.value ) {
return {
dates: true
};
}
return {};
}
Angular mat-datepicker 添加 matDatepickerParse 到表单控件错误对象,如果它不能解析输入字符串
我是 Angular 的新手。我正在使用 angular 4 种反应形式,并弄清楚了如何执行自定义验证。以下是我对 numeric
的实现function numberValidator(c: AbstractControl): { [key: string]: boolean } | null {
if (c.pristine) {
return null;
}
if (c.value.match(/.*[^0-9].*/)) {
return { 'numeric': true };
}
return null;
}
phoneControl: ['', [Validators.required, Validators.minLength(10), Validators.maxLength(10), numberValidator]],
我正在尝试了解如何执行货币(带或不带两位小数)以及最重要的日期字段。
请原谅我是否在其他地方回答了这个问题,但我找不到 angular(4)
的任何示例感谢您的宝贵时间
您需要什么样的日期验证?只是该值是有效日期?如果您在输入元素上设置 type="date"
,浏览器将确保只输入有效日期。
对于您显示的数字验证器和任何货币验证器都是一样的。您应该能够在输入元素上设置 type="number"
,并且不需要验证器。
如果您仍然 想要执行自己的验证,您可以像示例中那样使用正则表达式。
只需查找货币和日期的正则表达式。对于日期,是这样的:Javascript - Regex to validate date format
创建了一个自定义验证器来处理格式 MM/DD/YYYY 和 MMDDYYYY
function dateValidator(c: AbstractControl): { [key: string]: boolean } | null {
if (c.pristine) {
return null;
}
if ((c.value !== undefined && c.value !== '' && c.value != null)) {
var month = null;
var day = null;
var year = null;
var currentTaxYear = Number(new Date().getFullYear() - 1);
if (c.value.indexOf('/') > -1) {
var res = c.value.split("/");
if (res.length > 1) {
month = res[0];
day = res[1]
year = res[2];
}
}
else {
if (c.value.length == 8) {
month = c.value.substring(0, 2);
day = c.value.substring(2, 4);
year = c.value.substring(4, 8);
}
}
if (isNaN(month) || isNaN(day) || isNaN(year)) {
return { 'dateInvalid': true };
}
month = Number(month);
day = Number(day);
year = Number(year);
if (month < 1 || month > 12) { // check month range
return { 'dateInvalid': true };
}
if (day < 1 || day > 31) {
return { 'dateInvalid': true };
}
if ((month === 4 || month === 6 || month === 9 || month === 11) && day === 31) {
return { 'dateInvalid': true };
}
if (month == 2) { // check for february 29th
var isleap = (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0));
if (day > 29 || (day === 29 && !isleap)) {
return { 'dateInvalid': true };
}
}
if (year !== currentTaxYear) {
return { 'dateYearGreaterThanTaxYear': true };
}
}
return null;
}
这是使用自定义验证器的另一种选择
import { FormControl } from '@angular/forms';
export class DateValidator {
static ptDate(control: FormControl): { [key: string]: any } {
let ptDatePattern = /^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g;
if (!control.value.match(ptDatePattern))
return { "ptDate": true };
return null;
}
static usDate(control: FormControl): { [key: string]: any } {
let usDatePattern = /^02\/(?:[01]\d|2\d)\/(?:19|20)(?:0[048]|[13579][26]|[2468][048])|(?:0[13578]|10|12)\/(?:[0-2]\d|3[01])\/(?:19|20)\d{2}|(?:0[469]|11)\/(?:[0-2]\d|30)\/(?:19|20)\d{2}|02\/(?:[0-1]\d|2[0-8])\/(?:19|20)\d{2}$/;
if (!control.value.match(usDatePattern))
return { "usDate": true };
return null;
}
}
并以这种方式用于 "dd/mm/yyyy" 格式:
this.formDetail = this.formBuilder.group({
date: ['', DateValidator.ptDate],
});
并以这种方式用于 "mm/dd/yyyy" 格式:
this.formDetail = this.formBuilder.group({
date: ['', DateValidator.usDate],
});
希望对您有所帮助!
这是我的解决方案:
import {AbstractControl} from "@angular/forms";
export class MyValidators {
// validate MM/DD/YYYY
static date(c: AbstractControl): { [key: string]: boolean } {
let value = c.value;
if (value && typeof value === "string") {
let match = value.match(/^([0-9]{1,2})\/([0-9]{1,2})\/([0-9]{4})$/);
if (!match) {
return {'dateInvalid': true};
}
let date = new Date(`${match[3]}-${match[1]}-${match[2]}`);
if (isNaN(date.getTime())) {
return {'dateInvalid': true};
}
}
return null;
}
}
如果您使用的是 Angular Material,您可以使用 MatDatepicker 与 Moment.js 的集成来使用 FormControl 验证自定义日期格式,如下所示:
https://material.angular.io/components/datepicker/overview#customizing-the-parse-and-display-formats
HTML:
<input matInput [matDatepicker]="dp" placeholder="Verbose datepicker" [formControl]="date">
TS:
export const MY_FORMATS = {
parse: {
dateInput: 'LL',
},
display: {
dateInput: 'LL',
monthYearLabel: 'MMM YYYY',
dateA11yLabel: 'LL',
monthYearA11yLabel: 'MMMM YYYY',
},
};
@Component({
selector: 'datepicker-formats-example',
templateUrl: 'datepicker-formats-example.html',
styleUrls: ['datepicker-formats-example.css'],
providers: [
{provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE]},
{provide: MAT_DATE_FORMATS, useValue: MY_FORMATS},
],
})
export class DatepickerFormatsExample {
date = new FormControl(moment());
}
如果您使用反应式表单,您可以编写自定义验证器,见下文
dateValidator(c: AbstractControl): { [key: string]: boolean } {
let value = c.value;
if (value && typeof value === "string") {
let match = value.match(/^([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))/);
if (!match) {
return { 'dateInvalid': true };
} else if (match && match[0] !== value) {
return { 'dateInvalid': true };
}
}
return null;
}
创建控件时,您需要将此验证器与其他验证器一起添加,如下所示,
const group = this.fb.group({
DateType: ['', [Validators.required, this.dateValidator]],
})
这是 (imo) 更好的日期验证函数:
function date(c: AbstractControl): { [key: string]: boolean } {
let value = new Date(c.value);
return isNaN(value.getTime()) || value <= new Date('01/01/1753') ? {'dateInvalid': true} : undefined;
}
这个解决方案对我有效并且满足以下条件
- 开始日期 < 结束日期
- 开始日期 >= 今天
- 结束日期 >= 今天
app.component.html
<form [formGroup]="addContract>
<div class="form-group">
<label>Start Date *</label>
<input type="date" name="startDate" formControlName="startDate"
class="form-control" placeholder="Arrival *"
[ngClass]="{ 'is-invalid': submitted && f.startDate.errors}"/>
<div *ngIf="f.startDate.touched">
<small *ngIf="f.startDate.errors?.required"
class="text-danger">Required</small>
<small *ngIf="addContract.errors?.invaineFrom" class="text-danger">
Select a date Over today</small>
</div>
</div>
<div class="form-group">
<label>End Date*</label>
<input type="date" name="endDate" formControlName="endDate"
class="form-control" placeholder="Departure *"
[class.is-invalid]="endDate.invalid && endDate.touched"/>
<div *ngIf="f.endDate.touched">
<small *ngIf="endDate.errors?.required &&
endDate.touched ">Required</small>
<small *ngIf="addContract.errors?.invaineTo" class="text-danger">
choose a date over today</small>
<small *ngIf="addContract.errors?.dates" class="text-danger">
End Date should be grater than start Date</small>
</div>
</div>
</div>
</form>
app.component.ts
import { DateValidator} from '../shared/date-validator';
export class AppComponent implements OnInit {
addContract: FormGroup;
ngOnInit() {
this.addContract = this.fb.group({
startDate: ['', [Validators.required]],
endDate: ['', [Validators.required]]
}, {validator: DateValidator});
get f() { return this.addContract.controls; }
get endDate() {
return this.addContract.get('endDate');
}
get startDate() {
return this.addContract.get('startDate');
}
}
日期-validator.ts
import {AbstractControl} from '@angular/forms';
export function DateValidator(control: AbstractControl): { [ key: string]: boolean} | null {
let from = control.get('startDate');
let to = control.get('endDate');
let c= new Date();
if(new Date(from.value)< c )
{
return {
invaineFrom:true
}
}
if(new Date(to.value) < c )
{
return {
invaineTo:true
}
}
if (from.value > to.value ) {
return {
dates: true
};
}
return {};
}
Angular mat-datepicker 添加 matDatepickerParse 到表单控件错误对象,如果它不能解析输入字符串