日付をクリックすると別ページへリンクするカレンダー

清水北山好会のホームページ作成支援ツールを改修した。
今回は、このページの左下にあるような記事ページに飛ぶカレンダーを追加した。カレンダーそのものは今までもいろいろなホームページに付いているので、特に目新しいものではないが、今回はカレンダー用 JavaScript と、山行日のデータを別ファイルにして、それを読み込む形にした。

今まではカレンダー JavaScript ファイル内に、山行日付データを保存していたが、より汎用性を持たせる意味で、登山日データは TXTファイルで別ファイルにしておくことにした。このデータを読み込むのは、『Justified-Gallery』の画像リストを読み込むところでも使っている「csv2Array」関数が使えると思っていたが、共用は思っていた以上に面倒だったので、数行のことだから別に作成することにした。(たぶん後で解決法が分かるかもしれないが・・・・)
山行日の日付けデータは、作成支援ツールで新しい記事を追加す時に、同じ日付の記事がないかを確認する時に、すべての日付フォルダをダウンロードするので、そのデータを流用することにした。

今までのホームページ同様、記事ページ一番下に「前記事へ」と「後記事へ」のリンクも付けた。

 山行日データの TXTファイル(follist.txt)

160901
160731
160601
160322-2
160322
150802-2
150802
150610
   :
   :
   :
				

登山日のデータは、上記のようなテキストファイルである。
頭から西暦年の下2桁、月、日である。登山日の記事ページはサーバーの上記の数字フォルダに登山日毎に保存されている。各会員が登山記事をサーバーにアップする時は、既に他の会員が同じ日付の記事をアップしていないか事前に自動的に日付フォルダをサーチして確認している。もし、既に同じフォルダが存在する場合は枝番を付けたフォルダを作成してそこにアップすることになっている。(これは自動処理)
この時のデータが上記のテキストデータだ。これを利用する。

(A) 山行日データを読み込む部分(calen.js)

var filePath = "../follist.txt";		// index.htmlからの相対Path
var list = new Array();
var data = new XMLHttpRequest();
data.open("GET", filePath, false);		// false:同期
data.send(null);

var LF = String.fromCharCode(10);		// 改行コード毎に1デーダ
var list = data.responseText.split(LF);
list = list.sort();				// 日付リストを昇順にソート
				

記事ページは必ずあるが、地図ページはない場合もある。これはGPSを持参しなかった場合などは、登山軌跡を描けないために地図ページを作成しないことがあるためである。そのために、記事ページと地図ページにそれぞれ別のカレンダーを付けようと思ったが、地図ページはGoogle や 国土地理院のサーバーにアクセスしているためか「location.pathname」でぺーじのURLが取得できなかった。何か良い方法はあると思うが、私の頭では解決できなかった。

と、言うことで今回は地図ページにカレンダーを埋め込むことは諦め、記事ページだけにカレンダーを付けた。そのため下記の行番号 4 と 6 は使っていないが将来のために一応残してある。(いつの日か解決方法が分かるかも知れないから・・・・)

(B) ページのURLからフォルダ名などを取得する部分(calen.js)

var url = location.pathname;
var regexp1 = /\w{3,5}\.html/;			// map.htmlとindex.html
var regexp2 = /\d{6}-?\d?/;			// 160807-2など
var fname   = url.match(regexp1) + "";		// ファイル名取得
var strDate = url.match(regexp2) + "";		// 日付フォルダ名取得
var myYear  = Number(strDate.substr(0,2));	// 年取得(2桁)
var myMonth = Number(strDate.substr(2,2));	// 月取得
var myDay   = Number(strDate.substr(4,2));	// 日取得
myYear += 2000;					// 2桁年を4桁年に直す
				

以下はカレンダー本体部分。もうかなり昔のことになるが、JavaScript の何たるかも分からないときに本を参考に試行錯誤で作ったもので、その後何度か改修している。

(C) カレンダー本体部分(calen.js)

var listlen = list.length;
var pos;
for (var i=0; i<listlen; i++) {
  if (strDate == list[i]) {
    pos = i;
    break;
  }
}

