Hoe een datum opmaken met ng-model?

Ik heb een invoer gedefinieerd als

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

Die is opgetuigd om elders op de pagina te worden weergegeven:

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

Als de pagina wordt geladen, wordt de geboortedatum netjes opgemaakt als Dec 22, 2009. Als ik echter in mijn <input>kijk, wordt het weergegeven als Tue Dec 22 2009 00:00:00 GMT-0800 (Pacific Standard Time), wat volgens mij zo is JS geeft Date-objecten weer als tekenreeksen.

Ten eerste, hoe vertel ik Angular dat de datum in de <input>moet worden weergegeven als bijvoorbeeld 12/22/2009? Ik kan geen |filterstoepassen binnen het ng-modelattribuut.

Ten tweede, zodra ik de datum bewerk, zelfs als ik hem in zijn oorspronkelijke formaat houd, lijkt mijn andere tekst (binnen de <td>) de |datefilter meer; het verandert plotseling de formaten om overeen te komen met die van het invoertekstvak. Hoe zorg ik ervoor dat het filter |dateelke keer dat het model verandert, wordt toegepast?


Verwante vragen:


Antwoord 1, autoriteit 100%

Gebruik aangepaste validatie van formulieren http://docs.angularjs.org/guide/formsDemo: http://plnkr.co/edit/NzeauIDVHlgeb6qF75hX?p=preview

Richtlijn die formaters en parsers gebruikt en MomentJS)

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() : "";
            });
        }
    };
});

Antwoord 2, autoriteit 53%

Hier is een erg handige richtlijn angular-datetime.
Je kunt het als volgt gebruiken:

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

Het voegt ook een masker toe aan uw invoer en voert validatie uit.


Antwoord 3, autoriteit 11%

Ik heb een eenvoudige richtlijn gemaakt om standaard input[type="date"]formulierelementen correct te laten werken met AngularJS ~1.2.16.

Kijk hier:
https://github.com/betsol/angular-input-date

En hier is de demo:
http://jsfiddle.net/F2LcY/1/


Antwoord 4, autoriteit 10%

Ik gebruik jQuery datepicker om een ​​datum te selecteren. Mijn richtlijn lees datum en converteer het naar json-datumformaat (in milliseconden) sla op in ng-modelgegevens terwijl de geformatteerde datum wordt weergegeven. mijn formaat als jQuery datepicker.

Html-code:

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

Hoekrichtlijn:

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

Antwoord 5, autoriteit 10%

Aangezien je datepicker als klasse hebt gebruikt, neem ik aan dat je een JQuery datepicker of iets dergelijks gebruikt.

Er is een manier om te doen wat je van plan bent zonder moment.js te gebruiken, puur met alleen datepicker en angularjs-richtlijnen.

Ik heb hier een voorbeeld gegeven in deze Fiddle

Fragmenten uit de viool hier:

  1. Datepicker heeft een ander formaat en het angularjs-formaat is anders, moet de juiste overeenkomst vinden zodat de datum vooraf is geselecteerd in het besturingselement en ook wordt ingevuld in het invoerveld terwijl het ng-model is gebonden. Het onderstaande formaat is gelijk aan het 'mediumDate'formaat van AngularJS.

    $(element).find(".datepicker")
              .datepicker({
                 dateFormat: 'M d, yy'
              }); 
    
  2. De datuminvoerrichtlijn moet een tussentijdse tekenreeksvariabele hebben om de voor mensen leesbare vorm van datum weer te geven.

  3. Verversen in verschillende secties van de pagina moet gebeuren via evenementen, zoals $broadcasten $on.

  4. Het gebruik van een filter om de datum in menselijk leesbare vorm weer te geven is ook mogelijk in ng-model, maar met een tijdelijke modelvariabele.

    $scope.dateValString = $filter('date')($scope.dateVal, 'mediumDate');
    

Antwoord 6, autoriteit 8%

Ik gebruik de volgende richtlijn waar ik en de meeste gebruikers erg blij mee zijn! Het gebruikt moment voor het ontleden en formatteren. Het lijkt een beetje op die van SunnyShah, eerder genoemd.

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

In mijn formulier gebruik ik het als volgt:

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

Hierdoor wordt een tijdstempel (milliseconden sinds 1970) gekoppeld aan doc.beginen doc.end.


Antwoord 7, autoriteit 4%

In Angular2+ voor iedereen die geïnteresseerd is:

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

met type filters in DatePipeAngular.


Antwoord 8, autoriteit 3%

Ik heb liever dat de server de datum zonder wijziging terugstuurt, en javascript de weergave laat masseren. Mijn API retourneert “MM/DD/YYYY uu:mm:ss” van SQL Server.

Bron

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

Controller

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

mijnDatum Validatierichtlijn

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>

sjabloon/validatie/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>

Antwoord 9

Angularjs ui-bootstrap
je kunt angularjs ui bootstrap gebruiken, het biedt ook datumvalidatie

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

in controller kan specificeren welk formaat u de datum wilt weergeven als datumfilter

$scope.formats = [‘dd-MMMM-yyyy’, ‘yyyy/MM/dd’, ‘dd.MM.yyyy’, ‘shortDate’];

Other episodes