サンプルコード
<form> <select id="upper"> <option value="1">first</option> <option value="2">second</option> </select> <select id="downer"> <option value="1_1">first_first</option> <option value="1_2">first_second</option> <option value="2_1">second_first</option> <option value="2_2">second_second</option> </select> </form>
仕様は、
- id="upper" のselect要素のvalueと、id="downer"のselet要素の子のoption要素のvalueの1文字目を比較し、値が一致するdownerのoptionだけを、ユーザーが選択可能とする。
最初に作ったプログラム
最初に、条件に一致しないdownerのoption要素に、disabled属性を設定してみました。
サンプルコード
window.onload = function(){ var upper_select = document.getElementById("upper"), downer_select = document.getElementById("downer"); autoSelectOptions(upper_select, downer_select); upper_select.onchange = function(){autoSelectOptions(upper_select, downer_select)}; } function autoSelectOptions(upper_select, downer_select) { var selected_value = upper_select.value, downer_ch = downer_select.childNodes, first_hit_flag = true; for (var i=0, len=downer_ch.length; i < len; i++) { if (downer_ch[i].tagName && downer_ch[i].tagName === 'OPTION' ){ downer_ch[i].disabled = true; //一旦すべてのoptionを選択不可にする downer_ch[i].selected = false; //選択状態をリセットする if (selected_value === downer_ch[i].value.split('_')[0]) { downer_ch[i].disabled = false; //選択可能にする if (first_hit_flag === true) { //一番上の選択可能optionを選択状態表示させる downer_ch[i].selected = true; first_hit_flag = false; } } } } }
落とし穴にはまる
ふふふ、このくらい簡単々と調子に乗ってたら、このコードではIE6, 7では正しく動作しませんでした。IE6, 7 では、option要素にはdisabled を設定できないということが原因です。。
というわけで、IE6, 7にも対応したのが以下のコードです。 ポイントは、window のonload イベントが呼ばれたときに、id=downerのselect要素の子のoption要素に対してcloneNode()メソッドを呼び出し、optionのクローンを作成していることです。
autoSelectOptions関数が呼ばれるたびに、一旦downerのoption要素を全て削除してから、複製化しておいたoptionから、条件に一致する要素のみ挿入しています。
サンプルコード
window.onload = function(){ var doc = document, upper_select = document.getElementById("upper"), downer_select = document.getElementById("downer"), downer_options = downer_select.childNodes, cloned_options = new Array(); //初期表示されるdownerのoptionのクローンを保存しておく for( var i=0, len=downer_options.length; i < len; i++){ if (downer_options[i].tagName && downer_options[i].tagName.toLowerCase() === 'option') { cloned_options.push(downer_options[i].cloneNode(true)); } } autoSelectOptions(upper_select, downer_select, cloned_options); upper_select.onchange = function(){autoSelectOptions(upper_select, downer_select, cloned_options)}; } function autoSelectOptions(key_select_box, target_select_box, option_list){ if (typeof key_select_box === 'undefined' || typeof target_select_box === 'undefined' || typeof option_list === 'undefined') { return; } var first_node_flag = true, ch = target_select_box.childNodes; for (var i=ch.length - 1; i >= 0; i-- ){ //selectの子ノードを一旦すべて削除する。 ch[i].parentNode.removeChild(ch[i]); } var fragment = document.createDocumentFragment(); for (var i = 0, len = option_list.length; i < len; i++) { if (option_list[i].tagName && option_list[i].tagName.toLowerCase() == 'option'){ option_list[i].selected = false; if (option_list[i].value.split('_')[0] === key_select_box.value){ fragment.appendChild(option_list[i]); if (first_node_flag) { option_list[i].selected = true;//最初に挿入するノードを,選択状態にする first_node_flag = false; } } } } //documentに条件に一致するのoptionのみ追加 target_select_box.appendChild(fragment); }IE6, 7 ともに動作することを確認しました! 一旦option要素をすべてremoveするなどちょっと強引ですが、仕様は満たされてるので良しとします。
まとめ
- IE6, IE7 では、optionのdisabled属性は、設定できないので注意する!
参照URL
Forms in HTML documents http://www.w3.org/TR/1999/REC-html401-19991224/interact/forms.html#h-17.6
Node.cloneNode - MDN https://developer.mozilla.org/En/DOM/Node.cloneNode
0 件のコメント:
コメントを投稿