Je suis nouveau sur Angular. J'utilise angular 4 formulaires réactifs et compris comment effectuer des validations personnalisées. Voici mon implémentation pour numérique
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]],
J'essaie de savoir comment effectuer la devise (avec ou sans deux décimales) et surtout le champ Date.
Pardonnez-moi si cela a été répondu ailleurs mais je ne trouve aucun échantillon pour angular (4)
Merci pour votre temps
De quel type de validation de date avez-vous besoin? Juste que la valeur est une date valide? Si vous définissez le type="date"
sur l'élément d'entrée, le navigateur s'assurera que seule une date valide est entrée.
Idem pour votre validateur de numéro affiché et pour tout validateur de devise. Vous devriez pouvoir définir le type="number"
sur l'élément d'entrée et vous n'aurez pas besoin d'un validateur.
Si vous voulez toujours effectuer votre propre validation, vous pouvez utiliser des expressions régulières comme dans votre exemple.
Recherchez simplement les expressions régulières pour la devise et la date. Pour la date, quelque chose comme ceci: Javascript - Regex pour valider le format de date
Ceci est une autre option pour utiliser des validateurs personnalisés
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;
}
}
et utilisez-le de cette façon pour le format "jj/mm/aaaa":
this.formDetail = this.formBuilder.group({
date: ['', DateValidator.ptDate],
});
et utilisez-le de cette façon pour le format "mm/jj/aaaa":
this.formDetail = this.formBuilder.group({
date: ['', DateValidator.usDate],
});
J'espère que cette aide!
Création d'un validateur personnalisé pour gérer les formats MM/DD/YYYY et 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;
}
Voici ma solution:
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;
}
}
Si vous utilisez des formulaires réactifs, vous pouvez écrire un validateur personnalisé, voir ci-dessous
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;
}
Lors de la création du contrôle, vous devez ajouter ce validateur avec vos autres validateurs comme indiqué ci-dessous,
const group = this.fb.group({
DateType: ['', [Validators.required, this.dateValidator]],
})
Si vous utilisez Angular Material, vous pouvez utiliser l'intégration MatDatepicker avec Moment.js pour valider un format de date personnalisé à l'aide de FormControl comme indiqué ici:
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());
}