複数の項目が連動したリストの表示について



0   名前: satochan : 2006/05/14(日) 22:27  ID:zlAemG07
下記のような複数の項目が連動したリストで、それぞれ中身が違うものを
同じページ内(JSP)に表示させたいと思っています。

<リスト1>
項目1:「病院」「学校」「娯楽施設」

↓(3つのうちいずれか選択)

項目2:項目1で選んだモノによって中身が変わる
(病院→「内科」「小児科」「皮膚科」etc)
(学校→「小学校」「中学校」「高校」etc)
(娯楽施設→「遊園地」「パチンコ」「動物園」etc)

<リスト2>
項目1:「主食」「野菜」「デザート」

↓(3つのうちいずれか選択)

項目2:項目1で選んだモノによって中身が変わる
(主食→「ごはん」「パン」「麺類」etc)
(野菜→「トマト」「玉ねぎ」「キャベツ」etc)
(デザート→「ケーキ」「ゼリー」「団子」etc)

JavaScriptについてはほとんど知識がなく、下記のサイトを真似て
<リスト1>は作ることが出来ました。
http://www.hiyoko3.com/sample/forme/multi_select/pref_list.html
続けて<リスト2>を追加したいのですが、
やり方を載せているサイトも見つけれず
どこをどう書き換えたり何を追加すればいいのか、
全く分からない状態です。

どなたか分かる方がいらっしゃいましたら、ご指導よろしくお願い致します。

1   名前: miz : 2006/05/14(日) 22:27  ID:IqvcT83d
解説付きのはここらとか?
http://www.parkcity.ne.jp/~chaichan/src/javasc31.htm
http://www.ybi.co.jp/koike/qa2500/qa2867.htm

まったく分からないとか言われても、配列の概念とか、DOM記述方法の詳細まで説明するのは難儀なので、どこまで作ったのかを提示して貰った方が、追加説明しやすいですけど。

2   名前: satochan : 2006/05/14(日) 22:27  ID:zlAemG07
mizさんご回答ありがとうございます。
参考にしたサイトだけ載せても分かりませんよね・・・
すいませんでした(汗)

同じページ内に、2つのセレクトボックスが連動したリストを
2箇所に表示するのは解決しました。
ですがそれとは別に、3つのセレクトボックスが連動したリストを
作ろうとしたのですが、追記の仕方が分かりません。

動作的には、下記のようにさせたいと思っています。(中身は変えました)
●セレクトボックス1:「家の中」「外出」

↓(選択)

●セレクトボックス2:
(「家の中」→「あそぶ」「昼寝」)
(「外出」 →「ショッピング」「ランチ」「デート」)

↓(選択)

●セレクトボックス3:
(「家の中」→「あそぶ」→「バドミントン」「人生ゲーム」「トランプ」)
(「家の中」→「昼寝」→「いびき」「寝言」)
(「外出」→「ショッピング」→「服」「バッグ」「化粧品」)
(「外出」→「ランチ」→「ファーストフード」「和食」)
(「外出」→「デート」→「映画」「遊園地」)


ソースの方は、セレクトボックス1・セレクトボックス2
の連動まで出来ています。
《testpage.jsp》
<html>
<head>
<title>てすとぺーじ</title>
<script language="JavaScript" src="testpage.js"></script>
</head>
<body>
<form name="Form1">
<select name="Select1" onChange="setMenuItem(this.selectedIndex)">
<option value="家の中">家の中</option>
<option value="外出">外出</option>
</select>
<select name="Select2">
<option value="あそぶ">あそぶ</option>
<option value="昼寝">昼寝</option>
</select>
</form>
</body>
</html>

《testpage.js》
menuItem1 = [["あそぶ","昼寝"],["ショッピング","ランチ","デート"]];

function setMenuItem1(n)
{
len = document.Form1.Select2.options.length;
for (i=len-1; i>=0; i--)
{
document.Form1.Select2.options[i] = null;
}
for (i=0; i<menuItem1[n].length; i++)
{
document.Form1.Select2.options[i] = new Option(menuItem1[n][i],menuItem1[n][i]);
}
}

参考サイト1:http://www.openspc2.org/reibun/javascript/form_selectmenu/027/index.html
参考サイト2:http://www.openspc2.org/reibun/javascript/index.html#17

すいませんが、よろしくお願いします。

3   名前: 花金 : 2006/05/14(日) 22:27
横からすいません。
new Option()って廃止されるんじゃなかったでしたっけ?
openspc.orgのサイトってIE専のひどいコード多いですよね。
Googleで捜せばもっとよいのあると思いまーす。
あ、すいませんでした。気にしないでください。

4   名前: miz : 2006/05/14(日) 22:27
改造の要点としては
1.3次元配列が必要です。
2.Select1の選択状態とSelect2の選択状態との2つのデータを関数に送る必要があります。
3連動を並列に2つ並べるとか、ほかのページにも使うとかを考えると、3つのidを引数で送る方が汎用性が高くなります。
ということで、selectタグにidも振ることとします。
3.Select1のonchange でも、変更したSelect2の状態によって、Select3を書き換える必要がある。

