ng-modelを使用して日付をフォーマットする方法は?


93

次のように定義された入力があります

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

これは、ページの他の場所に表示されるようになっています。

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

ページが読み込まれると、誕生日はのように適切にフォーマットされますDec 22, 2009。私は私の内部を見るときしかし、<input>次のように示されていますTue Dec 22 2009 00:00:00 GMT-0800 (Pacific Standard Time)、私はJSのレンダリング方法です推測されDateた文字列などのオブジェクトを。

まず、Angularで日付をの<input>ように表示するにはどうすればよい12/22/2009ですか?属性|filters内に適用できないようng-modelです。

次に、日付を編集するとすぐに、元の形式のままでも、(内の<td>)私の他のテキストは|dateフィルターを適用しなくなったように見えます。入力テキストボックスのフォーマットに一致するようにフォーマットを突然変更します。|dateモデルが変更されるたびにフィルターを適用するにはどうすればよいですか?


関連する質問:


私もそれに問題がありましたが、標準のjs Date()関数を使用したより簡単なソリューションが付属し$scope.departDate = new Date(); $scope.departTime = $scope.departDate.toTimeString().slice(0, 5);ました。AngularJSIMOの他のフィルターやトリッキーな回避策は必要ありません。
boldnik 2015年

回答:


71

フォームのカスタム検証を使用するhttp://docs.angularjs.org/guide/formsデモ:http : //plnkr.co/edit/NzeauIDVHlgeb6qF75hX?p=preview

フォーマッターとパーサー、および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() : "";
            });
        }
    };
});

4
フォーマッターとパーサーの小さな例を作りたかったのですが、今日の質問のおかげで、それを行う理由がわかりました。
SunnyShah 2013年

1
@マーク、第二フィドルのナンの問題を修正。;)
サニーシャー2013年

1
2番目のアプローチを削除しました。バギー過ぎました。
SunnyShah 2013年

1
on-changeディレクティブを使用して、さらに改善することができます。stackoverflow.com/questions/14477904/...
SunnyShah

7
@SunnyShah-素晴らしいもの、本当に役立つ、本当にありがとう。私はあなたが持っている理由思っていたvar dateFormat = attrs.moMediumDate;としませvar dateFormat = attrs.moDateInput;moMediumDateは、入力が初期フォーマットが選択されることはありません動的に作成されていない場合、そのいずれかの場所に設定されていないようです。
toxaq 2013

37

これは非常に便利なディレクティブangular-datetimeです。次のように使用できます。

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

また、入力にマスクを追加して検証を実行します。


1
ありがとう、このディレクティブも使用しました。jQuery UI Datepickerで使用する場合は、datetime="<format>"属性値で指定された形式が、DatepickerのdateFormatオプションで指定された形式と一致することを確認する必要があります。
タイラーウォール2015年

1
投票数がわずかしかなく、ここに完璧な解決策があるのはどうしてでしょうか。日付についてはこれで終わりです。今すぐここで解決できます!ありがとう、相棒。
C0ZEN、2016年

2
既存のAngularアプリに簡単に組み込むことができるようにドキュメントが改善されていれば、より多くの人々がこれに賛成票を投じると思います。
Joel Hansen

8

標準のinput[type="date"]フォーム要素をAngularJS〜1.2.16で正しく機能させるための簡単なディレクティブを作成しました。

こちらをご覧くださいhttps : //github.com/betsol/angular-input-date

そしてここにデモがあります:http : //jsfiddle.net/F2LcY/1/


@Lorenzoさん、どういう意味ですか?詳しく説明してもらえますか?
Slava Fomin II 2014

月曜日は、月曜日火曜日のルンマーメールのようにフランス語である
マーリン2014

@Lorenzo私は私が理解できないかわかりません。ディレクティブはローカリゼーションとは関係ありません。おそらく、使用しているフォーマット機能は、ブラウザ/システムからロケール設定を取得しています。あなたが例を提供するなら、私は助けることができます(jsfiddle)。
Slava Fomin II 2014

1
ただクロムをサポートしているので、悪い。
GeminiYellow 2015年

