やりたいこと
htmlのセレクトボックスにて、選択肢が大量にある場合、階層的に選択できるようにしたいと考えました。1つ目のセレクトボックスで大分類を選択し、2つ目で中分類、3つ目で末端の項目を選択するイメージです。
質問
下のコードで実現できたと考えていますが(logic="OK")、このままでは案件によってコードの書き換えが必要なので、汎用的にするため、配列で指定できるように改修しました(logic="NG")。しかし、期待していた動作になりません。
当方の理解がどのように間違っているのか。どう直せばいいか。ご教授いただければ幸いです。
当方なりの考察
ソースを「var logic="NG";」としたとき、1つ目のセレクトボックスを操作すると、console.logで「A/B/2」と出力して欲しいところ、「B/C/4」と出力されました。本来、2つ目のセレクトボックスのイベントで出力するログです。
addEventListenerの動作が、当方の期待と異なるのかも知れません。
値渡しや参照渡しと関係あるかと妄想しましたが、解決には至りませんでした。
動作確認方法
下のソースを保存して、ブラウザで開き、
A地域を選択し、B国を選択し、C都市を選択すると、絞り込みができると思います。
ソースが「var logic="OK";」のままで、1つ目のセレクトボックスの選択を変えると、
2つ目のセレクトボックスが影響受けますが、
ソースを「var logic="NG";」に変更し、1つ目のセレクトボックスの選択を変えると、
2つ目のセレクトボックスが影響受けなくなります。
ソースコード
html、javascript
1<!DOCTYPE html> 2<html lang="ja"> 3<body> 4<script> 5function shiborikomi(name1,name2,n){ 6console.log(name1+"/"+name2+"/"+n); 7 idx=document.getElementsByName(name1)[0].selectedIndex; 8 v1= document.getElementsByName(name1)[0].options[idx].value; 9 n1= document.getElementsByName(name1)[0].options[idx].text.trim().substr(0,n); 10 11 es= document.getElementsByName(name2)[0].getElementsByTagName("option"); 12 for(i=0;i<es.length;i++){ 13 n2=es[i].innerText.trim().substr(0,n); 14 if(n1==n2 && v1>0){ 15 es[i].style.display=''; 16 }else{ 17 if(document.getElementsByName(name2)[0].selectedIndex==es[i].index){ 18 document.getElementsByName(name2)[0].selectedIndex=0; 19 } 20 es[i].style.display='none'; 21 } 22 } 23 em= document.getElementsByName(name2)[0]; 24 const ev=new Event("change",{bubbles:false,cancelable:true}); 25 em.dispatchEvent(ev); 26} 27 28var logic="OK"; 29 30window.addEventListener("DOMContentLoaded",function(){ 31 if(logic=="OK"){ 32 name1= "A"; 33 name2= "B"; 34 name3= "C"; 35 shiborikomi(name1,name2,2); 36 shiborikomi(name2,name3,4); 37 document.getElementsByName(name1)[0].addEventListener("change",function(e){shiborikomi(name1,name2,2)}); 38 document.getElementsByName(name2)[0].addEventListener("change",function(e){shiborikomi(name2,name3,4)}); 39 } 40 if(logic=="NG"){ 41 var arr=[[2,"A","B"],[4,"B","C"]]; 42 for (var i=0;i<arr.length;i++) { 43 n=arr[i][0];parent_=arr[i][1];child_=arr[i][2]; 44 shiborikomi(parent_,child_,n); 45 } 46 for (var i=0;i<arr.length;i++) { 47 n=arr[i][0];parent_=arr[i][1];child_=arr[i][2]; 48 document.getElementsByName(parent_)[0].addEventListener("change",function(e){shiborikomi(parent_,child_,n)}); 49 } 50 } 51}); 52 53</script> 54<br>A地域 55<select name="A"> 56 <option value="">選択してください</option> 57 <option value="1" selected>01:欧米</option> 58 <option value="2">02:アジア</option> 59</select> 60<br>B国 61<select name="B"> 62 <option value="" >選択してください</option> 63 <option value="11" selected>0101:アメリカ</option> 64 <option value="12">0102:フランス</option> 65 <option value="21">0201:インド</option> 66 <option value="22">0202:中国</option> 67</select> 68<br>C都市 69<select name="C"> 70 <option value="">選択してください</option> 71 <option value="111" selected>010101:ニューヨーク</option> 72 <option value="112">010102:ロサンゼルス</option> 73 <option value="121">010201:ニース</option> 74 <option value="122">010202:パリ</option> 75 <option value="211">020101:デリー</option> 76 <option value="212">020102:バンガロール</option> 77 <option value="221">020201:北京</option> 78 <option value="222">020202:香港</option> 79</select> 80</body></html>
補足情報(FW/ツールのバージョンなど)
当方は、chromeで動作確認しました。

回答2件
あなたの回答
tips
プレビュー
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。
また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。
2023/04/14 06:20