Comment formater une date en utilisant ng-model?

j'ai une entrée définie comme

<input class="datepicker" type="text" ng-model="clientForm.birthDate" />

qui est truqué pour être affiché ailleurs sur la page:

<tr>
    <th>Birth Date</th>
    <td>{{client.birthDate|date:'mediumDate'}}</td>
</tr>

quand la page charge la date de naissance est joliment formatée comme quelque chose comme Dec 22, 2009 . Cependant, quand je regarde à l'intérieur de mon <input> il est montré comme Tue Dec 22 2009 00:00:00 GMT-0800 (Pacific Standard Time) qui je suppose est comment JS rend Date objets comme des cordes.

tout D'abord, comment puis-je dire Angular pour montrer la date en le <input> comme quelque chose comme 12/22/2009 ? Je n'arrive pas à appliquer |filters dans l'attribut ng-model .

Deuxièmement, dès que je modifie la date, même en la conservant dans son format original, mon autre texte (à l'intérieur du <td> ) ne semble plus appliquer le filtre |date ; il change soudainement de formats pour correspondre à celui de la boîte de texte d'entrée. Comment faire pour appliquer le filtre |date à chaque changement de modèle?


questions connexes:

  • Comment faire pour que ma directive ne s'applique qu'à onchange?
  • comment accéder aux arguments dans une directive?
86
demandé sur Community 2013-01-23 11:35:17

9 réponses

utiliser la validation personnalisée des formulaires http://docs.angularjs.org/guide/forms Démo: http://plnkr.co/edit/NzeauIDVHlgeb6qF75hX?p=preview

151910920

151910920

151960920"

angModule.directive('moDateInput', function ($window) {
    return {
        require:'^ngModel',
        restrict:'A',
        link:function (scope, elm, attrs, ctrl) {
            var moment = $window.moment;
            var dateFormat = attrs.moDateInput;
            attrs.$observe('moDateInput', function (newValue) {
                if (dateFormat == newValue || !ctrl.$modelValue) return;
                dateFormat = newValue;
                ctrl.$modelValue = new Date(ctrl.$setViewValue);
            });

            ctrl.$formatters.unshift(function (modelValue) {
                if (!dateFormat || !modelValue) return "";
                var retVal = moment(modelValue).format(dateFormat);
                return retVal;
            });

            ctrl.$parsers.unshift(function (viewValue) {
                var date = moment(viewValue, dateFormat);
                return (date && date.isValid() && date.year() > 1950 ) ? date.toDate() : "";
            });
        }
    };
});
68
répondu SunnyShah 2015-12-02 19:36:12

Voici la directive très pratique angular-datetime . Vous pouvez l'utiliser comme ceci:

<input type="text" datetime="yyyy-MM-dd HH:mm:ss" ng-model="myDate">

il ajoute également le masque à votre entrée et effectue la validation.

32
répondu Sergei Svekolnikov 2015-04-15 10:01:07

j'ai créé une directive simple pour permettre à la norme input[type="date"] de former des éléments pour fonctionner correctement avec AngularJS ~1.2.16.

Regardez ici: https://github.com/betsol/angular-input-date

Et voici la démo: http://jsfiddle.net/F2LcY/1 /

7
répondu Slava Fomin II 2014-04-19 19:00:26

j'utilise jQuery datepicker pour sélectionner la date. Ma directive lit la date et la convertit en format JSON date (en millisecondes) stocké dans ng-model données pendant l'affichage date formatée.et inversez si ng-model ont JSON date (en milliseconde) mon affichage de formatteur dans mon format comme jQuery datepicker.

Code Html:

<input type="text" jqdatepicker  ng-model="course.launchDate" required readonly />

Directive Angulaire:

myModule.directive('jqdatepicker', function ($filter) {
    return {
        restrict: 'A',
        require: 'ngModel',
         link: function (scope, element, attrs, ngModelCtrl) {
            element.datepicker({
                dateFormat: 'dd/mm/yy',
                onSelect: function (date) {   
                    var ar=date.split("/");
                    date=new Date(ar[2]+"-"+ar[1]+"-"+ar[0]);
                    ngModelCtrl.$setViewValue(date.getTime());            
                    scope.$apply();
                }
            });
            ngModelCtrl.$formatters.unshift(function(v) {
            return $filter('date')(v,'dd/MM/yyyy'); 
            });

        }
    };
});
7
répondu Amit Bhandari 2015-10-15 02:36:26

puisque vous avez utilisé datepicker comme classe, je suppose que vous utilisez un jQuery datepicker ou quelque chose de similaire.

il y a une façon de faire ce que vous voulez sans utiliser le moment.js du tout, en utilisant uniquement les directives datepicker et angularjs.

j'ai donné un exemple ici dans ce violon

extraits du violon ici:

  1. Datepicker a un format différent et angularjs format est différent, besoin de trouver la correspondance appropriée de sorte que la date est présélectionnée dans le contrôle et est également peuplé dans le champ d'entrée tandis que le ng-model est lié. Le format ci-dessous est équivalent au format 'mediumDate' D'AngularJS.

    $(element).find(".datepicker")
              .datepicker({
                 dateFormat: 'M d, yy'
              }); 
    
  2. la directive date input doit avoir une variable chaîne de caractères intermédiaire pour représenter la forme humaine lisible de la date.

  3. rafraîchissement à travers différentes sections de la page devrait se produire via des événements, comme $broadcast et $on .

  4. utiliser un filtre pour représenter la date sous une forme lisible par l'homme est également possible dans le modèle ng mais avec une variable de modèle temporaire.

    $scope.dateValString = $filter('date')($scope.dateVal, 'mediumDate');
    
7
répondu Praveenram Balachandar 2015-12-20 09:52:53

j'utilise la directive suivante qui me rend moi et la plupart des utilisateurs très heureux! Il utilise le moment pour l'analyse et le formatage. Elle ressemble un peu à celle de Sunnysha, mentionnée plus haut.

angular.module('app.directives')

.directive('appDatetime', function ($window) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attrs, ngModel) {
            var moment = $window.moment;

            ngModel.$formatters.push(formatter);
            ngModel.$parsers.push(parser);

            element.on('change', function (e) {
                var element = e.target;
                element.value = formatter(ngModel.$modelValue);
            });

            function parser(value) {
                var m = moment(value);
                var valid = m.isValid();
                ngModel.$setValidity('datetime', valid);
                if (valid) return m.valueOf();
                else return value;
            }

            function formatter(value) {
                var m = moment(value);
                var valid = m.isValid();
                if (valid) return m.format("LLLL");
                else return value;

            }

        } //link
    };

}); //appDatetime

