1. ホーム
  2. angularjs

[解決済み] シンプルなangularjsの日付入力

2022-02-13 08:06:26

質問

イベントの編集ページがあり、フィールドの1つに日付があります。 ブラウザによっては、プレーンテキストボックスのように動作しますが(IE8)、クロームでは "dd/mm/yyyy" と表示され、クリックすると日付を設定するための追加オプションが表示されます。

しかし、私の問題は、編集ページで、既存の日付が入力されないことです(正しい形式でないためと想像しています)。 MVCコントローラはこのフォーマットでデータを返します "2014-03-08T00:00:00" (基本的なCRUDコントローラアクションを使用しているだけです).

<form name="form" class="form-horizontal">
<div class="control-group" ng-class="{error: form.EventDate.$invalid}">
        <label class="control-label" for="EventDate">Event Date</label>
        <div class="controls">
            <input type="date" ng-model="item.EventDate" id="EventDate">
        </div>
    </div>
<div class="form-actions">
        <button ng-click="save()" class="btn btn-primary">
            {{action}}
        </button>
        <a href="#/" class="btn">Cancel</a>
    </div>
</form>

ディレクティブやウォッチを使うという書き込みを結構見かけますが、複雑そうですね。 モデルデータを正しい形式で表示し、期待通りに動作するようにフォーマットする、比較的簡単な方法があるはずだと思ったのですが。 Chromeが他のブラウザーと異なる体験を与えても気にしません - それは単なる内部ユーザーのウェブサイトです。ただ、レコードを編集するときに日付が事前に入力されないのが気に入らないのです。

解決方法は?

フィールドに初期値を入力したい場合は、以下のようにするとうまくいきます。

//Controller:
$scope.myDate = new Date('2014-03-08T00:00:00');

//HTML:
<input type="date" ng-init="model=(myDate | date:'yyyy-MM-dd')" ng-model="model" />

しかし、私はカスタムの日付フィールドディレクティブを作成することを強くお勧めします。

カスタム入力フィールドディレクティブには、次のような利点があります。

  1. モデルとビューの間の双方向のバインディング。 例えば、入力フィールドに有効な日付を入力すると、自動的にjavascriptの日付がモデルに割り当てられます。そして、モデルとして有効なjavascriptの日付を割り当てると、自動的にテキストフィールドにフォーマットされます。
  2. フォームバリデーションに対応。 無効な日付を入力すると、$error フラグを設定し、ビューバインディングで使用できます (つまり、エラーメッセージを表示します)。 エラーフラグを設定すると form.$valid を false に設定して、条件付きでフォームをサーバーに送信できるようにします。

カスタム日付ディレクティブを実装する際に考慮すべき基本的なことは、3つあります。

  1. 入力されたテキストを解析して、モデル (この場合、javascriptの日付)。
  2. モデルをフォーマットしてテキストフィールドに表示するフォーマッタ。
  3. UIで使用できるオプションのバリデーションフラグの設定 カスタムフォームの検証のため。

Date ディレクティブ。

myApp.directive('dateField', function($filter) {
  return {
      require: 'ngModel',
      link: function(scope, element, attrs, ngModelController) {
           ngModelController.$parsers.push(function(data) {

              //View -> Model
              var date = Date.parseExact(data,'yyyy-MM-dd');

              // if the date field is not a valid date 
              // then set a 'date' error flag by calling $setValidity
              ngModelController.$setValidity('date', date!=null);
              return date == null ? undefined : date;
           });
           ngModelController.$formatters.push(function(data) {
              //Model -> View
              return $filter('date')(data, "yyyy-MM-dd");
           });    
       }
    }
});

注意: このディレクティブは、日付の解析のために 日付.js (外部ライブラリ)を使用します。

CSSです。

.error {
  color:red;
}
.error-border {
  border: solid 2px red;
}

HTMLです。

<form name="myForm">
     <input ng-class="{'error-border': myForm.myDate.$error.date}" type="date"
            name="myDate" ng-model="myDate" date-field />
              <span ng-show="myForm.myDate.$error.date" class="error">
                  Please enter a valid date!!!
              </span>             
         <br /> Raw Date: {{myDate}} 
         <br /> Formatted Nicely: {{ myDate | date:'yyyy, MMMM dd'}}    
         <br /> Is Valid Date? {{ !myForm.myDate.$error.date}}
         <br /> Is Form Valid? {{ myForm.$valid }}
</form>

コントローラーです。

myApp.controller('ctrl', function($scope) {
    $scope.myDate = new Date('2014-03-08T00:00:00');
});

デモJSフィドル 日付.js
デモJSフィドル モーメント.js