このディレクティブの目的は、すべてのプラットフォームをサポートすることです。問題がある場合は、GitHubリポジトリに問題を作成してみませんか?私は常にすべての問題に対応しています。
Slava Fomin II

7

私はjquery datepickerを使用して日付を選択しています。私のディレクティブは日付を読み取ってjson日付形式(ミリ秒単位)に変換し、フォーマットされた日付ng-modelを表示します。ng-modelがjson日付(ミリ秒単位)を持っている場合は逆に、フォーマッターがjquery datepickerとして私の形式で表示されます。

HTMLコード:

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

角度指令:

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

        }
    };
});

なんてことだ!!どうもありがとうございます!文字通りこのような答えを2日間探していましたが、見つかりませんでした!あなたはロック!
マイケルレントマイスター

素晴らしい。このようなものをしばらく探していました。私のソリューションにはmaterializecssを使用しています。誰かがこれに固執し、この指令を具体化するために変換する必要がある場合は、交換しelement.datepickerてくださいelement.pickadate
IWI

7

あなたはクラスとしてdatepickerを使用してきたので、私はあなたがJquery datepickerまたは類似のものを使用していると想定しています。

純粋にdatepickerとangularjsディレクティブを使用するだけで、moment.jsをまったく使用せずに、意図したことを実行する方法があります。

このフィドルで例を挙げました

ここのフィドルからの抜粋:

  1. Datepickerの形式は異なり、angularjsの形式も異なります。適切な一致を見つける必要があるため、コントロールで日付が事前に選択され、ngモデルがバインドされているときに入力フィールドにも入力されます。以下のフォーマットは'mediumDate'AngularJSのフォーマットと同等です。

    $(element).find(".datepicker")
              .datepicker({
                 dateFormat: 'M d, yy'
              }); 
  2. 日付入力ディレクティブには、人間が読める形式の日付を表すための暫定文字列変数が必要です。

  3. ページのさまざまなセクションにわたる更新は、などのイベントを介して行われる必要が$broadcastあり$onます。

  4. フィルターを使用して人間が読める形式で日付を表すことは、ng-modelでも可能ですが、一時的なモデル変数を使用します。

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

6

私とほとんどのユーザーを非常に満足させる次のディレクティブを使用します!解析とフォーマットにモーメントを使用します。前述のSunnyShahのものと少し似ています。

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

私のフォームでは、次のように使用します。

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

これは、タイムスタンプ(1970年からのミリ秒)をdoc.beginおよびにバインドしdoc.endます。


1
このリンク関数内ngModelでは、への直接の名前付き参照ではなく、コントローラー引数のカスタム識別子であるという事実を見落としがちngModelです。これは、引数に「ctrl」または「controller」という命名規則を使用して、物事をより明確に保ち、​​混乱を避ける場所です。
XML

ありがとう!私はこれを行うための良い方法を一日中探していました。残念ながら、他のほとんどの修正には、angular専用に作成された日付ピッカーへの切り替えが含まれていました。
Josh Mouch、2015

私はあなたと@SunnyShahの両方の答えを試しましたが、彼はうまくいかなかったようです。なぜだかわかりません。
Josh Mouch、2015

3

興味のある方のためのAngular2 +:

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

DatePipe Angular のフィルターのタイプ。


ダン、私は強制的に取り組んできたレガシーAngularJSに行き詰まり、嫌いです!上記を一緒に使ってもらいたいです。
ジョーダン

2

私はサーバーに変更なしで日付を返させ、javascriptにビューマッサージを行わせることを好みます。私のAPIはSQL Serverから「MM / DD / YYYY hh:mm:ss」を返します。

資源

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

コントローラ

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

myDate検証ディレクティブ

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>

1

Angularjs uiブートストラップangularjs uiブートストラップを使用でき、日付の検証も提供します

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



コントローラーでは、日付を表示する任意の形式をdatefilterとして指定できます

$ scope.formats = ['dd-MMMM-yyyy'、 'yyyy / MM / dd'、 'dd.MM.yyyy'、 'shortDate'];


単一の入力フィールドに対してのみディレクティブを実装する必要はありません
P.JAYASRI
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.