dans ma forme je l'utilise comme ceci:

<label>begin: <input type="text" ng-model="doc.begin" app-datetime required /></label>
<label>end: <input type="text" ng-model="doc.end" app-datetime required /></label>

cela liera une estampille temporelle (millisecondes depuis 1970) à doc.begin et doc.end .

6
répondu Elmer 2014-06-18 11:26:01

je préfère que le serveur renvoie la date sans modification, et que javascript fasse le massage de la vue. Mon API retourne "MM/JJ / YYYY hh:mm:ss" depuis SQL Server.

Ressource

angular.module('myApp').factory('myResource',
    function($resource) {
        return $resource('api/myRestEndpoint/', null,
        {
            'GET': { method: 'GET' },
            'QUERY': { method: 'GET', isArray: true },
            'POST': { method: 'POST' },
            'PUT': { method: 'PUT' },
            'DELETE': { method: 'DELETE' }
        });
    }
);

contrôleur

var getHttpJson = function () {
    return myResource.GET().$promise.then(
        function (response) {

            if (response.myDateExample) {
                response.myDateExample = $filter('date')(new Date(response.myDateExample), 'M/d/yyyy');
            };

            $scope.myModel= response;
        },
        function (response) {
            console.log(response.data);
        }
    );
};

madate de Validation de la Directive

angular.module('myApp').directive('myDate',
    function($window) {
        return {
            require: 'ngModel',
            link: function(scope, element, attrs, ngModel) {

                var moment = $window.moment;

                var acceptableFormats = ['M/D/YYYY', 'M-D-YYYY'];

                function isDate(value) {

                    var m = moment(value, acceptableFormats, true);

                    var isValid = m.isValid();

                    //console.log(value);
                    //console.log(isValid);

                    return isValid;

                };

                ngModel.$parsers.push(function(value) {

                    if (!value || value.length === 0) {
                         return value;
                    };

                    if (isDate(value)) {
                        ngModel.$setValidity('myDate', true);
                    } else {
                        ngModel.$setValidity('myDate', false);
                    }

                    return value;

                });

            }
        }
    }
);

HTML

<div class="form-group">
    <label for="myDateExample">My Date Example</label>
    <input id="myDateExample"
           name="myDateExample"
           class="form-control"
           required=""
           my-date
           maxlength="50"
           ng-model="myModel.myDateExample"
           type="text" />
    <div ng-messages="myForm.myDateExample.$error" ng-if="myForm.$submitted || myForm.myDateExample.$touched" class="errors">
        <div ng-messages-include="template/validation/messages.html"></div>
    </div>
</div>

template/validation/messages.html

<div ng-message="required">Required Field</div>
<div ng-message="number">Must be a number</div>
<div ng-message="email">Must be a valid email address</div>
<div ng-message="minlength">The data entered is too short</div>
<div ng-message="maxlength">The data entered is too long</div>
<div ng-message="myDate">Must be a valid date</div>
2
répondu meffect 2015-06-30 17:28:27

en Angular2 + pour toute personne intéressée:

<input type="text" placeholder="My Date" [ngModel]="myDate | date: 'longDate'">

avec le type de filtres dans sonde de données angulaire.

2
répondu Wazza El 2018-01-12 11:41:59

Angularjs ui bootstrap vous pouvez utiliser angularjs ui bootstrap, il fournit la validation de date aussi

<input type="text"  class="form-control" 
datepicker-popup="{{format}}" ng-model="dt" is-open="opened" 
min-date="minDate" max-date="'2015-06-22'"  datepickeroptions="dateOptions"
date-disabled="disabled(date, mode)" ng-required="true"> 





dans controller peut spécifier quel que soit le format que vous voulez afficher la date en tant que datefilter



$portée.formats = ['JJ-MMMM-AAAA', 'AAAA/MM/JJ', 'JJ.MMM.yyyy', 'shortDate'];

1
répondu P.JAYASRI 2015-03-05 13:37:39