• ベストアンサー

セレクトメニューで選択された項目に応じて、別のセレクトメニューの内容を変更する場合について

アドバイスお願いします。 ページロード時、最初ののセレクトメニューは「国を選択してください」が選択された状態となりますが、次のセレクトメニューが空白になってしまいます。 これを最初のメニューと同じく「国を選択してください」と表示させるには、どうしたらよろしいでしょうか? 【HTML】 <html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>JavaScript</title> <link rel="stylesheet" type="text/css" href="main.css" media="all"> <script type="text/javascript" src="main.js"></script> </head> <body> <form action="./enq.cgi" method="get" id="mainForm" name="mainForm"> <select id="selMain"> <option value="">国を選択してください</option> <option value="jp">日本</option> <option value="usa">アメリカ</option> </select> <select id="selSub">国を選択してください</select> </form> </body> </html> 【main.js】 window.onload = function(){ document.getElementById("selMain").onchange = function(){ var selNo = this.selectedIndex; var selObj = document.getElementById("selSub"); var optionData = [[ ],[ { text:"東京", value:"tokyo"}, { text:"大阪", value:"osaka"}, { text:"名古屋", value:"nagoya"} ],[ { text:"ニューヨーク", value:"ny"}, { text:"ロサンゼルス", value:"la"} ] ]; while(selObj.hasChildNodes()) { selObj.removeChild(selObj.firstChild); } for (var i=0; i<optionData[selNo].length; i++){ selObj.options[i] = new Option(optionData[selNo][i].text, optionData[selNo][i].value); } } } また、質問にありますようなセレクトメニューを実装する場合、JavaScriptとAJAX、どちらが適したものと言えるのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • yyr446
  • ベストアンサー率65% (870/1330)
回答No.5

<補足> value値をCGIに送信する方法は、蛇足ですよね。 別にajaxやjavascript使わなくても、 <form method="POST" action="xxx.cgi"> ---- <input type="submit" value="送信" /> </form> で送信するだけです。

editbooth
質問者

お礼

とても参考になるご意見、またアドバイスを頂きありがとうございます。 value値のセット方法について、教えて頂いた方法でうまくできそうです。 >selObj.options[i+1] = new Option(Citys[i], Citys[i]); この状態でvalue値を変えるには他をどう変えたらいいのか悩んでおりましたが、教えて頂いた方法を見てとても参考になりました。 当方、まだまだ知識不足なもので何をどう変えればいいのかも定かではない状態ですが、こうやって教えて頂いたものをじっくり勉強し自分の理解を深めるヒントにしていきたいと思います。 >それにつけても、素のjavascriptのみでXMLを扱うのは結構面倒で、参考資料も少ないのが現状です。 >ちなみに私は普段javascriptでXMLを扱う時は先人の方が作成して広く出回っているブラウザー非依存のxmlパーサーのライブラリーを使っています。 教えて頂いたURLを参考に私も先人の方が作成したブラウザー非依存のxmlパーサーを勉強していきたいと思います 詳しい説明をして頂き、本当にありがとうございました。

その他の回答 (4)

  • yyr446
  • ベストアンサー率65% (870/1330)
回答No.4

>>Ajaxカテゴリーで同じような質問をされている方がおり、私もその回答を待っていました。<< 別の人だったのですか。どうも失礼しました。でも、よけいなおせっかいにならずによかったです。 正直言って私も自身のスキルアップのために回答を作っています。ですから解説するのは苦手なんですよ。 お尋ねの,都市の<option>のVALUE値もセットする件ですが、 selObj.options[i+1] = new Option(Citys[i], Citys[i]); の一つ目のアーギュメントがテキストで後ろがvalue値ですがこのサンプルでは同じにしています。 別途value値をセットするには、その値を取ってくる必要があります。 例えば、xmlで、 <city id="tokyo">tokyo,東京</city> としておいて、 var arg = Citys[i].split(","); selObj.options[i+1] = new Option(arg[1], arg[0]); としてしまう方法もありますが、とってつけたような方法ですね。 本来なら、xmlのポリシーに則って、 <city id="tokyo">東京</city> ---(1) とか、 <city> ---(2)  <optiontext>東京</optiontext>  <optionvalue>tokyo</optionvalue> </city> みたいにするのが、正統かもしれません。(あまりxmlくわしくないので..) xmlの構造を変えて、しかも取ってくるデータも追加するわけですから そんな時はjavascriptでxmlをパースしている部分も変更する必要があります。 (1)ならtarget_node自身のattributeノード(nodeType=3)の値を参照して、テキストノード値と一緒に格納すればよし、 (2)ならtarget_nodeの子供が増えますから、子供らのnodeNameで振り分けそれぞれのテキストノード値をと一緒に 格納すればよし、格納する配列も2次元配列Citys[][]にしておけば、 手間が省けます。まあ、少しづつ試してみる事ですね。  それにつけても、素のjavascriptのみでXMLを扱うのは結構面倒で、参考資料も少ないのが現状です。 ちなみに私は普段javascriptでXMLを扱う時は先人の方が作成して広く出回っているブラウザー非依存のxmlパーサー のライブラリーを使っています。 http://www.kawa.net/works/js/xml/objtree.html とかGoogleの http://code.google.com/intl/ja/apis/maps/documentation/reference.html#GXml とか、他にも多数あると思います。

  • yyr446
  • ベストアンサー率65% (870/1330)
