HTML5の日付入力があり、その値をデフォルトでモデルの日付プロパティの値に設定したいのですが。 Chromeはロケールに基づいてとにかくそれを決定するように思えるので、書式設定にはあまりこだわりませんが、理想的には一貫してdd/MM/yyyy
になります。
これは私が入力を設定する方法です:
<input type="date"
ng-model="date"
value="{{ date | date: 'yyyy-MM-dd' }}" />
これはChromeで正常に機能し、デフォルトでは次のように表示されます。
(Chromeがまだロケールに基づいてフォーマットする場合、yyyy-MM-dd
で値を指定する必要がある理由はまだよくわかりませんが、それは別の質問です。)
私の問題は、Firefoxが指定した方法で日付の値を表示しないことです。これは、入力をdate
モデルにバインドすることに関係していると思います。これは、value
属性にほとんどすべての文字列を指定でき、デフォルトでは入力に長い日付文字列が表示されるためです。
Inputタグからng-model="date"
を削除すると、Firefoxは指定した値を適切に表示します。入力がバインドされるモデルが実際にデフォルト値に影響を与えるとは思いませんでしたか?
私は日付入力が普遍的にサポートされていないことを理解していますが、単純なテキスト入力にフォールバックするはずなので、その値が単に角度の日付フィルターで指定された2013-08-05
にならない理由がわかりません。
では、Firefoxに日付入力で書式設定された値を受け入れるにはどうすればよいですか?
NOTE編集がユーザーによって行われた後、もちろん検証を実行し、各日付入力値を適切なDate
オブジェクトに変換します。これが質問に関連するかどうかはわかりませんが、万が一の場合に備えて、すべてのブラウザーで日付変換が同じように機能するためには入力形式が一貫している必要があるためです。もちろん、Chromeが入力形式を決定していて問題があります...
問題は、 ng-model
が存在する場合、value
は無視される です。
現在type="date"
をサポートしていないFirefoxは、すべての値を文字列に変換します。あなたは(当然)date
を文字列ではなく実際のDate
オブジェクトにしたいので、別の変数、たとえばdateString
を作成してから2つをリンクすることが最善の選択だと思います変数:
<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
以外の形式を許可する、dateString
変数ではなく NgModelController#$formatters
および NgModelController#$parsers
を使用できるようにします(このテーマの documentation を参照)。JavaScript Date
オブジェクトで直接サポートされている形式であるため、yyyy-MM-dd
を使用していることに注意してください。別のものを使用する場合は、 変換を行う 自分で行う必要があります。
編集
クリーンディレクティブを作成する方法を次に示します。
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
の代わりにカスタム形式の使用を許可します。これを使用できますが、うまく機能します:
<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>
私の場合、この方法で解決しました。
$scope.MyObject = // get from database or other sources;
$scope.MyObject.Date = new Date($scope.MyObject.Date);
入力タイプの日付は大丈夫です
私は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>
MEAN.JS(Angular.js、bootstrap、Express.js、MongoDb)のこの完全に機能するディレクティブを確認してください
@Blackholeの応答に基づいて、mongodbおよびexpressで使用できるように仕上げました。
Mongooseコネクタから日付を保存およびロードできます
それが役に立てば幸い!!
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")
Angular Material Designを使用している場合は、そこでdatepickerコンポーネントを使用できます。これは、Firefox、IEなどで機能します。
https://material.angularjs.org/latest/demo/datepicker
公正な警告-個人的な経験では、これには問題があるということであり、現在は見直されています。こちらをご覧ください: