Angular 2 data feed inside FormControl input

I have a dynamically generated Angular 2 FormGroup with multiple FormControl input fields. Some entries are Dates, which are retrieved from the server as unix timestamps.

What I would like to do:

  • to be able to translate the unix timestamp into a human readable form when my FormGroup is populated, and also
  • translate a person's date representation into a unix timestamp when the form is submitted.

Part 1 is somewhat simple using:

<input class="form-control" [formControlName]="question.key" [value]="this.form.controls[this.question.key].value | date:'dd/MM/yyyy'"> 

If this.form is a reference to FormGroup and this.question is a custom wrapper class based on the official guide to dynamic forms:

https://angular.io/docs/ts/latest/cookbook/dynamic-form.html

Trying to change the date input this way will not work, because the pipe will constantly try to convert the input value, thereby making the input unusable if you do not throw out the Invalid argument to exclude the 'DatePipe' for the pipe.

To clarify, I fill out my form using FormGroup.patchValue() api and FormGroup.getRawValue() form data using FormGroup.getRawValue() api.

I tried using the Angular 2 date picker, but they made my huge forms pretty slow, so I would like to do this without special date sorters or any jQuery dependent widgets.

Thanks in advance.

+7
angular pipe forms datepicker
source share
1 answer

One way to do this is to create an input component that implements ControlValueAccessor

The bridge between the control and its own element.

A ControlValueAccessor abstracts the write operations of a new value to a DOM element that represents an input control.

See DefaultValueAccessor for more details.

Something like this should do the trick (not verified):

 export const DATE_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MyDateInput), multi: true }; @Component({ template:`<input #input (input)="onChange($event)" (blur)="touchCallback()" type="date" [attr.disabled]="disabled?true:null">` selector:"my-input", styles:[], providers:[DATE_VALUE_ACCESSOR] }) export class MyDateInput implements ControlValueAccessor{ @ViewChild("input") input:ElementRef; disabled=false; changeCallback=(data:any)=>{}; touchCallback=()=>{}; onChange(event){ let timestamp=this.convertToTimestamp(event.target.value); this.changeCallback(timestamp); } convertToTimestamp(formatedDate){ //TODO:implement } convertFromTimestamp(timestamp){ //TODO:implement } writeValue(obj: any){ let formatedDate=this.convertFromTimestamp(obj); this.input.nativeElement.value=formatedDate; } registerOnChange(fn: any){ this.changeCallback=fn; } registerOnTouched(fn: any){ this.touchCallback=fn; } setDisabledState(isDisabled: boolean){ this.disabled=isDisabled; } } 

then you can use it as follows:

 <my-input class="form-control" [formControlName]="question.key"></my-input> 

or

 <my-input [(ngModel)]="myModel"></my-input> 
+8
source share

All Articles