2
votes

I have a problem that I initially thought was a regex error, but I've deduced that it is a problem with how the material datepicker is putting the date string into the input as a full date object instead of the string version of the date as it is shown in the input, and thus setting off a validation message.

Below is how I'm using it, and then two screen shots showing the same date failing validation with the date picker, and passing it if the date picker is removed/commented out and simply typed into the input.

<div class="col-xs-12 col-sm-6">
                                    <div class="form-group" [ngClass]="{'td-group-error': (changeForm.get('changeInfoFG.dateSubmitted').touched || changeForm.get('changeInfoFG.dateSubmitted').dirty) && !changeForm.get('changeInfoFG.dateSubmitted').valid }">
                                        <span><input id="dateSubmittedId" class="form-control" type="text" formControlName="dateSubmitted" [mdDatepicker]="sbdate" style="width:90%;display:inline-block">
                                    <md-datepicker-toggle [for]="sbdate"></md-datepicker-toggle>
                                    <md-datepicker #sbdate></md-datepicker></span>
                                        <div class="error-block" *ngIf="(changeForm.get('changeInfoFG.dateSubmitted').touched || changeForm.get('changeInfoFG.dateSubmitted').dirty) && !changeForm.get('changeInfoFG.dateSubmitted').valid"
                                            role="alert" style="color: #ae0101"> <strong>!</strong>
                                            <span *ngIf="changeForm.get('changeInfoFG.dateSubmitted').errors.required">Required</span>
                                            <span *ngIf="changeForm.get('changeInfoFG.dateSubmitted').errors.pattern">Date must be mm/dd/yyyy, date is currently: {{changeForm.get('changeInfoFG.dateSubmitted').value}}</span>
                                        </div>
                                    </div>
                                </div>

With DatePicker

enter image description here

Without DatePicker

enter image description here

And this is the validator being used, enforcing a short date string representation of a date in m/d/yyyy/ mm/dd/yyyy formats.

dateSubmitted: [null, [Validators.required, Validators.pattern('^(?:(?:10|12|0?[13578])/(?:3[01]|[12][0-9]|0?[1-9])/(?:1[8-9]\\d{2}|[2-9]\\d{3})|(?:11|0?[469])/(?:30|[12][0-9]|0?[1-9])/(?:1[8-9]\\d{2}|[2-9]\\d{3})|0?2/(?:2[0-8]|1[0-9]|0?[1-9])/(?:1[8-9]\\d{2}|[2-9]\\d{3})|0?2/29/[2468][048]00|0?2/29/[3579][26]00|0?2/29/[1][89][0][48]|0?2/29/[2-9][0-9][0][48]|0?2/29/1[89][2468][048]|0?2/29/[2-9][0-9][2468][048]|0?2/29/1[89][13579][26]|0?2/29/[2-9][0-9][13579][26])$')]],

I would like to be able to use the datepicker to get exactly the date string the material datepicker places in the input as shown, as opposed to the full date object it's actually putting in. Can someone help me figure out how I would go about that?

1

1 Answers

1
votes

Angular Material Datepicker already has validators, you only need to create formControlName for datepicker but without validators.pattern('regExp').

<md-form-field class="form-field" color="accent">
    <input mdInput [mdDatepicker]="picker" name="birthDate" 
     formControlName="dateCtrl">
    <md-datepicker-toggle mdSuffix [for]="picker"></md-datepicker-toggle>
    <md-datepicker #picker></md-datepicker>
</md-form-field>

And this is the formControlName being used without validator

dateCtrl: ['']

I tested most of the validations for format mm/dd/yyyy and only found an error in the year. It can accept years with 5 digits.

Custom Validators You can do a custom validator. First, check if control value is a string and then to apply regExp for format date.

import { ValidatorFn, AbstractControl } from "@angular/forms";

export function dateFormatValidator(control: AbstractControl) {
   let date = control.value;
   if (date) {
       if (typeof date === 'string' && typeof date !== null) {
           if (/[0-9]{4}-(0?[1-9]|1[0-2])-(0?[1-9]|1\d|2\d|3[01])/.test(date)) 
        {
            return null;
        } else {
            return { 'forbiddenName': { value: control.value } };
        }
      }

   return null;
   }

Then, you must import custom validator in your control definition.

  ...
  dateCtrl: [null, dateFormatValidator]
  ...

Regards.