SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

Facadeデザインパターンを利用したオブジェクト指向JavaScriptカレンダーの作成

月ごとの画像表示が可能なJavaScript+CSSによるカレンダー

コンストラクタの作成

 次に、テキストエディタで新しいファイルを開き、次のようにカレンダーオブジェクトのコンストラクタを入力します。

// Constructor
function calendar(id, d, p){
   this.id = id;
   this.dateObject = d;
   this.pix = p;
   this.write = writeCalendar;
   this.length = getLength();
   this.month = d.getMonth();
   this.date = d.getDate();
   this.day = d.getDay();
   this.year = d.getFullYear();
   this.getFormattedDate = getFormattedDate;
   // get the first day of the month's day
   d.setDate(1);
   this.firstDay = d.getDay();
   // then reset the date object to the correct date
   d.setDate(this.date);
}

 このコンストラクタには3つのパラメータがあり、それぞれID値(1つのページに複数のカレンダーを配置するために必要)、JavaScriptのDateオブジェクト(カレンダーを任意の日付から開始するために必要)、JavaScriptのImageオブジェクトの配列(必要に応じてプログラムで操作可能)を受け取ります。

 このコンストラクタでは、3つのパラメータをそれぞれ対応するプロパティに割り当てるだけでなく、カレンダーオブジェクトを機能させるための補助的なプロパティとメソッドを追加しています。これらのプロパティはラップされるDateオブジェクトの値を公開し、これらのメソッドはカレンダーの情報を表示するために必要な仕組みを提供します。このようにDateオブジェクトをカレンダーオブジェクト内に隠すことが、Facadeデザインパターンになっています。

メソッドの記述

 このカレンダーには、writeCalendar()getLength()getFormattedDate()という3つの便利なメソッドが含まれています。getFormattedDate()を実装するには、月名と曜日名を格納している2つの便利な配列を使用します。スクリプトファイルに次のコードを追加します。

var days = new Array('Sunday','Monday','Tuesday',
   'Wednesday','Thursday','Friday','Saturday');
var months = new Array('January',
   'February','March','April',
   'May','June','July','August','September',
   'October','November','December');

function getFormattedDate(){
   return days[this.day] + ', ' + months[this.month] +
      ' ' + this.date + ', ' + this.year;
   // return this.month + '/' + this.date + '/' +
      this.year;
   }

 この便利な配列を使用しない場合は、カレンダーオブジェクト自体から書式設定済みの日付を取得します。そのためのコードをgetFormattedDate()メソッド内にコメントとして記述しておきました。こちらの方法を使用する場合でも、便利な配列は削除しないでください。後で必要になります。

 ひと月の日数はさまざまなので、それぞれの月の日数を把握する必要があります。getLength()メソッドは日数の計算を行うので、このメソッドにより、カレンダーのlengthプロパティには現在表示されている月の日数が格納されます。月の日数を覚える方法として英語圏では古くから「Thirty days hath September, April, June and November...」(30日は9月、4月、6月、11月...)という文章が使われていますが、getLength()メソッドでもこれと似たような処理をします。スクリプトに次のgetLength()メソッドを追加します。

function getLength(){
   // thirty days has September...
   switch(this.month){
      case 1:
         if ((this.dateObject.getFullYear()%4==0 &&
           this.dateObject.getFullYear()%100!=0) ||
           this.dateObject.getFullYear()%400==0)
            return 29; // leap year
         else
            return 28;
      case 3:
         return 30;
      case 5:
         return 30;
      case 8:
         return 30;
      case 10:
         return 30
      default:
         return 31;
   }
}

 このgetLength()メソッドは、うるう年についても正確に判断し、それに応じて戻り値を調整します。

 writeCalendar()メソッドは、今回のカレンダーアプリケーションの心臓部です。writeCalendar()メソッドは、Webページにカレンダーを表示するためのHTML生成処理を担当します。基本的にwriteCalendar()メソッドは、カレンダーオブジェクトのプロパティから構成される非常に長い文字列を生成します。難しそうに見えるかもしれませんが、一度書いておけば済む話です。writeCalendar()メソッドのコードを以下に示します。

