Ayla
Ayla

Reputation: 114

Material Datepicker two way binding with ngModel?

I have a stepper process form and on the first step the user is asked to pick a date using the Angular Material design Datepicker component.

When the user goes to the next step I want to bind the value they selected and show it again at the top in an input field (they should be able to change it here as well).

I've tried [(ngModel)] but not sure if I'm using it properly.

<mat-form-field>
  <input [(ngModel)]="date" formControlName="dateFormCtrl" matInput 
      [matDatepicker]="picker" [max]="maxDate" [min]="minDate" 
      placeholder="When is your event?" readonly> 
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle> 
  <mat-datepicker #picker></mat-datepicker> 
  <mat-error>The input is required.</mat-error>
</mat-form-field>

Upvotes: 3

Views: 12674

Answers (3)

Ethan H
Ethan H

Reputation: 11

Thank you @Christopher-Peisert. I had problems getting the DatePicker to bind to the control. I am not using ngModel. I am using Angular FormBuilder, and dynamically adding controls.
When I added [formControlName]="nameVariable" to:

<mat-form-field appearance="fill">
   <mat-label>Choose a date</mat-label>
   <input matInput [matDatepicker]="picker" [formControlName]="control.name" [value]="control.value"/>
   <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle> 
   <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

the angular material datepicker bound to my control. Now, I can populate date value from server, and when changed by user, new value updates my control, and is accessible from myForm.value.

Thank you @Eliseo. I removed [value]="control.value" from <input matInput [matDatepicker]="picker" [formControlName]="control.name" it works well, and is easier for me to understand.

Upvotes: 0

Christopher Peisert
Christopher Peisert

Reputation: 24184

In Angular 4 and 5, it possible to use ngModel in Reactive Forms. However, to future-proof the design, it is better to reference the value of the FormControl directly, assuming that you wish to use reactive forms rather than template-driven forms.

Angular Docs for FormControlName

Support for using the ngModel input property and ngModelChange event with reactive form directives has been deprecated in Angular v6 and will be removed in Angular v7.

Now deprecated:

<form [formGroup]="form">
  <input formControlName="first" [(ngModel)]="value">
</form>

Datepicker Component

import {Component, OnInit} from '@angular/core';
import {FormBuilder, FormControl, FormGroup} from '@angular/forms';

@Component({
  selector: 'datepicker-example',
  templateUrl: 'datepicker-example.html',
  styleUrls: ['datepicker-example.css'],
})
export class DatepickerExample implements OnInit {
  myGroup: FormGroup

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.myGroup = this.fb.group({
      dateFormCtrl: new FormControl(new Date())
    })
  }
}

Datepicker Template

<div [formGroup]="myGroup">
  <mat-form-field>
    <input matInput formControlName="dateFormCtrl" [matDatepicker]="picker"  
      placeholder="When is your event?" readonly>
    <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
    <mat-datepicker #picker></mat-datepicker>
  </mat-form-field>

  <mat-form-field>
    Selected date:
    <input matInput [value]="myGroup.get('dateFormCtrl').value | date">
  </mat-form-field>
</div>

Upvotes: 0

Vinay Kumar
Vinay Kumar

Reputation: 21

Use [formControl]="dateFormCtrl"

Example:

<input [formControl]="dateFormCtrl" matInput [matDatepicker]="picker" [max]="maxDate" [min]="minDate" placeholder="When is your event?" readonly> 

In the .ts file you should have a variable dateFormCtrl.

dateFormCtrl = new FormControl(new Date()); // this will display your date in the picker

Now to access the value anywhere use dateFormCtrl.value.

In your case you can also show by [value]="dateFormCtrl.value" in the input of datepicker.

Upvotes: 0

Related Questions