Elise Elise - 4 months ago 24x
AngularJS Question

Angular.js and HTML5 date input value -- how to get Firefox to show a readable date value in a date input?

I have an HTML5 date input and I would like its value to be set to the value of the date property in my model by default. I'm not too fussy about formatting since Chrome seems to decide that for me anyway based on my locale, but ideally the format would be consistently



This is how I set up my input:

<input type="date"
value="{{ date | date: 'yyyy-MM-dd' }}" />

This works fine on Chrome, and I see the following by default:

Chrome displaying the formatted value of the date

(I still don't quite understand why the value had to be given in
, if Chrome still formats it based on my locale, but that's a different question.)

My issue is with Firefox not showing the date's value in the way I've specified. I think this has to do with binding the input to the
model, because I can specify pretty much any string in the
attribute, and I will still see the long date string in the input by default:

Firefox showing datestring

If I remove
from the input tag, Firefox nicely displays any value I give it. I didn't think the model that an input was bound to actually had any effect on its default value?

I understand the date input isn't supported universally, but seeing as it's supposed to fall back on a simple text input, I don't see why its value won't simply be
, as specified by angular's date filter.

So, how do I get Firefox to accept my formatted value in the date input?

NOTE After the edits have been done by the user, I will of course perform validation and convert each date input value into a proper
object. Not sure if this is relevant to the question, but putting it out there just in case, because the input formats would obviously need to be consistent for the date conversion to work the same in all browsers. Problematic, of course, with Chrome deciding the input format for me...


The problem is that value is ignored when ng-model is present.

Firefox, which doesn't currently support type="date", will convert all the values to string. Since you (rightly) want date to be a real Date object and not a string, I think the best choice is to create another variable, for instance dateString, and then link the two variables:

<input type="date" ng-model="dateString" />
function MainCtrl($scope, dateFilter) {
    $scope.date = new Date();

    $scope.$watch('date', function (date)
        $scope.dateString = dateFilter(date, 'yyyy-MM-dd');

    $scope.$watch('dateString', function (dateString)
        $scope.date = new Date(dateString);


The actual structure is for demonstration purposes only. You'd be better off creating your own directive, especially in order to:

Please notice that I've used yyyy-MM-dd, because it's a format directly supported by the JavaScript Date object. In case you want to use another one, you must make the conversion yourself.


Here is a way to make a clean directive:

    function(dateFilter) {
        return {
            require: 'ngModel',
            template: '<input type="date"></input>',
            replace: true,
            link: function(scope, elm, attrs, ngModelCtrl) {
                ngModelCtrl.$formatters.unshift(function (modelValue) {
                    return dateFilter(modelValue, 'yyyy-MM-dd');

                ngModelCtrl.$parsers.unshift(function(viewValue) {
                    return new Date(viewValue);


That's a basic directive, there's still a lot of room for improvement, for example:

  • allow the use of a custom format instead of yyyy-MM-dd,
  • check that the date typed by the user is correct.