回答No.3

No.2のyyr446です。 セレクトのオプションをAJAXにした利点ですが、 選択させるデータをXMLで外部に作っておけば,データの変更・追加 があった時にXMLだけメンテナンスすればよいという点です。 この例のように、国、県、都市、...みたいな階層を持ち、頻繁に 更新され、項目自体が追加されるようなデータにはXMLが便利です。 (件数が膨大になれば、DB使った方がいいですが) ただし、javascript側でXMLをパースするのは、ブラウザーによる実装の 違いとか、効率とかを考えるといまいちです。サーバーサイドのプログラムで解析した結果をajaxで返した方がよいかもしれません。 一応、IE7.0とFirefox3.5でうまくいきました。ご参考までに <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="ja-JP"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Script-Type" content="text/javascript"> <meta http-equiv="Content-Style-Type" content="text/css"> <meta http-equiv="Cache-Control" content="no-cache" /> <meta http-equiv="Expires" content="0" /> <title></title> <style type="text/css"></style> <script type="text/javascript" charset="utf-8"> <!-- function SetCity(country){ var xmlHttp =(window.ActiveXObject)?new ActiveXObject("Msxml2.XMLHTTP"):new XMLHttpRequest(); var Citys =[]; xmlHttp.onreadystatechange = GetXmlObj; if(country){ xmlHttp.open("GET","City.xml",true); xmlHttp.send(null); }else{ ResetSelectOpt(); } function GetXmlObj(){ if (xmlHttp.readyState == 4 && xmlHttp.status == 200){ var xmlobj=xmlHttp.responseXML; var xpath_str = '//country[@id="'+ country + '"]'; var target_node; var node_list; if(window.ActiveXObject){ // IE xmlobj.setProperty("SelectionLanguage", "XPath"); node_list = xmlobj.selectNodes(xpath_str); target_node = node_list(0); for(i=1;i<target_node.childNodes.length;i++){ if(target_node.childNodes[i].nodeType==1){ Citys.push(target_node.childNodes[i].childNodes[0].nodeValue); } } }else{ // IE以外 node_list = xmlobj.evaluate(xpath_str,xmlobj,null,XPathResult.ANY_TYPE,null); target_node = node_list.iterateNext(); for(i=0;i<target_node.childNodes.length;i++){ if(target_node.childNodes[i].nodeType==1){ Citys.push(target_node.childNodes[i].textContent); } } } SetSelectOpt(Citys); } } function SetSelectOpt(Citys){ var selObj = document.getElementById("city"); while(selObj.hasChildNodes()){ selObj.removeChild(selObj.firstChild); } selObj.options[0] = new Option("都市を選択して下さい", ""); for(i=0;i<Citys.length;i++){ selObj.options[i+1] = new Option(Citys[i], Citys[i]); } } function ResetSelectOpt(){ var selObj = document.getElementById("city"); while(selObj.hasChildNodes()){ selObj.removeChild(selObj.firstChild); } selObj.options[0] = new Option("都市を選択して下さい", ""); } } // --> </script> </head> <body onload="document.form.country.selectedIndex=0;"> <form name="form" action="#"> <select name="country" id="country" onchange="SetCity(this.value)"> <option id="" value="" selected>国名を選択して下さい</option> <option id="jp" value="jp">日本</option> <option id="usa" value="usa">アメリカ</option> <option id="uk" value="uk">イギリス</option> </select> <br /> <select name="city" id="city"> <option vlaue="" selected>都市を選択して下さい</option> </select> </form> </body> </html> --------------------------------------------------- データはXMLとして外出しします。City.xmlの中身 --------------------------------------------------- <?xml version="1.0" encoding="UTF-8"?> <citydata> <country id="jp"> 日本 <city>東京</city> <city>大阪</city> <city>京都</city> </country> <country id="usa"> アメリカ <city>ニューヨーク</city> <city>ワシントン</city> <city>シカゴ</city> </country> <country id="uk"> イギリス <city>ロンドン</city> <city>リバプール</city> <city>マンチェスター</city> </country> </citydata>

editbooth
質問者

お礼

IEでも無事動作しました! この方法だと項目が増えた時にもXMLのみを更新すればいいのでとても作業が楽になりそうな気がしてます。 ただ、申し訳ありませんが、1点教えて頂きたいことがございます。 Ajaxの教本を見ながら教えて内容を熟読しているのですが、都市を選ぶセレクトメニューのvalue値はどのように設定すればいいのでしょうか? 最初のセレクトメニューで「日本」を選択、次のセレクトメニューで「東京」を選択した場合、東京のvalue値を"tokyo"と仮定してこの値をCGIに送信したいと思っています。 うまく伝えられず申し訳ありませんが、アドバイス頂けませんでしょうか。 よろしくお願いします。