あとのは、蛇足ですけど
4.options[i]=null; はMac版 Netscape7.0(OS 8/9用)で動作しないと云う情報を他のサイトの掲示板で見たことがあります。
http://www.gac.jp/article/index.php?stats=question&id=16732&command=msg
 配列の要素を削除する方法として、lengthに0を代入という方法を、こちらでつい最近見かけたので、これを採用。
http://www.tagindex.com/cgi-lib/q4bbs/patio.cgi?mode=view&no=422
5.new Option() 一行で済むのは魅力的だけど。。。
createElement()を使ってユーティリティ関数を作ってみました

以下3連動用JavaScript 

menuItem1 = [["あそぶ","昼寝"],["ショッピング","ランチ","デート"]];
menuItem3 = [[["バドミントン", "人生ゲーム", "トランプ"],
              ["いびき", "寝言"]          ],
             [["服", "バッグ", "化粧品"],
              ["ファーストフード", "和食"],
              ["映画","遊園地"]           ]
            ];
// 1番目変更による  2番目のリスト切り替え
// @param select1_id : 連動元 select id 最初のリスト
// @param set2_id    : 連動変更先 select id 2番目のリスト
// @param set3_id    : 連動変更先 select id
function list_set2(select1_id, set2_id, set3_id){
	if(! document.getElementById) return;
	var n1 = document.getElementById(select1_id).selectedIndex;
	add_list( set2_id, menuItem1[n1] );
	var n2 = 0;
	add_list( set3_id, menuItem3[n1][n2] );
}

// 連動optionオブジェクト 切り替え, data array 利用 (3連動→3次元配列)
// 2番目変更による  3番目のリスト切り替え
// @param select1_id : 連動元 select id 最初のリスト
// @param select2_id : 連動元 select id 2番目のリスト
// @param set3_id    : 連動変更先 select id
function list_set3(select1_id,select2_id, set3_id){
	if(! document.getElementById) return;
	var n1 = document.getElementById(select1_id).selectedIndex;
	var n2 = document.getElementById(select2_id).selectedIndex;
	add_list( set3_id, menuItem3[n1][n2] );
}

//  select optionとして 配列の要素を追加
// @param set_id : 変更先 select id
// @param list   : 配列オブジェクト
function  add_list( set_id, list ){
	if(! document.getElementById) return;
	var sel_obj = document.getElementById(set_id);
	sel_obj.options.length = 0;	// 配列の要素全削除はこれでもいける
	var ll = list.length;
	for (i=0; i<ll; i++){
		opt_add(sel_obj, list[i]);
	}
	sel_obj.size = ll ;// 全行表示 ドロップダウンにするならllを1に変更
	sel_obj.selectedIndex = 0;
}

// select object に option追加
// @param sel_obj : select object
// @param opt_v   : option value, text
function opt_add(sel_obj,opt_v){
	if(! document.createElement) return null;
	var opt_obj = document.createElement("OPTION");
	opt_obj.value = opt_v;
	opt_obj.appendChild( document.createTextNode(opt_v) );
	sel_obj.appendChild(opt_obj);
}

select タグの記述はこんな感じ
<select name="s1_rendou" id="s1_rendou" onchange="list_set2(this.id, 's2_rendou', 's3_rendou')" >
<select name="s2_rendou" id="s2_rendou" onchange="list_set3('s1_rendou', this.id, 's3_rendou')" >
<select name="s3_rendou" id="s3_rendou" >


5   名前: Pid ◆byEkK9OALr : 2006/05/14(日) 22:27
>>3
> new Option()って廃止されるんじゃなかったでしたっけ?

JavaScript 1.4 で,いつの間にか消えていますね。廃止とは明示されてないようですが……。


>>4
> options[i]=null; はMac版 Netscape7.0(OS 8/9用)で動作しない

と言うか,options.items (i) で返ってくるノードの参照だけを消しても意味がないので,その動作は正当です。


> 配列の要素を削除する方法として、lengthに0を代入という方法を、こちらでつい最近見かけたので

ちょっとだけ補足しますと,Array と options(HTMLOptionsCollection)は全く別のインタフェースですので,Array で可能でも options で可能とは限りません。

この場合,HTMLOptionsCollection の定義を見ます。
http://www2u.biglobe.ne.jp/%7Eoz-07ams/prog/dom-ref/HTML/HTMLOptionsCollection.html

すると,length は『リストの長さまたはサイズを指定する』とありますので,値の設定も可能です。ただし,続けて『実装が長さの設定を許可しない場合』は例外を返す,とも明記してありますので,若干注意が必要です。


> var opt_obj = document.createElement("OPTION");

sel_obj.add/remove メソッドでも良いでしょうが,IE とそれ以外で挙動が違うので,miz さんの方法が確実ですね(なお,i がグローバル変数になっていますのでご注意を)。

6   名前: miz : 2006/05/14(日) 22:27
>>5
>ちょっとだけ補足しますと,Array と options(HTMLOptionsCollection)は全く別のインタフェースですので,Array で可能でも options で可能とは限りません。

あ、ごっちゃにしてました、いつも素早い訂正有り難うございます。

>なお,i がグローバル変数になっていますのでご注意を

ご指摘有り難うございます。
for()内の変数にvar宣言を付けるのはつい忘れてしまいます。

一覧へ戻る