例:簡易なイベントカレンダーを実装する
もっとも、ただカレンダーを表示するだけでは面白くありませんので、あらかじめ用意しておいたスケジュール情報に基づいて、予定がある日にマークを付けてみましょう。また、その日付を選択することで、詳細な予定情報が表示されるようにしてみます。
<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)。
