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:

Chrome displaying the formatted value of the date

(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:

Firefox showing datestring

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...

64
demandé sur Elise 2013-08-05 19:19:30

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

Violon

la structure actuelle n'est utilisée qu'à des fins de démonstration. Vous feriez mieux de créer votre propre directive, surtout pour:

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

Violon

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.
72
répondu Blackhole 2017-05-23 12:26:26

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.

12
répondu zsong 2013-09-04 21:21:43

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>
3
répondu Debashis Bhattacharyya 2015-10-07 07:29:03

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

1
répondu Giovanni De Rosa 2016-06-05 03:05:12

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>
0
répondu hypery2k 2015-02-04 11:46:20

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")
0
répondu Alejandro Teixeira Muñoz 2015-04-16 22:08:42

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:

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

0
répondu John Rix 2016-02-09 01:20:19