editbooth
質問者

補足

とても詳しいご回答ありがとうございます。 Ajaxカテゴリーで同じような質問をされている方がおり、私もその回答を待っていましたが、回答がつかないようでしたので、こちらでご質問させて頂きました。 Ajaxを使い希望の動作をするには複雑な処理が必要だったためjavascriptのみでの実装を考えていましたが、とても参考になるご回答を頂き大変勉強になりました。 まずは、教えて頂いた方法を試行させて頂き、内容を考察した上で再度お礼をさせて頂ければと思います。 何度もご回答頂きありがとうございました。

  • yyr446
  • ベストアンサー率65% (870/1330)
回答No.2

AJAXのカテゴリーに同様の質問をされていたような... AJAXでやる例を途中まで、試して見ました(IEはだめです)。 <script type="text/javascript"> <!-- function SetCity(country){ var xmlHttp = new XMLHttpRequest(); var Citys =[]; xmlHttp.onreadystatechange = GetXmlObj; if(country){ xmlHttp.open("GET","./City.xml",true); xmlHttp.send(null); } function GetXmlObj(){ if (xmlHttp.readyState == 4 && xmlHttp.status == 200){ var xmlobj=xmlHttp.responseXML; var xml = xmlobj.evaluate('//country[@id="'+ country + '"]',xmlobj,null,XPathResult.ANY_TYPE,null); var thisNode = xml.iterateNext(); for(i=0;i<thisNode.childNodes.length;i++){ if(thisNode.childNodes[i].nodeType==1){ Citys.push(thisNode.childNodes[i].textContent); } } SetSelectOpt(Citys); } } function SetSelectOpt(Citys){ for(i=0;i<Citys.length;i++){ alert(Citys[i]); } } } // --> </script> <body> <select name="country" id="country" onchange="SetCity(this.value)"> <option id="" value="">国名を選択して下さい</option> <option id="jp" value="jp">日本</option> <option id="usa" value="usa">アメリカ</option> <option id="uk" value="uk">イギリス</option> </select> <select name="city" id="city"> <option vlaue="">国名を選択して下さい</option> </select> </body> --------------------------------------------------- データはXMLとして外出しします。City.xmlの中身 --------------------------------------------------- <?xml version="1.0" encoding="UTF-8"?> <citydata> <country id="jp"> 日本 <city>東京</city> <city>大阪</city> <city>京都</city> </country> <country id="usa"> アメリカ <city>ニューヨーク</city> <city>ワシントン</city> <city>シカゴ</city> </country> <country id="uk"> イギリス <city>ロンドン</city> <city>リバプール</city> <city>マンチェスター</city> </country> </citydata>

  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.1

こんばんは。 「日本」や「アメリカ」を選択したときと同じように処理すればよいのでは? *配列は「text」と「value」の組合せに決まっているので、勝手ながら  連想配列となっている部分をはずしてしまいました。 <html> <head> <script type="text/javascript"> window.onload = function(){ document.getElementById("selMain").onchange = function(){ var selNo = this.selectedIndex; var selObj = document.getElementById("selSub"); var optionData = [ ["国名を選択してください,"], ["東京,tokyo","大阪,osaka","名古屋,nagoya"], ["ニューヨーク,ny","ロサンゼルス,la"] ]; var i, tmp = []; while(selObj.hasChildNodes()) { selObj.removeChild(selObj.firstChild); } for (var i=0; i<optionData[selNo].length; i++){ tmp = optionData[selNo][i].split(","); selObj.options[i] = new Option(tmp[0], tmp[1]); } } } </script> </head> <body> <form action="./enq.cgi" method="get" id="mainForm" name="mainForm"> <select id="selMain"> <option value="" selected>国を選択してください</option> <option value="jp">日本</option> <option value="usa">アメリカ</option> </select> <select id="selSub"> <option value="">国を選択してください</option> </select> </form> </body> </html> >JavaScriptとAJAX、どちらが適したものと言えるのでしょうか? Ajaxもjavascriptを利用するので、どちらが適しているという選択でもないような… データ量が多くて組合せが多かったり、条件判定がいろいろあったりでデータベースから選んだり、そのデータファイルの更新が別のソフトで行われていたり、他でも共通で利用していたりなどであれば迷わずAjax、固定的なデータで量がそれほどでもなく、かつ、同じデータを他でも利用するとかでなければ、通信しない分レスポンスが良いjavascriptでしょうか。

editbooth
質問者

お礼

ご回答ありがとうございます。 無事、希望通りの動作ができました。 また、最初のプルダウンでどこかの国を選択した後、再度「国を選択してください」を選択すると 次のセレクトメニューが空白になってしまうろいう現象が起きていましたが、 連想配列部分も訂正することで、こちらもうまくいくようになりました。 また、Ajaxを使うかjavascriptのみで実装するのがいいのかは目的によっても大きく違ってくると思いますので再度考察して見たいと思います。 詳しく教えて頂きありがとうございました。

関連するQ&A