1

I need to validate a date of birth control of a reactive form, so if a user selected a value from the future, to disable the save button:

import { AbstractControl } from '@angular/forms';

export function validateDOB(control: AbstractControl)
{

    let currentDateTime = new Date();
    let monthValue = currentDateTime.getMonth()+1;
    let formattedDate = currentDateTime.getFullYear() +'-'+ monthValue +'-'+currentDateTime.getDay();

    let controlValue = control.value;
    let monthOfControlValue = controlValue.getMonth()+1;
    let FinalControlValue = controlValue.getFullYear()+'-'+monthOfControlValue+'-'+controlValue.getDay;
    console.log(FinalControlValue)
    if(formattedDate<control.value)
    {
        return {response: true};
    }
    return null;
}

Explanation:

I am working with angular material date picker, so the date will be displayed like the following:

Mon Oct 01 2018 00:00:00 GMT+0300 (Eastern European Summer Time)

the first 3 line are getting the current date and transforming it to YYYY-mm-dd format:

let currentDateTime = new Date();
let monthValue = currentDateTime.getMonth()+1;
let formattedDate = currentDateTime.getFullYear() +'-'+ 
              monthValue +'-'+currentDateTime.getDay();

The last 3 lines are converting the date selected by the user:

let monthOfControlValue = controlValue.getMonth()+1;
let FinalControlValue = controlValue.getFullYear()+'-'+monthOfControlValue+'-'+controlValue.getDay;
console.log(FinalControlValue )

At the user side, any date, whether it was less than or greater than, the validation will not work.

I tried to make the comparison without converting into YYYY-mm-dd, but it didn't/wouldn't work.

I changed the script by changing the value of the control into a new date:

let controlValue = new Date(control.value);

And the script is now like:

import { AbstractControl } from '@angular/forms';

export function validateDOB(control: AbstractControl)
{

    let currentDateTime = new Date();
    let monthValue = currentDateTime.getMonth()+1;
    let formattedDate = currentDateTime.getFullYear() +'-'+ monthValue +'-'+currentDateTime.getDay();
    console.log(formattedDate)
    let controlValue = new Date(control.value);
    let monthOfControlValue = controlValue.getMonth()+1;
    let FinalControlValue = controlValue.getFullYear()+'-'+monthOfControlValue+'-'+controlValue.getDay();
    console.log(FinalControlValue)
    if(formattedDate<control.value)
    {
        return {response: true};
    }
    return null;
}

And still not working.

alim1990
  • 4,656
  • 12
  • 67
  • 130

3 Answers3

3

Instead of writing custom Validate function to disable the dates, I would use MAX property of date picker to disable the Today's Date and Future dates from being selected.

The HTML Code:

<mat-form-field class="example-full-width">
  <input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="picker" placeholder="Choose a date">
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

And in TS file:

 minDate = new Date(1900, 0, 1);
 maxDate =  new Date(new Date().setDate(new Date().getDate()-1))

Here is StackBlitz Example

Reference Link

Prashant Pimpale
  • 10,349
  • 9
  • 44
  • 84
1

could you try this?

if(currentDateTime <controlValue )

with

let controlValue = new Date(control.value);

formattedDate is a string in this case.

lesiano
  • 288
  • 3
  • 9
1

Part of the answer is based on the help provided by @lesiano. But the main problem was that the comparing is including the time. And as mentioned in this old stack overflow answer, we need to set the time of the date into 0's, so the comparison take place:

date1.setHours(0,0,0,0)

The working custom validator is:

import { AbstractControl } from '@angular/forms';

export function validateDOB(control: AbstractControl)
{

    let currentDateTime = new Date();
    currentDateTime.setHours(0,0,0,0);

    let controlValue = new Date(control.value);
    controlValue.setHours(0,0,0,0);

    //console.log(currentDateTime+'-'+controlValue)

    if(currentDateTime<control.value)
    {
        return {response: true};
    }
    return null;
}
alim1990
  • 4,656
  • 12
  • 67
  • 130