首页 文章

Angular.js和HTML5日期输入值 - 如何让Firefox在日期输入中显示可读日期值?

提问于
浏览
64

我有一个HTML5日期输入,我希望默认情况下将其值设置为我的模型中的日期属性的值 . 我对格式化并不是太挑剔,因为Chrome似乎根据我的语言环境决定对我来说,但理想情况下格式将始终是 dd/MM/yyyy .

Fiddle

这是我设置输入的方式:

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

这在Chrome上工作正常,默认情况下我会看到以下内容:

Chrome displaying the formatted value of the date

(我仍然不太明白为什么值必须在 yyyy-MM-dd 中给出,如果Chrome仍然根据我的语言环境对其进行格式化,但这是一个不同的问题 . )

我的问题是Firefox没有显示指定日期's value in the way I' ve . 我认为这与将输入绑定到 date 模型有关,因为我可以在 value 属性中指定几乎任何字符串,默认情况下我仍然会在输入中看到长日期字符串:

Firefox showing datestring

如果我从输入标签中删除 ng-model="date" ,Firefox会很好地显示我给它的任何值 . 我不认为输入绑定的模型实际上对其默认值有任何影响?

我理解日期输入isn 't supported universally, but seeing as it'应该回落在一个简单的文本输入上,我不是't see why its value won'只是 2013-08-05 ,由angular的日期过滤器指定 .

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


NOTE 用户完成编辑后,我当然会执行验证并将每个日期输入值转换为正确的 Date 对象 . 不确定这是否与问题相关,而是将其放在那里以防万一,因为输入格式显然需要保持一致,以便日期转换在所有浏览器中都能正常工作 . 当然有问题,Chrome决定我的输入格式......

7 回答

  • 72

    问题是value is ignored when ng-model is present .

    Firefox目前不支持 type="date" ,会将所有值转换为字符串 . 既然你(正确地)希望 date 是一个真正的 Date 对象而不是一个字符串,我认为最好的选择是创建另一个变量,例如 dateString ,然后链接这两个变量:

    <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);
        });
    }
    

    小提琴

    实际结构仅用于演示目的 . 你最好创建自己的指令,尤其是为了:

    请注意我使用了 yyyy-MM-dd ,因为它是JavaScript Date 对象直接支持的格式 . 如果你想使用另一个,你必须自己make the conversion .


    EDIT

    这是一种制作干净指令的方法:

    myModule.directive(
        'dateInput',
        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);
                    });
                },
            };
    });
    

    小提琴

    这是一个基本指令,仍有很大的改进空间,例如:

    • 允许使用自定义格式而不是 yyyy-MM-dd

    • 检查用户输入的日期是否正确 .

  • 3

    Why the value had to be given in yyyy-MM-dd?

    根据HTML 5的input type = date spec,值必须采用 yyyy-MM-dd 格式,因为它采用RFC3339中指定的有效 full-date 格式

    full-date = date-fullyear "-" date-month "-" date-mday
    

    由于指令输入不支持 date 类型,因此与Angularjs无关 .

    How do I get Firefox to accept my formatted value in the date input?

    FF不支持至少高达版本24.0的 date 类型的输入 . 您可以从here获取此信息 . 因此,对于现在,如果在FF中使用类型为 date 的输入,则文本框将采用您传入的任何值 .

    我的建议是你可以使用Angular-ui's Timepicker并且不要使用HTML5支持日期输入 .

  • 0

    你可以使用它,它工作正常:

    <input type="date" class="form1"  
      value="{{date | date:MM/dd/yyyy}}"
      ng-model="date" 
      name="id" 
      validatedateformat 
      data-date-format="mm/dd/yyyy"
      maxlength="10" 
      id="id" 
      calendar 
      maxdate="todays"
      ng-click="openCalendar('id')">
        <span class="input-group-addon">
          <span class="glyphicon glyphicon-calendar" ng-click="openCalendar('id')"></span>
        </span>
    </input>
    
  • 12

    就我而言,我已经解决了这个问题:

    $scope.MyObject = // get from database or other sources;
    $scope.MyObject.Date = new Date($scope.MyObject.Date);
    

    和输入类型日期是好的

  • 0

    我用过ng-change:

    Date.prototype.addDays = function(days) {
      var dat = new Date(this.valueOf());
      dat.setDate(dat.getDate() + days);
      return dat;
    }
    
    var app = angular.module('myApp', []);
    
    app.controller('DateController', ['$rootScope', '$scope',
      function($rootScope, $scope) {
        function init() {
          $scope.startDate = new Date();
          $scope.endDate = $scope.startDate.addDays(14);
        }
    
    
        function load() {
          alert($scope.startDate);
          alert($scope.endDate);
        }
    
        init();
        // public methods
        $scope.load = load;
        $scope.setStart = function(date) {
          $scope.startDate = date;
        };
        $scope.setEnd = function(date) {
          $scope.endDate = date;
        };
    
      }
    ]);
    
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <div data-ng-controller="DateController">
      <label class="item-input"> <span class="input-label">Start</span>
        <input type="date" data-ng-model="startDate" ng-change="setStart(startDate)" required validatedateformat calendar>
      </label>
      <label class="item-input"> <span class="input-label">End</span>
        <input type="date" data-ng-model="endDate" ng-change="setEnd(endDate)" required validatedateformat calendar>
      </label>
      <button button="button" ng-disabled="planningForm.$invalid" ng-click="load()" class="button button-positive">
        Run
      </button>
    </div <label class="item-input"> <span class="input-label">Start</span>
    <input type="date" data-ng-model="startDate" ng-change="setStart(startDate)" required validatedateformat calendar>
    </label>
    <label class="item-input"> <span class="input-label">End</span>
      <input type="date" data-ng-model="endDate" ng-change="setEnd(endDate)" required validatedateformat calendar>
    </label>
    
  • 1

    检查MEAN.JS的完整功能指令(Angular.js,bootstrap,Express.js和MongoDb)

    基于@Blackhole的回复,我们刚刚完成它与mongodb和express一起使用 .

    它允许您从猫鼬连接器保存和加载日期

    希望能帮助到你!!

    angular.module('myApp')
    .directive(
      'dateInput',
      function(dateFilter) {
        return {
          require: 'ngModel',
          template: '<input type="date" class="form-control"></input>',
          replace: true,
          link: function(scope, elm, attrs, ngModelCtrl) {
            ngModelCtrl.$formatters.unshift(function (modelValue) {
              return dateFilter(modelValue, 'yyyy-MM-dd');
            });
    
            ngModelCtrl.$parsers.push(function(modelValue){
               return angular.toJson(modelValue,true)
              .substring(1,angular.toJson(modelValue).length-1);
            })
    
          }
        };
      });
    

    JADE / HTML:

    div(date-input, ng-model="modelDate")
    
  • 0

    如果使用Angular Material Design,您可以在那里使用datepicker组件,这将适用于Firefox,IE等 .

    https://material.angularjs.org/latest/demo/datepicker

    虽然公平警告 - 个人经验是这方面存在问题,而且目前似乎正在重新工作 . 看这里:

    https://github.com/angular/material/issues/4856

相关问题