はじめに
ある日、私は買い物をしていて、かなり多くの小売店がそれぞれに趣向を凝らした画像入りのカレンダーを配っていることに気が付きました。そこでふと思ったのは、表示される画像を月ごとに制御できるWebベースのカレンダーを作成したら面白いだろうなということです。さらに、このカレンダーを画像なしでも表示できるようにして、日付ピッカーコンポーネントの役割も果たせるようにしたらどうかと考えました。
Facadeデザインパターン
デザインパターンはおもしろい概念です。通常、デザインパターンとは、プログラミング言語で何かを行う一般的な(通常は効率的な)方法を表します。ニュースフィードの統合に欠かせないModel-View-Controllerデザインパターンについては、既に別の記事で取り上げました。デザインパターンは言語に関係なく適用可能です。おそらく皆さんも、これまで知らず知らずのうちにデザインパターンを使用しているのではないかと思います。
ファサード(Facade)とは、仰々しく飾り立てられた正面の外観――つまり「表の顔」――を指す建築用語で、その裏側にある魅力のない構造および機能を隠蔽する方法です。例えば建築家は、本体はれんが造りの建物なのに、通りに面した側には大理石のファサードを追加したりします。同様に、Facadeデザインパターンは、開発者が複雑なオブジェクトの周囲にラッパー(つまり表の顔)を作成するときに使用する概念です。このようなラッパーは、オブジェクトのメソッドとプロパティを公開しますが、他のほとんどの部分は隠蔽します。一般的には、Facadeパターンを適用することでオブジェクトを扱いやすくし、特定の目的に適した「表の顔」を用意します。
本稿で紹介するカレンダープロジェクトでは、まさにこのような処理を行います。カレンダーを作成するには、Facadeデザインパターンを使用して、組み込みJavaScriptのDateオブジェクトの周囲にラッパーを作成します。このラッパーは、カレンダーの作成に必要なDateオブジェクトのプロパティを公開します。ただ注意してほしいのは、今回のプロジェクトのラッパーはDateオブジェクトの機能を実際に隠蔽しているわけではなく、ただアクセスしにくくしているだけです。
本稿の課題
JavaScriptベースのカレンダーを効率的かつ柔軟な方法で作成する。
解決策
Facadeデザインパターンを使用してJavaScriptのDateオブジェクトの周囲にラッパーを作成し、さらにオブジェクト指向のJavaScriptのトリックを使用する。
CSSファイルの作成
まず、カレンダー上部に表示される年+月のバナーと、カレンダー下部のナビゲーションバーのためのCSSルールが必要です。カレンダーには、「現在の日付」と「他のすべての日付」という2種類の日付が含まれます。「現在の日付」を「他のすべての日付」とは別の方法で表示するために、これらについても別々のCSSルールを作成する必要があります。また、バナー直下に表示される曜日を書式設定するためのCSSルールも必要です。図1は、完成済みのカレンダーの実行中のスクリーンショットです。ユーザーはカレンダーの下部にある矢印リンクを使用して、月または年を切り替えることができます。
任意のテキストエディタを開いて、次のような一連のクラスを作成します。このファイルに「calendar.css」という名前を付けて保存します。
.month, .nav{ background-color: navy; color: white; font: 10pt sans-serif; } .nav{ cursor: pointer; cursor: hand; } .dayHeader{ color: black; font: 10pt sans-serif; border-bottom: 1px black solid; font-weight: bold; } .empty{ background-color: white; border-bottom: 1px black solid; } .days{ color: black; background-color: rgb(235,235,235);; font: 10pt sans-serif; border-bottom: 1px black solid; border-left: 1px black solid; border-right: 1px black solid; cursor: pointer; cursor: hand; } .date{ color: maroon; font: 10pt sans-serif; font-weight: bold; border-bottom: 1px black solid; border-left: 1px black solid; border-right: 1px black solid; cursor: pointer; cursor: hand; }