Issue
I am trying to utilize ControlValueAccessor with Angular Material datepicker. For some reason, its not not working with formControlName and a reactive form. Can someone resolve this? The wrappers are being built for certain styling and attributes. The values are sent to reactive form, etc
https://material.angular.io/components/datepicker/overview
Typescript:
import { Component, OnInit, Input, Output, EventEmitter, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'app-date-picker',
templateUrl: './date-picker.component.html',
styleUrls: ['./date-picker.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DatePickerComponent),
multi: true
}
], host: {
'(change)': 'onChange($event)',
'(blur)': 'onTouch()'
}
})
export class DatePickerComponent implements OnInit {
@Input() Value: Date = new Date();
@Input() PlaceHolder: string;
@Input() Label:string;
@Output() dateValueAction = new EventEmitter();
onChange: any = () => { };
onTouch: any = () => { };
constructor() { }
ngOnInit() {
}
set valueUpdated(val) {
this.Value = val;
this.onChange(val);
this.onTouch(val);
}
writeValue(obj: any): void {
this.Value = obj;
this.valueUpdated = obj;
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouch = fn;
}
dateValueChanged() {
this.valueUpdated = this.Value;
this.dateValueAction.emit(this.Value);
}
}
HTML:
<mat-form-field appearance="outline">
<mat-label>{{Label}}</mat-label>
<input matInput [matDatepicker]="picker" placeholder={{PlaceHolder}} [(value)]="Value" (dateChange)="dateValueChanged()">
<mat-datepicker-toggle matSuffix [for]="picker">
<mat-icon matDatepickerToggleIcon>calendar_today</mat-icon>
</mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
Wanting to implement with formControlName, etc
<app-date-picker formControlName="startDate">
Solution
When implementing ControlValueAccessor you shouldn't use the standard input/output communication mechanism.
The input value is provided by writeValue, notification of changes to the control (output value) is done by calling the callback function provided by registerOnChange.
Please try the following code:
export class DatePickerComponent implements ControlValueAccessor {
private value: Date = new Date();
@Input() placeHolder: string;
@Input() label: string;
private onChange: Function;
private onTouch: Function;
writeValue(obj: Date): void {
this.value = obj;
}
registerOnChange(fn: Function): void {
this.onChange = fn;
}
registerOnTouched(fn: Function): void {
this.onTouch = fn;
}
dateValueChanged(): void {
this.onChange(this.value)
}
}
Also, you specified a class directly in the descriptor for the component decorator. doing so you shouldn't be using forwardRef.
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: DatePickerComponent,
multi: true
}
]
Answered By - Rafi Henig
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.