function dispCalendar() {
  var lastDay = new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
  var strWeek = new Array("日","月","火","水","木","金","土");
  var calDate = new Array(38);			// カレンダーの日付スペースは38日分有れば充分
  var myDate  = new Date();			// 日付オブジェクトを生成

  myDate.setYear(myYear);			// 指定年を取得
  myDate.setMonth(myMonth-1);			// 指定月を取得

  if (((myYear % 4 == 0) && (myYear % 100 != 0)) || (myYear % 400 == 0)) lastDay[2]++;	// 閏年の2月を29日にする
  myDate.setDate(1);				// 日付を1日にする
  var offset = myDate.getDay();			// その月の1日の曜日取得(暦の開始曜日=offset)

  var i, j, d, str1, str2;
  var str3 = '<<';
  var str4 = '>>';


  for (i=0; i<=38; i++) calDate[i] = " ";	// カレンダー全セルにスペース設定
  for (i=1; i<=lastDay[myMonth]; i++) calDate[i+offset-1] = i;	// カレンダー日付設定
  calDate[myDay+offset-1] = '<a href="../' + strDate + '/' + fname + '"><b>' + calDate[myDay + offset-1] + '</b></a>';

  if (pos >= 0 && pos < listlen) {
    i = 1;
    while (pos+i < listlen) {			// 同月の山行日後方検索
      str1 = list[pos+i];
      str2 = strDate;
      if (str1.substr(0,4) == str2.substr(0,4)) {
        d = Number(str1.substr(4,2));
        calDate[d+offset-1] = '<a href="../' + str1 + '/' + fname + '"><b>' + calDate[d + offset-1] + '</b></a>';
      } else {
        break;
      }
      i++;
    }
    i = 1;
    while (pos-i >= 0) {			// 同月の山行日前方検索
      str1 = list[pos-i];
      str2 = strDate;
      if (str1.substr(0,4) == str2.substr(0,4)) {
        d = Number(str1.substr(4,2));
        calDate[d+offset-1] = '<a href="../' + str1 + '/' + fname + '"><b>' + calDate[d + offset-1] + '</b></a>';
      } else {
        break;
      }
      i++;
    }
    i = 1;
    while (pos+i < listlen) {		// 後方月の山行日検索
      str1 = list[pos+i];
      str2 = strDate;
      if (str1.substr(0,4) != str2.substr(0,4)) {
        str4 = '<a href="../' + str1 + '/' + fname + '"><b>' + '>>' + '</b></a>';
        break;
      }
      i++;
    }
    i = 1;
    while (pos-i > 0) {			// 前方月の山行日検索
      str1 = list[pos-i];
      str2 = strDate;
      if (str1.substr(0, 4) != str2.substr(0, 4)) {
        str3 = '<a href="../' + str1 + '/' + fname + '"><b>' + '<<' + '</b></a>';
        break;
      }
      i++;
    }
  }
  with (document) {				// カレンダー描画
    write('<table id="javacal"><tr>');
    write('<td align="center" colspan="2">' + str3 + '</td>');
    write('<td height="28" colspan="3">' + myYear + '年' + myMonth + '月</td>');	// 年月書き出し
    write('<td align="center" colspan="2">' + str4 + '</td></tr><tr>');
    for (i=0; i<7; i++) write('<td>',strWeek[i],'</td>');			// 曜日書き出し
    write('</tr>');
    for (i = 0; i < 38; i++) {
      write('<td>'+calDate[i]+'</td>');
      if (i % 7 == 6) write('</tr><tr>');
    }
    write('</tr></table>');
  }
}
				

下記は記事ページの末尾に付けている「前記事へ」「後記事へ」の部分。 calen.js はAからDまでの4個の部分からなっている。

(D)「前記事へ」「後記事へ」の部分(calen.js)

function prevDate() {
  var j = pos - 1;
  if (j > 0 && j < listlen) {
    document.write('<a href="../' + list[j] + '/' + fname + '"><< 前記事(' + list[j].substr(0,2) + '/' + list[j].substr(2,2) + '/' + list[j].substr(4,2) + ')</a>');
  }
}
function nextDate() {
  var j = pos + 1;
  if (j > 0 && j < listlen) {
    document.write('<a href="../' + list[j] + '/' + fname + '">(' + list[j].substr(0,2) + '/' + list[j].substr(2,2) + '/' + list[j].substr(4,2) + ')後記事 >></a>');
  }
}
				

HTML に上記のカレンダーを埋め込むには、埋め込みたい場所に
 <div class="calendar">
    <script>
       dispCalendar();
    </script>
 </div>
を書く。「前記事へ」「後記事へ」も同様にする。
カレンダーの表示はテーブルで描画しているので、CSSで表示を調整する必要がある場合もある。

現在位置: ホームなんでも日記メニュー > このページ