2013-08-05 96 views
61

我有一個HTML5日期輸入,我希望它的值默認設置爲我模型中date屬性的值。我不太關心格式化,因爲無論如何,Chrome似乎都會根據我的語言環境來決定我的格式,但理想情況下格式會始終如一dd/MM/yyyyAngular.js和HTML5日期輸入值 - 如何讓Firefox在日期輸入中顯示可讀的日期值?

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沒有按照我指定的方式顯示日期值。我覺得這做的輸入綁定到date模式,因爲我可以指定value屬性幾乎任何字符串,我仍然會默認顯示在輸入長日期字符串:

Firefox showing datestring

如果我從輸入標記中刪除ng-model="date",Firefox會很好地顯示我給它的任何值。我不認爲輸入必然會影響其默認值的模型?

我知道日期輸入不被普遍支持,但是由於它應該回落到簡單的文本輸入上,我不明白爲什麼它的值不會簡單地變成2013-08-05,正如由angular的日期過濾器。

那麼,如何讓Firefox在日期輸入中接受格式化的值?


注意的編輯之後已經由用戶完成的,我當然會進行驗證和每個日期輸入值轉換成適當的Date對象。不確定這是否與問題相關,但爲了防萬一,將其放在那裏,因爲輸入格式顯然需要保持一致,才能使日期轉換在所有瀏覽器中都一樣。當然,有問題的是,Chrome爲我決定輸入格式...

+0

有你在初始化以正確的格式嘗試(如這裏:http://jsfiddle.net/DotDotDot/Vq65z/7/)?它可能是這樣的:'$ scope.date = $ filter('date')(new Date(),'MM/dd/yyyy')' – DotDotDot

+0

@DotDotDot這很好,因爲這種情況下的日期將是一個字符串。不過,我更喜歡日期是一個實際的JavaScript日期對象,因爲我需要以各種方式操作它,而且它也更具語義。但基本上你的建議是我目前的黑客,是的。我爲輸入綁定的模型和它的值使用臨時字符串,並將它轉換爲表單提交的日期。 – Elise

+1

我不同意封閉,因爲它是關於主題的,描述了代碼重現它的問題,並指出了問題所在。 – forforf

回答

72

問題是value is ignored when ng-model is present

目前不支持type="date"的Firefox會將所有值轉換爲字符串。既然你(正確地)想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); 
    }); 
} 

Fiddle

實際結構僅用於演示目的。你會更好創建自己的指令,特別是爲了:

請注意,我使用了yyyy-MM-dd,因爲它是JavaScript Date對象直接支持的格式。如果你想使用另一個,你自己必須make the conversion


編輯

這是一種方法,使一個乾淨的指令:

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

Fiddle

這是一個基本的指令,仍然有很大的空間例如:

  • 允許使用自定義格式,而不是yyyy-MM-dd的,
  • 檢查由用戶輸入的日期是否正確。
+0

謝謝,我開始認爲我自己需要一些中間字符串變量需要替換綁定到我的日期輸入的模型。你說我應該爲此創建指令來隔離字符串變量 - 我是否理解,當輸入的值發生更改時,會更新我的實際'date'模型,而不是將輸入綁定到模型? – Elise

+0

我編輯了我的答案。看一看 :) 。 – Blackhole

+0

很酷,我剛開始使用__ [this](http://www.benlesh.com/2012/12/angular-js-custom-validation-via.html)__作爲粗略指南,看起來像技術差不多一樣! – Elise

12

爲什麼值必須在yyyy-MM-dd中給出?

根據HTML 5的input type = date spec,該值必須在格式yyyy-MM-dd,因爲它需要的它在RFC3339指定爲

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

有效full-date格式沒有什麼做因爲指令輸入不支持date類型,所以使用Angularjs。

如何使Firefox在日期輸入中接受格式化的值?

FF不支持至少達到版本24.0的date輸入類型。你可以從here得到這個信息。所以現在,如果在FF中使用類型爲date的輸入,文本框將採用您傳入的任何值。

我的建議是您可以使用Angular-ui's Timepicker,並且不要使用日期輸入的HTML5支持。

+0

我一定會考慮Angular的timepicker,如果我不能自己破解它,雖然我想知道對定製樣式的支持...... – Elise

3

你可以利用這一點,它工作正常:

<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> 
+0

謝謝。它的幫助 – 2015-03-05 18:11:11

+0

'data-date-format =「mm/dd/yyyy」'幫助我。 – offset

+1

openCalendar基於什麼? – patroqueeet

0

我用NG-變化:

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>

0

檢查是說這個功能齊全的指令.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); 
     }) 

     } 
    }; 
    }); 

玉/ HTML:

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

就我而言,我已經解決了這個辦法:

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

和輸入型日期是確定