reactive form validation fails for correct date selected from datepicker or program entered

Am on angular 5 and not sure if i am doing things right. Basically, i have validation for date field, which must be today or before. Else, it is error. If I enter the dates, the validation works perfectly.If a correct date is selected from datepicker or I enter data from code such as inputelement.value='2018-01-01', the control is marked as invalid until I change something in the value and lost focus. Here is the code I am using:

component.ts:

            this.rForm = fb.group({
  'processedon' : [null, [Validators.required,dateIsBeforeOrOnToday]]

        });

the validator:

        export function dateIsBeforeOrOnToday(control: AbstractControl) {

    var date=control.value;

    if (dateisvalid(date)==false){
         //another method confirms the date is valid
        return { validDate: true };
    }

    //confirm it is before today or today
    date = new Date(Date.parse(date));
    let today=new Date();
    today.setHours(0,0,0,0);

    if (date <= today) {

        return null;
    } 

    return { validDate: true };

}

the html:

     <div class="input-group">
    <input type="text" class="form-control" formControlName="processedon" ngbDatepicker #d="ngbDatepicker"/>
    <span class="input-group-addon" (click)="d.toggle()">
        <i class="fa fa-calendar"></i>
    </span>
</div>

The issue here is if i select an otherwise valid date with the bootstrap datepicker, it still says it is invalid. I simply have to just change anything (e.g. 2018-01-01, remove last 1 then put it back) then it becomes valid.

1 answer

  • answered 2018-01-13 17:34 JB Nizet

    Your validator is wrong. An ng-bootstrap datepicker's model is of type NgbDateStruct, i.e. an object with a year, a month (starting from 1) and a day. Such an object can't be passed to Date.parse().

    Here's a working example, showing a correct validator. Read the ng-bootstrap documentation, and learn to use TypeScript and specify types.

    export function dateIsBeforeOrOnToday(control: FormControl) {
        const dateStruct: NgbDateStruct = control.value;
        if (!dateStruct || !dateStruct.year || !dateStruct.month || !dateStruct.day) {
          return { validDate: true };
        }
        //confirm it is before today or today
        const date = new Date(dateStruct.year, dateStruct.month - 1, dateStruct.day);
    
        let today = new Date();
        today.setHours(0,0,0,0);
    
        if (date <= today) {
            return null;
        } 
    
        return { validDate: true };
    }