75

trying to get a form set up but for some reason, the Date input in my html is not binding to the object's date value, despite using [(ngModel)]

html:

<input type='date' #myDate [(ngModel)]='demoUser.date'/><br>

form component:

export class FormComponent {
    demoUser = new User(0, '', '', '', '', new Date(), '', 0, [], []);  
}

User class:

export class User {
    constructor (
        public id: number,
        public email: string,
        public password: string,
        public firstName: string,
        public lastName: string,
        public date: Date,
        public gender: string,
        public weight: number,
        public dietRestrictions: string[],
        public fitnessGoals: string[]
    ){

    }
}

A test output reveals the current "new" Date as the object's value, but the input doesn't update the User object's date value or reflect the value, suggesting neither of the two-way bindings are working. Help would be greatly appreciated.

Namitha Reval
  • 551
  • 1
  • 7
  • 13
MoSheikh
  • 769
  • 1
  • 11
  • 20
  • 1
    Possible duplicate of [Angular2: How to use JavaScript Date Object with NgModel two way binding](http://stackoverflow.com/questions/37055311/angular2-how-to-use-javascript-date-object-with-ngmodel-two-way-binding) – Ankit Singh Jul 04 '16 at 04:46

10 Answers10

97

Angular 2 , 4 and 5 :

the simplest way : plunker

<input type="date" [ngModel] ="dt | date:'yyyy-MM-dd'" (ngModelChange)="dt = $event">
El houcine bougarfaoui
  • 35,805
  • 9
  • 37
  • 37
74

Instead of [(ngModel)] you can use:

// view
<input type="date" #myDate [value]="demoUser.date | date:'yyyy-MM-dd'" (input)="demoUser.date=parseDate($event.target.value)" />

// controller
parseDate(dateString: string): Date {
    if (dateString) {
        return new Date(dateString);
    }
    return null;
}

You can also choose not to use parseDate function. In this case the date will be saved as string format like "2016-10-06" instead of Date type (I haven't tried whether this has negative consequences when manipulating the data or saving to database for example).

Usama nadeem
  • 411
  • 7
  • 15
hakany
  • 7,134
  • 2
  • 19
  • 22
28

In your component

let today: string;

ngOnInit() {
  this.today = new Date().toISOString().split('T')[0];
}

and in your html file

<input name="date" [(ngModel)]="today" type="date" required>
Matiullah Karimi
  • 1,234
  • 1
  • 15
  • 17
13

In .ts :

today: Date;

constructor() {  

    this.today =new Date();
}

.html:

<input type="date"  
       [ngModel]="today | date:'yyyy-MM-dd'"  
       (ngModelChange)="today = $event"    
       name="dt" 
       class="form-control form-control-rounded" #searchDate 
>
jps
  • 20,041
  • 15
  • 75
  • 79
user10121373
  • 131
  • 1
  • 2
8

use DatePipe

> // ts file

import { DatePipe } from '@angular/common';

@Component({
....
providers:[DatePipe]
})

export class FormComponent {

constructor(private datePipe : DatePipe){}

    demoUser = new User(0, '', '', '', '', this.datePipe.transform(new Date(), 'yyyy-MM-dd'), '', 0, [], []);  
}
M Rameez
  • 189
  • 1
  • 3
  • 10
6

Angular 2 completely ignores type=date. If you change type to text you'll see that your input has two-way binding.

<input type='text' #myDate [(ngModel)]='demoUser.date'/><br>

Here is pretty bad advise with better one to follow:

My project originally used jQuery. So, I'm using jQuery datepicker for now, hoping that angular team will fix the original issue. Also it's a better replacement because it has cross-browser support. FYI, input=date doesn't work in Firefox.

Good advise: There are few pretty good Angular2 datepickers:

Andrei Zhytkevich
  • 8,039
  • 2
  • 31
  • 45
  • FYI: input=date works in Firefox 57+, but it does not work in IE or Safari. With IE still holding about 3% of browser usage, it's a bit of a headache still trying to support it at this point. – Grungondola May 18 '18 at 18:56
6

As per HTML5, you can use input type="datetime-local" instead of input type="date".

It will allow the [(ngModel)] directive to read and write value from input control.

Note: If the date string contains 'Z' then to implement above solution, you need to trim the 'Z' character from date.

For more details, please go through this link on mozilla docs.

Shiv
  • 3,069
  • 1
  • 24
  • 17
  • 2
    `input type="date"` still works as well. It is supported in every browser except for IE and Safari. `type="datetime-local"` is a different input type altogether and is also not supported in Firefox: [link](https://caniuse.com/#feat=input-datetime) – Grungondola May 18 '18 at 19:45
0

If you are using a modern browser there's a simple solution.

First, attach a template variable to the input.

<input type="date" #date />

Then pass the variable into your receiving method.

<button (click)="submit(date)"></button>

In your controller just accept the parameter as type HTMLInputElement and use the method valueAsDate on the HTMLInputElement.

submit(date: HTMLInputElement){
    console.log(date.valueAsDate);
}

You can then manipulate the date anyway you would a normal date.

You can also set the value of your <input [value]= "..."> as you would normally.

Personally, as someone trying to stay true to the unidirectional data flow, i try to stay away from two way data binding in my components.

-2

you can use a workaround, like this:

<input type='date' (keyup)="0" #myDate [(ngModel)]='demoUser.date'/><br>

on your component :

 @Input public date: Date,
tecnocrata
  • 901
  • 1
  • 8
  • 19
-3

In Typescript - app.component.ts file

export class AppComponent implements OnInit {
    currentDate = new Date();
}

In HTML Input field

<input id="form21_1" type="text" tabindex="28" title="DATE" [ngModel]="currentDate | date:'MM/dd/yyyy'" />

It will display the current date inside the input field.