プルダウンメニューに表示されたアーカイブリンクの選択状態を保持する

プルダウンメニューに表示されたアーカイブリンクの選択状態を保持する

Posted at February 2,2005 9:20 AM
Tag:[Customize, MovableType, PulldownMenu, Usability]

selectboxサイドバーのカテゴリーアーカイブリストや月別アーカイブリストをプルダウンメニュー(セレクトボックス)にしている場合、プルダウンメニューから選択したアーカイブリンクの選択状態を保持するカスタマイズです。選択されたアーカイブリンクを強調表示する(モジュール化対応版)の最後に提案ベースで記していたものを動作するようにしました。

具体的な動作は、プルダウンメニュー化された月別アーカイブリストやカテゴリーアーカイブリストから任意のアーカイブリンクを選択すると、自動的に選択したアーカイブページにジャンプし、ジャンプ先にある同じプルダウンメニューに、選択されたアーカイブリンクを表示します(通常のプルダウンメニューは他のページにジャンプすると選択状態が元に戻ってしまいます)。このカスタマイズを行うことでプルダウンメニューの直感的な操作が可能になります。左の図は月別アーカイブリストから「2004年11月」を選択した後、リンク先のページで2004年11月が選択状態になっていることを示しています。
選択状態はプルダウン形式・リスト形式のいずれにも対応します。

以下のカスタマイズはJavascriptを外部ファイルにする場合・しない場合の2パターンで記述しています。外部ファイルにしない場合は1項を、する場合は2項を実施してください。
初めてプルダウンメニューにされる方はプルダウンメニュー用のMTタグを掲載していますのでご利用ください。また3項のスタイルシートも併せて設定してください。

1.JavaScriptを外部ファイルにしない場合のカスタマイズ

1.1 月別アーカイブリストの変更
テンプレートの「日付アーカイブテンプレート」を選択し、サイドメニューの月別アーカイブ("Monthly Archives"というタイトルのタグ)が設定されている直下に青色のタグおよびスクリプトを挿入します。

<script type="text/javascript">
<!--
function selectUrl(sel){
    if(sel.options[sel.selectedIndex].value){
        location.href = sel.options[sel.selectedIndex].value;
    }
}
//-->
</script>
 
<div class="sidetitle">
Monthly Archives
</div>
 
<div class="side" id="monthlylist">
<form>
<select name="select" onChange="selectUrl(this.form.select)">
<MTArchiveList archive_type="Monthly">
<option value="<$MTArchiveLink$>"><$MTArchiveTitle$> [<$MTArchiveCount$>]</option>
</MTArchiveList>
</select> 
</form>
</div>
 
<script type="text/javascript">
<!--
var data ="<$MTArchiveTitle$>";
var year = data.substring(0,4);
var month = data.substring(12,14);
var nodes = document.getElementById('monthlylist').getElementsByTagName("option");
for (var i = 0; i < nodes.length; i++) {
    var selectYear = nodes[i].innerHTML.substring(0,4);
    var selectMonth = nodes[i].innerHTML.substring(5,7);
    if(year == selectYear && month == selectMonth){
        nodes[i].selected = true;
    }
}
//-->
</script>

リストは公開テンプレートを例にしていますがデフォルトテンプレートも大体同じです。緑色部分はデフォルトからセレクトボックスへの変更、および選択時に該当URLにジャンプするためのスクリプトです。既にセレクトボックスが設定済みであれば修正は不要ですので必要に応じて修正してください。また赤色で示す id属性名が他で使用中の場合は、異なる属性名に適宜変更してください。
月別アーカイブをモジュール化(日付アーカイブテンプレートより php または MTInclude タグを用いてインクルード)している場合は、スクリプトをインクルードしている行の直下に設定します。緑色のJavaScriptはどちらに記述しても大丈夫です。
なお、サイドメニューの折りたたみを利用されている方はそちらの id属性名を用いますので、先の

<div class="side" id="monthlylist">

の設定は不要です。ただし現在設定されている id属性名と一致するように、リスト内の赤字部分を適宜修正してください。サイドメニュー折りたたみ用スクリプトが設定されている場合は、上記スクリプトの後方に配置してください。

上記のリストは、図のように先頭から「yyyy年mm月」と表示されているものを前提にカスタマイズしています。先頭に他の文字列を含んでいる場合や年月が「yyyy/mm」等にしている場合は、

var selectYear = nodes[i].innerHTML.substring(0,4);
var selectMonth = nodes[i].innerHTML.substring(5,7);

の赤色部分を修正してください。例えば上の行は「0文字目から4文字目の直前(つまり3文字目)までを取得」という意味です(通常の1文字目はプログラム上「0」と数えます)。
リストをツリー形式にされている場合(例えば該当行のHTMLに月しか表示してない場合)は、先の2行を

var selectYear = nodes[i].value.substring(44,48);
var selectMonth = nodes[i].value.substring(49,51);

として、value属性のURL内にある年月を取得するようにします。赤色部分の値は適宜変更してください。
さらに年月以外のoptionタグが存在する場合は、value属性値(つまりURL)の文字列長をチェックして

for (var i = 0; i < nodes.length; i++) {
    var selectYear = nodes[i].innerHTML.substring(0,4);
    var selectMonth = nodes[i].innerHTML.substring(5,7);
    if(nodes[i].value.length == 61) {
        var selectYear = nodes[i].value.substring(44,48);
        var selectMonth = nodes[i].value.substring(49,51);
        if(year == selectYear && month == selectMonth){
            nodes[i].selected = true;
        }
    }
}

とすれば良いでしょう。

1.2 カテゴリーリストの変更

テンプレートの「カテゴリー・アーカイブテンプレート」を選択し、サイドメニューのカテゴリーリスト("Categories"というタイトルのタグ)の設定されている直下に青色のタグおよびスクリプトを挿入します。リストは公開テンプレートを例にしています。緑色部分の意味は月別アーカイブと同様です。

<script type="text/javascript">
<!--
function selectUrl(sel){
    if(sel.options[sel.selectedIndex].value){
        location.href = sel.options[sel.selectedIndex].value;
    }
}
//-->
</script>
 
<div class="sidetitle">
Categories
</div>
 
<div class="side" id="categorylist">
<form>
<select name="select" onChange="selectUrl(this.form.select)">
<MTCategories>
<option value="<$MTCategoryArchiveLink$>"><$MTCategoryLabel$> [<$MTCategoryCount$>]</option>
</MTCategories>
</select> 
</form>
</div>
 
<script type="text/javascript">
<!--
var data ="<$MTArchiveTitle$>";
var nodes = document.getElementById('categorylist').getElementsByTagName("option");
for (j = 0; j < nodes.length; j++) {
    if(nodes[j].innerHTML.indexOf(data) == 0){
        nodes[j].selected = true;
    }
}
//-->
</script>

赤色で示す id属性名が他で使用中の場合は、異なる属性名に適宜変更してください。
カテゴリー・アーカイブをモジュール化(カテゴリー・アーカイブテンプレートより php または MTInclude タグを用いてインクルード)している場合は、スクリプトをインクルードしている行の直下に設定します。緑色のJavaScriptはどちらに記述しても大丈夫です。
なお、サイドメニューの折りたたみを利用されている方はそちらの id属性名を用いますので、先の

<div class="side" id="categorylist">

の設定は不要です。ただし現在設定されている id属性名と一致するように、リスト内の赤字部分を適宜修正してください。サイドメニュー折りたたみ用スクリプトが設定されている場合は、上記スクリプトの後方に配置してください。
今回サブカテゴリー表示を意識したカスタマイズには対応していませんので予めご了承ください。

1.3 メインページの変更
メインページには月別アーカイブリストやカテゴリーリストに追加したものからJavaScript(青字部分)を除いたものを設定します。また空要素をメニュー先頭に表示する場合は茶色で示したタグを追加してください。青字部分が含まれていると再構築時にエラーになりますのでご注意ください。

月別アーカイブリスト

<script type="text/javascript">
<!--
function selectUrl(sel){
    if(sel.options[sel.selectedIndex].value){
        location.href = sel.options[sel.selectedIndex].value;
    }
}
//-->
</script>
 
<div class="sidetitle">
Monthly Archives
</div>
 
<div class="side" id="monthlylist">
<form>
<select name="select" onChange="selectUrl(this.form.select)">
<option value="">選択してください</option>
<MTArchiveList archive_type="Monthly">
<option value="<$MTArchiveLink$>"><$MTArchiveTitle$> [<$MTArchiveCount$>]</option>
</MTArchiveList>
</select> 
</form>
</div>

カテゴリーリスト

<script type="text/javascript">
<!--
function selectUrl(sel){
    if(sel.options[sel.selectedIndex].value){
        location.href = sel.options[sel.selectedIndex].value;
    }
}
//-->
</script>
 
<div class="sidetitle">
Categories
</div>
 
<div class="side" id="categorylist">
<form>
<select name="select" onChange="selectUrl(this.form.select)">
<option value="">選択してください</option>
<MTCategories>
<option value="<$MTCategoryArchiveLink$>"><$MTCategoryLabel$> [<$MTCategoryCount$>]</option>
</MTCategories>
</select> 
</form>
</div>

2.JavaScriptを外部ファイルにする場合のカスタマイズ

2.1 外部ファイルの設定
下記のスクリプトを「selectbox.js」というファイル名で保存し、ローカル・サイト・パスに配置(またはアップロード)してください。ファイルはブログで用いている文字コード(UTF-8等)で保存してください。
外部ファイルは日別アーカイブ/カテゴリー・アーカイブ共通に使用します。

selectbox.js

function selectUrl(sel){
    if(sel.options[sel.selectedIndex].value){
        location.href = sel.options[sel.selectedIndex].value;
    }
}
 
function addSelectForMonthly(data){
    var year = data.substring(0,4);
    var month = data.substring(12,14);
    var nodes = document.getElementById('monthlylist').getElementsByTagName("option");
    for (var i = 0; i < nodes.length; i++) {
        var selectYear = nodes[i].innerHTML.substring(0,4);
        var selectMonth = nodes[i].innerHTML.substring(5,7);
        if(year == selectYear && month == selectMonth){
            nodes[i].selected = true;
        }
    }
}
 
function addSelectForCategory(data){
    var nodes = document.getElementById('categorylist').getElementsByTagName("option");
    for (var i = 0; i < nodes.length; i++) {
        if(nodes[i].innerHTML.indexOf(data) == 0){
            nodes[i].selected = true;
        }
    }
}

2.2 テンプレートの設定(1)
日別アーカイブテンプレート/カテゴリー・アーカイブテンプレートの<head>~</head>部分に下記のタグを設定します。

<script type="text/javascript" src="<$MTBlogURL$>selectbox.js"></script>

この設定で実行し、JavaScriptファイルが正常に取得できなかった場合は <$MTBlogURL$> の部分を適宜変更してみてください。

2.3 テンプレートの設定(2)
日別アーカイブテンプレートの月別アーカイブリストおよび、カテゴリー・アーカイブテンプレートのカテゴリーリストに下記の青色部分を追加します。

日付アーカイブテンプレート


<div class="sidetitle">
Monthly Archives
</div>
 
<div class="side" id="monthlylist">
<form>
<select name="select" onChange="selectUrl(this.form.select)">
<MTArchiveList archive_type="Monthly">
<option value="<$MTArchiveLink$>"><$MTArchiveTitle$> [<$MTArchiveCount$>]</option>
</MTArchiveList>
</select> 
</form>
</div>
 
<script type="text/javascript">
<!--
addSelectForMonthly("<$MTArchiveTitle$>");
//-->
</script>

カテゴリー・アーカイブテンプレート

<div class="sidetitle">
Categories
</div>
 
<div class="side" id="categorylist">
<form>
<select name="select" onChange="selectUrl(this.form.select)">
<MTCategories>
<option value="<$MTCategoryArchiveLink$>"><$MTCategoryLabel$> [<$MTCategoryCount$>]</option>
</MTCategories>
</select> 
</form>
</div>
 
<script type="text/javascript">
<!--
addSelectForCategory("<$MTArchiveTitle$>");
//-->
</script>

緑色部分はデフォルトからセレクトボックスへの変更箇所を示しています。既にセレクトボックスが設定済みであれば修正は不要ですので必要に応じて修正してください。また上記の id属性名を他で使用中の場合は青色部分、および select.js の赤色部分を異なる属性名に変更してください。

2.4 メインページの変更
メインページには月別アーカイブリストやカテゴリーリストに追加したものからJavaScript(青字部分)を除いたものを設定します。また空要素をメニュー先頭に表示する場合は茶色で示したタグを追加してください。青字部分が含まれていると再構築時にエラーになりますのでご注意ください。

月別アーカイブリスト


<div class="sidetitle">
Monthly Archives
</div>
 
<div class="side" id="monthlylist">
<form>
<select name="select" onChange="selectUrl(this.form.select)">
<option value="">選択してください</option>
<MTArchiveList archive_type="Monthly">
<option value="<$MTArchiveLink$>"><$MTArchiveTitle$> [<$MTArchiveCount$>]</option>
</MTArchiveList>
</select> 
</form>
</div>

カテゴリーリスト

<div class="sidetitle">
Categories
</div>
 
<div class="side" id="categorylist">
<form>
<select name="select" onChange="selectUrl(this.form.select)">
<option value="">選択してください</option>
<MTCategories>
<option value="<$MTCategoryArchiveLink$>"><$MTCategoryLabel$> [<$MTCategoryCount$>]</option>
</MTCategories>
</select> 
</form>
</div>

3.スタイルシートの設定
スタイルシートの .side が定義されている下に追加します。

.side select {
    font-family: Verdana, Arial, sans-serif;
    color:#666666;
    background: ffffff;
    font-size:9px;
}

内容はデザインに応じて適宜変更してください。なお background を設定しない場合、Netscape7.1 ではセレクトボックスの背景色が暗くなりましたのでご注意ください。

以上です。今回のカスタマイズについては現在のところ

OS:Windows2000 SP4
ブラウザ:IE6.0/Netscape7.1/Sleipnir1.66/Firefox1.0/Opera7.23

で動作の正常性を確認しております。なお、前回のサンプルでは selected 属性の設定を

nodes[i].setAttribute("selected","selected");

としておりましたが、Mozilla系のブラウザで正常に動作しないことが判明したため、

nodes[i].selected = true;

に変更致しました。
この場をお借りしてお詫びと訂正に代えさせていただきます。

2005.03.04 追記
メインページの設定について追加しました。

2006.04.04 追記
リストから language 属性を削除しました(HTML4.01/XHTMLで非推奨あるいは廃止されているため)。

関連記事
zenback
人気エントリー
トラックバックURL


トラックバック

月別書庫をプルダウン式化 from nijimama-room's blog
左のサイドバーにある「Monthly Archives」(過去に書いたこのブログの記事を、月毎に仕舞ってある書庫。と、言う説明で合ってるのか…?)が、あま... [続きを読む]

Tracked on September 11, 2006 3:27 PM
コメント

初めまして。テンプレートを使わせていただいております。
どこでご報告をすればいいのかわからなかったので、こちらにコメントをさせていただきました。
これから、ますますのご活躍を期待しております!
よろしくお願い致します。

[1] Posted by どんぐりころころ : February 2, 2005 3:07 PM

>どんぐりころころさん
はじめまして。
テンプレートご利用&ご連絡ありがとうございます!
小粋なUserListもご利用くださりありがとうございます。
先程登録させて頂きましたので反映されていると思います。

それでは今後ともどうぞよろしくお願い致します。

[2] Posted by yujiro : February 2, 2005 5:32 PM

大変完成度の高いテンプレートを公開していただいてありがとうございます。その他のカスタマイズに関しても参考にさせていただいております。

今回、月別アーカイブリストのプルダウン化をおこなおうと思い、早速上記のカスタマイズをおこなってみました。

「カテゴリー・アーカイブ」、「個別エントリーアーカイブ」、「日付アーカイブ」のテンプレートについては、問題なく変更できたのですが、「メインページ」のテンプレートで同様に変更すると、再構築時に以下のようになエラーが出てしまいました。

テンプレート メインページ の再構築に失敗しました: Error in tag: タグ がコンテナ・タグの外側で使われています。

このエラーの原因がわかりません。この点で何か注意すること、私が見落としていること等ありましたら、ご指摘お願いします。

[3] Posted by sin : March 4, 2005 1:43 PM

>sinさん
こんにちは。
ご利用ありがとうございます。

ご質問の件ですが、メインページの設定についての内容が全く抜けておりました。すいません。
ということで本文に設定方法を追加しましたので、そちらを参照頂けますでしょうか。不具合等ございましたらお手数ですが再度ご連絡ください。
ちなみにエラーになる理由は、選択されたページ情報となる

<$MTArchiveTitle$>

をJavaScriptで使っているのですが、このタグはアーカイブページまたは

<MTArchiveList>?</MTArchiveList>

で括られていないと再構築時にエラーとなります。

以上です。
それではどうぞよろしくお願い致します。

[4] Posted by yujiro : March 4, 2005 3:48 PM

すばやい対応、ありがとうございます。
追加分を試したところ、見事に解決いたしました。

ありがとうございました。

[5] Posted by sin : March 4, 2005 4:05 PM

>sinさん
こんばんは。
いえいえ、こちらこそ。
おかげさまで良い記事になりました。

[6] Posted by yujiro : March 5, 2005 1:59 AM

yujiro様。こんにちは。
テンプレートを使わせて頂いております、にじままと申します。

こちらの記事を参考に、月別アーカイブのプルダウンのカスタマイズをしました。他にもこちらの記事を参考に、ブログのカスタマイズをさせて頂いて、何時もお世話になっています。有難うございます。

今回のカスタマイズの事は、自分のブログで記事にしたので、図々しくも、こちら様にトラバを送らせて頂きました。

ところで、このプルダウンのボックスの枠やボタンのデザインをスタイルシートの記述で変える事は出来るのでしょうか?
もしお時間が御座いましたら教えて頂けると大変嬉しいです。宜しくお願いいたします。

[7] Posted by にじまま : September 11, 2006 4:12 PM

>にじままさん
こんばんは。
カスタマイズご利用&ご連絡ありがとうございます。
ご質問の件ですが、調べてみたところ、select 要素のボックス枠やボタンに対してスタイルは適用できないようです。
それではよろしくお願い致します。

[8] Posted by yujiro : September 11, 2006 10:58 PM
コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)