Pardeep
Pardeep

Reputation: 161

Angular Material Date Validator gets invalid value

<mat-form-field>
<input matInput [(ngModel)]="myDate" name="myDate" [matDatepicker]="Datepicker"
                        (click)="Datepicker.open()" >
<mat-datepicker-toggle matSuffix [for]="Datepicker"></mat-datepicker-toggle>
<mat-error>Invaild Date</mat-error>
</mat-form-field>
<mat-datepicker #Datepicker></mat-datepicker>

this.form = this.fb.group({
      myDate: [this.dateService.dateValidator]
});


dateValidator(control: FormControl) {
      console.log(control.value) <<<< problem here
}

Dear all,

I tried to input a date value "1" to the date field, however, the control.value in dateValidator returns 2001-01-01 GMT 00:00. It makes the dateValidator always passes even I filled-in "1" into the date field. How can I get the original value "1" from "control.value" instead of the auto-converted value? Thanks

Upvotes: 3

Views: 11032

Answers (2)

gizmo
gizmo

Reputation: 201

The reason of why this happens is because Material registers an input listener on its DatePicker's input:

_onInput(value: string) {
  let date = this._dateAdapter.parse(value, this._dateFormats.parse.dateInput);

And parse() method does this:

parse(value: any): Date | null {
  if (typeof value == 'number') {
    return new Date(value);
  }

So when user writes 1 in your input, behind the scene it becomes into new Date(1)

So to answer your question - "How can I get the original value "1" from "control.value", you could overrite both input and change events:

<input matInput 
       [(ngModel)]="myDate" 
       name="myDate" [matDatepicker]="Datepicker"
       (click)="Datepicker.open()" 
       (input)="someMethod($event.target.value)" 
       (change)="someMethod($event.target.value)">

Upvotes: 2

Akj
Akj

Reputation: 7231

Try like this:

Live Example

HTML:

<h1>
    Try Reactive Form Validation with custom validation
</h1>

<form [formGroup]="basicForm">
    <div>
        <input type="text" formControlName="myDate" />
        <p *ngIf="basicForm.get('myDate').hasError('required') && basicForm.get('myDate').touched">Required</p>
        <p *ngIf="basicForm.get('myDate').hasError('invalidDate')">Invalid Date DD/MM/YYYY</p>
    </div>
</form>

TS:

 basicForm: FormGroup;


  ngOnInit() {
    this.createForm();
  }

  constructor(private fb: FormBuilder) {
  }

  createForm() {
    this.basicForm = this.fb.group({

      myDate: [null, [Validators.required, CustomValidatorService.dateValidator]]
    })
  }

validation_service.ts:

import { Injectable } from '@angular/core';
import { AbstractControl, FormControl, ValidatorFn } from '@angular/forms';

@Injectable()
export class CustomValidatorService {

  constructor() { }

  static dateValidator(control: FormControl) {
    if (control.value) {
      const matches = control.value.match(/^\d{2}\/\d{2}\/\d{4}$/);
      return matches ? null : { 'invalidDate': true };
    } else {
      return null;
    }
  }
}

Upvotes: 0

Related Questions