例:簡易なイベントカレンダーを実装する
もっとも、ただカレンダーを表示するだけでは面白くありませんので、あらかじめ用意しておいたスケジュール情報に基づいて、予定がある日にマークを付けてみましょう。また、その日付を選択することで、詳細な予定情報が表示されるようにしてみます。
<uib-datepicker ng-model="current" datepicker-options="options"> </uib-datepicker> 選択された日の予定:{{result}}
angular.module('myApp', [ 'ui.bootstrap' ]) .controller('MyController', ['$scope', '$filter', function($scope, $filter) { $scope.options = { formatDayTitle: "yyyy年MM月", minDate: new Date(), // (1)スタイル関数を指定 customClass: function(data) { var date = data.date, mode = data.mode; // 現在の表示モードが日付の場合にスタイルの判定 if (mode === 'day') { var current = new Date(date); // (2)現在の日付と一致するイベント日付が存在する場合、 // そのclazzプロパティを適用 for (var i = 0; i < $scope.events.length; i++) { var event = $scope.events[i].day; if (current.getMonth() === event.getMonth() && current.getDate() === event.getDate()) { return $scope.events[i].clazz; } } } return ''; } }; // イベント情報をオブジェクト配列で準備 $scope.events = [ { day: new Date(2015, 4, 3), title: 'お休み', clazz: 'holiday' }, ...中略... { day: new Date(2015, 4, 25), title: '給料日', clazz: 'payday' } ]; // (3)日付に紐づいたスケジュール情報を表示 $scope.$watch('current', function(n_value, o_value, scope) { if (!n_value) { return; } var tmp = []; // 現在の日付と一致するイベント日付が存在する場合、 // そのタイトルを変数tmpに追加 for (var i = 0; i < $scope.events.length; i++) { var current = n_value; var event = $scope.events[i].day; if (current.getMonth() === event.getMonth() && current.getDate() === event.getDate()) { tmp.push($scope.events[i].title); } } // (4)変数tmpの内容を「/」で連結してページに反映 $scope.result = tmp.join('/'); }); }]);
.english button span{ background-color: #0ff; border-radius: 30px; } .holiday button span { color: #f00; } .payday button span{ background-color: #0f0; border-radius: 30px; }
まず、カレンダーに特定の条件でマークを付与するには、customClassオプションを利用します。customClassオプションは、カレンダーの各セル(表示モードがdayであれば個々の日付)を描画する際に呼び出され、適用すべきスタイルを決定するための関数を指定します(便宜的に、これをスタイル関数と呼びます(1))。
スタイル関数であることの条件は、以下の通りです[*1]。
- 引数としてdate(描画する日付)、mode(カレンダーの種類)プロパティを持ったオブジェクトを受け取る
- 戻り値は、適用すべきスタイルクラス
この例であれば、現在の表示モード(引数mode)がdayであれば、イベント情報(events)を検索し、現在の日付(引数date)と一致するものがあれば、そのイベント情報に紐づいたclazzプロパティの値をスタイルクラスとして返しています(2)[*2]。
もちろん、対応するスタイルクラスは、あらかじめ.cssファイルの側で準備しておきます(本稿ではevent.css)。
注
[*1]dateDisabledオプションも、基本的にはコールバック関数を介して、表示/非表示を制御します。コールバック関数の引数は、customClass属性と同じです。
[*2]ただし、同日に複数のイベントが紐づいていた場合には、最初のイベントが優先されます。
そして、選択された日付に紐づいたスケジュール情報を表示しているのは、(3)の部分です。選択日付(ng-model属性)の値を$scope.$watchメソッドで監視し、変更があった場合に、選択日付でもってイベント情報(events)を検索します。
検索された結果は、変数tmpに配列として格納されますので、これを連結したものを最後にスコープ変数result(=ページ下部)に反映させています(4)。