Anguleux.JS et HTML5 valeur d'entrée de date - Comment faire pour que Firefox affiche une valeur de date lisible dans une entrée de date?
j'ai une entrée de date HTML5 et je voudrais que sa valeur soit définie à la valeur de la propriété date dans mon model par défaut. Je ne suis pas trop pointilleux sur le formatage puisque Chrome semble décider que pour moi de toute façon basé sur ma locale, mais idéalement le format serait uniformément dd/MM/yyyy
.
Violon
Voici comment j'ai configuré mon entrée:
<input type="date"
ng-model="date"
value="{{ date | date: 'yyyy-MM-dd' }}" />
ce fonctionne bien sur Chrome, et je vois ce qui suit par défaut:
(Je ne comprends toujours pas pourquoi la valeur devait être donnée dans yyyy-MM-dd
, si Chrome le formate toujours basé sur ma locale, mais c'est une question différente.)
mon problème est avec Firefox ne montrant pas la valeur de la date de la façon dont je l'ai spécifié. Je pense que cela a à voir avec le fait de lier la contribution date
model, parce que je peux spécifier à peu près n'importe quelle chaîne de caractères dans l'attribut value
, et je verrai toujours la longue chaîne de caractères date dans l'entrée par défaut:
si je supprime ng-model="date"
de l'étiquette d'entrée, Firefox affiche bien toute valeur que je lui donne. Je ne pensais pas que le modèle auquel une entrée était liée avait réellement un effet sur sa valeur par défaut?
je comprends la date entrée n'est pas pris en charge universellement, mais vu qu'il est supposé retomber sur une simple entrée de texte, Je ne vois pas pourquoi sa valeur ne sera pas simplement 2013-08-05
, comme spécifié par le filtre de date d'angular.
alors, comment faire pour que Firefox accepte ma valeur formatée dans la date saisie?
NOTE après que les modifications ont été faites par l'utilisateur, je vais bien sûr effectuer la validation et convertir chaque date Valeur d'entrée dans un objet approprié Date
. Je ne sais pas si cela est pertinent à la question, mais le mettre là-bas juste au cas où, parce que les formats d'entrée auraient évidemment besoin d'être cohérent pour la conversion de date pour fonctionner le même dans tous les navigateurs. Problème, bien sûr, avec Chrome qui décide du format d'entrée pour moi...
7 réponses
le problème est que value
est ignoré quand ng-model
est présent .
Firefox , qui ne supporte pas actuellement type="date"
, convertira toutes les valeurs en chaîne. Puisque vous voulez (à juste titre) que date
soit un véritable objet Date
et non une chaîne de caractères, je pense que le meilleur choix est de créer une autre variable, par exemple dateString
, et puis lier les deux 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);
});
}
la structure actuelle n'est utilisée qu'à des fins de démonstration. Vous feriez mieux de créer votre propre directive, surtout pour:
- permettent des formats autres que
yyyy-MM-dd
, - pouvoir utiliser
NgModelController#$formatters
etNgModelController#$parsers
plutôt que l'artificieldateString
variable (voir la documentation à ce sujet).
veuillez noter que j'ai utilisé yyyy-MM-dd
, car c'est un format directement supporté par L'objet JavaScript Date
. Dans le cas où vous voulez utiliser un autre, vous devez faire la conversion vous-même.
modifier
voici un moyen de faire un nettoyage directive:
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);
});
},
};
});
C'est une directive de base, il y a encore beaucoup de place pour l'amélioration, par exemple:
- permettre l'utilisation d'un format personnalisé au lieu de
yyyy-MM-dd
, - vérifiez que la date tapée par l'utilisateur est correcte.
pourquoi la valeur devait-elle être indiquée dans les AAAA-MM-JJ?
selon le type d'entrée = Date spec de HTML 5, la valeur doit être dans le format yyyy-MM-dd
car il prend le format d'un valide full-date
qui est spécifié dans RFC3339 comme
full-date = date-fullyear "-" date-month "-" date-mday
il n'y a rien à voir avec Angularjs puisque la directive input ne support date
type.
Comment faire pour que Firefox accepte ma valeur formatée dans la date saisie?
FF ne supporte pas le type d'entrée date
pour au moins jusqu'à la version 24.0. Vous pouvez obtenir cette information de ici . Donc pour l'instant, si vous utilisez input avec le type date
en FF, la zone de texte prend n'importe quelle valeur que vous passez.
Ma suggestion est que vous pouvez utiliser Angular-ui Timepicker et ne pas utiliser le support HTML5 pour l'entrée de date.
vous pouvez utiliser ceci, cela fonctionne très bien:
<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>
dans mon cas, j'ai résolu cette voie:
$scope.MyObject = // get from database or other sources;
$scope.MyObject.Date = new Date($scope.MyObject.Date);
et de saisie de type date est ok
j'ai utilisé 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>
vérifier cette directive entièrement fonctionnelle pour la moyenne.JS (Angular.js, bootstrap, Express.js et MongoDb)
basé sur la réponse de @Blackhole, nous venons de le finir pour être utilisé avec mongodb et express.
il vous permettra de sauvegarder et de charger des dates à partir d'un connecteur Mangoose
Espère que cela Aide!!
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);
})
}
};
});
The JADE / HTML:
div(date-input, ng-model="modelDate")
si vous utilisez la conception de matériaux angulaires, vous pouvez utiliser le composant datepicker là-bas et cela fonctionnera dans Firefox, C'est-à-dire etc
https://material.angularjs.org/latest/demo/datepicker
bon avertissement cependant - l'expérience personnelle est qu'il y a des problèmes avec cela, et apparemment il est retravaillé à l'heure actuelle. Voir ici: