フォームの入力項目ごとのヘルプコンテンツを動的に表示・非表示する
Jenkinsで、ジョブの作成や設定などで、画面の右側にあるクエスチョンマークのついたアイコンをクリックすると、ヘルプが表示される例のアレ。
私的にすごく気に入っていて(たかが一つの項目の説明を知りたいだけなのに、いちいちPDFやWordのユーザーズガイドを見るなんて面倒だし)、今作っているアプリでも同じようなことをしたいと思った。
そんなわけで、より簡単な形で、既存のHTMLに組み込めるようなものを書いてみた。
form.html
まず入力フォーム。ここで<span>タグで囲まれた[?]をクリックすることで、ヘルプコンテンツを挿入されるようにしたいというもの。
入力フォーム用のHTMLでは、以下のように<table>を使ってフォームを表示させているとする。
この例では、NameとPasswordの2つのテキストフィールドがある。
<table class="form"> <tr> <td>Name <span id="help-name" class="help">[?]</span></td> <td><input type="text" id="name" /></td> </tr> <tr> <td>Password <span id="help-password" class="help">[?]</span></td> <td><input type="password" id="password" /></td> </tr> </table>
「Name」や「Password」の右にある[?]をクリックすると、その下に1行新しく追加して、該当項目に対するヘルプコンテンツが表示されるようにする。
_help.html
挿入するヘルプコンテンツは、以下のようなHTMLファイルを別に用意*1。
form.html中でNameの右の[?]をクリックすると「hoge」、Passwordの右の[?]をクリックすると「fuga」というヘルプコンテンツが挿入されるようにしたい。
<html> <head> <title>Example</title> </head> <body> <p id="help-name"> hoge </p> <p id="help-password"> fuga </p> <body> </html>
help.js
ここまでが準備。で、肝になるのがこのJavascript。
form.html側で、以下のJavascriptを読み込んでおくようにする(要JQuery)。
$(document).ready(function() { $(".help").unbind("click").bind("click", function() { var id = $(this).attr("id"); var helpContent = $("#_" + id); if (helpContent[0]) { helpContent.toggle(); } else { $(this).parent().parent().after("<tr><td colspan='2'><div id='_" + id +"'></div></td></tr>"); helpContent.load("_help.html #" + id); } }); });
jQuery#after()を使ってヘルプコンテンツを表示するための要素を挿入して、その要素に対してjQuery#load()を使って別HTML(_help.html)を読み込む。で、一度挿入された後は、jQuery#toggle()を使って表示・非表示を切り替えるだけ。
jQuery#after()でコンテンツを挿入するための位置を決めないとならないけど、テーブルの位置関係を暗黙の前提条件にして、parent().parent()という風に決め打ち。この辺りはもうちょっと汎用的にしたいけど。
挿入されるヘルプコンテンツは別に文字だけでなく、画像や任意のブロック要素でOK。一番外側の要素にIDを振っておけばよい。
前提条件
- フォーム用のテーブルが、項目名を1列目、入力フォームを2列目においた2列のテーブルになっている。
- ヘルプ用のspanのIDと、ヘルプ用HTML側のIDを対応づけておく。
CSSで、helpクラス(.help)に対して、cursor:pointer;を定義したり、背景画像としてヘルプ用のアイコンを表示する(background: url("help.png") no-repeat;)ようにしておくと、よりそれっぽくなると思う。
jQuery#after()を呼んでる行を工夫すると、下の行への挿入だけでなく、ポップアップとかにも応用できそう。
大したことではないけど、思ったよりもすっきりとやりたいことができた。
*1:ヘルプコンテンツはひとつのHTMLにまとめることにした。ファイルが増えるのも管理が大変なので。
このHTML自体を直接見ることはないけど、段落(p)よりは定義リスト(dl)で書いておいた方がよいとは思う。