Angular - Input with ngx-mask MatDatepicker and reactive form

12.9k Views Asked by At

I would like to add a reactive form control over a form and an error is triggered:

More than one custom value accessor matches form control with unspecified name attribute

Everything works separately, reactive form validation, mask or matDatepicker, any couple combination also works, but the three together prompt the error.

Here is my code:

In component.ts

formGroup = new FormGroup({
    date: new FormControl()
  });

In component.html

    <mat-form-field>
      <input type="text" matInput [matDatepicker]="date_picker" mask="d0/M0/0000" formControlName="date">
      <mat-datepicker-toggle matSuffix [for]="date_picker"></mat-datepicker-toggle>
      <mat-datepicker #date_picker></mat-datepicker>
    </mat-form-field>

I'm using:

"@angular/cli": "8.3.19"
"ngx-mask": "8.1.7"
"@angular/material": "8.2.3"
2

There are 2 best solutions below

2
On BEST ANSWER

I am struggling the same issue. According to this thread, there is no solution only a workaround: Error: More than one custom value accessor matches form control with unspecified name attribute

I used the workaround mentioned, with vanilla-text-mask as a temporary (I hope) solution, but there is no activity on the above thread so... Here is the link to the workaround: Use more than one CustomValueAcessor in one Input field

Hope it helps!

0
On

My solution:

1 - Create an auxiliar masked input below the date input, binding it's value to the date input using NgModel. (Don't use matInput directive on the masked input!)

 <input #dateInput matInput formControlName="control"  [matDatepicker]="picker" etc.../>
 <input #maskedInput [(ngModel)]="dateInput.value" mask="00/00/0000" [dropSpecialCharacters]="false" etc.../>

2 - Hide the date input using css:

input:first-child {
  height: 0;
  width: 0;
  overflow: hidden;
}

3 - Relay focus events from the date input to the masked input

<input #dateInput (focus)="maskedInput.focus()" etc...>
<input #maskedInput etc...>

4 - Relay input events from the masked input to the date input

<input #dateInput etc.../>
<input #maskedInput (input)="dispatch(dateInput)" etc.../>

5 - Create a 'dispatch' function in component ts

dispatch(input: HTMLInputElement){
    input.dispatchEvent(new Event('input'));
}

Working demo: https://stackblitz.com/edit/angular-ivy-gyy1i4?file=src%2Fapp%2Fapp.component.ts