function writeCalendar(){
   var calString = '<div id="calContainer">';
   // write month and year at top of table
   calString += '<table id="cal' + this.id +
      '" cellspacing="0" width="200"' +
      ' style="border:1px black solid;">';
   // write the image -- comment out to hide images
   calString += '<tr><th colspan="7"><img src="' +
      this.pix[this.month].src + '"/></th></tr>';
   // write the month
   calString += '<tr><th colspan="7" class="month">' +
      months[this.month] + ', ' + this.year +
      '</th></tr>';
   // write a row containing days of the week
   calString += '<tr>';

   for(i=0;i<days.length;i++){
      calString += '<th class="dayHeader">' +
         days[i].substring(0,3) + '</th>';
   }

   // write the body of the calendar
   calString += '<tr>';
   // create 6 rows so the calendar doesn't resize
   for(j=0;j<42;j++){
      var displayNum = (j-this.firstDay+1);
      if(j<this.firstDay){
         // write the leading empty cells
         calString += '<td class="empty"> </td>';
      }else if(displayNum==this.date){
         calString += '<td id="' + this.id +
           'selected" class="date" ' +
           'onClick="javascript:changeDate(this,\'' +
           this.id + '\')">' + displayNum + '</td>';
      }else if(displayNum > this.length()){
         // Empty cells at bottom of calendar
         calString += '<td> </td>';
      }else{
         // the rest of the numbered cells
         calString += '<td id="" class="days" ' +
           'onClick="javascript:changeDate(this,\'' +
           this.id + '\')">' + displayNum + '</td>';
      }
      if(j%7==6){
         calString += '</tr><tr>';
      }
   }
   // close the last number row
   calString += '</tr>';
   // write the nav row
   calString += '<tr>';
   calString += '<td class="nav" ' +
      'style="text-decoration:underline;"' +
      ' onClick="changeMonth(-12,\'' + this.id +
      '\')"><</td>';
   calString += '<td class="nav" ' +
      'onClick="changeMonth(-1,\'' + this.id +
      '\')"><</td>';
   calString += '<td class="month" ' +
      'colspan="3"> </td>';
   calString += '<td class="nav"' +
      ' onClick="changeMonth(1,\'' + this.id +
      '\')">></td>';
   calString += '<td class="nav" ' +
      'style="text-decoration:underline;text-' +
      'align:right;" onClick="changeMonth(12,\'' +
      this.id + '\')">></td>';
   calString += '</tr>';
   calString += '</table>';
   calString += '</div>';
   return calString;
}

 このメソッドでは、さまざまな処理が行われています。最初の数行では、カレンダーのコンテナ部分と表示する画像、さらに年+月のバナーに関するHTMLを生成しています。画像のない単純な日付ピッカーを作成する場合は、画像に関する行をコメントアウトします。

 次に、曜日を表示するために曜日配列をループ処理し、各曜日名の最初の3文字を取得します。その後、カレンダー本体のHTML生成に進み、カレンダーオブジェクトのfirstDayプロパティに基づいて、最初に用意しなければならない空白セルの数を決定します。

 続いて各日付を表すテーブルセルを作成し、現在の日付には専用のCSSスタイルを適用します。最後に、カレンダー下部のナビゲーションバーを作成します。

次のページ
ドキュメントオブジェクトメソッドの記述

この記事は参考になりましたか?

japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Tom Duffy(Tom Duffy)

DevXのJavaScriptライター。コネチカット州ノーウォークのノーウォークコミュニティカレッジ(NCC)の助教授で、Web開発とJavaを専門とする。学内のWebデザインスタジオ「NCC Ventures Lab」のマネージャでもある。電子メールの宛先はこちら

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/1345 2007/06/05 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー