JavaScript
jQuery
メモ

連動プルダウンshow()/hide()がsafari, IEでは効かない問題

More than 1 year has passed since last update.


連動プルダウンを作ろう

<input type="select" id="select1">

<option value="a">a</option>
<option value="b">b</option>
<option value="c">c</option>
</input>

<input type="select" id="select2">
<option value="a1">a1</option>
<option value="a2">a2</option>
<option value="b1">b1</option>
<option value="b2">b2</option>
<option value="c1">c1</option>
<option value="c2">c2</option>
</input>

こんなよくあるselect1の動きに追従してselect2のoptionの中身を変えようというプルダウン。


jQueryを書こう

$('#select1').on('change', evt => {

$('select2').find('option').each((idx, elem) => {
if($(elem).val().indexOf($(evt.target).val()) != -1){
// ①オプションを表示する
} else {
// ②オプションを非表示にする
}
});
});

select1の選択されたvalueとselect2のoptionのvalueをeachで一個ずつ比較して表示・非表示を行うというやつ。

簡単簡単はいできたーと書いたのがこのコード

$('#select1').on('change', evt => {

$('select2').find('option').each((idx, elem) => {
if($(elem).val().indexOf($(evt.target).val()) != -1){
// ①オプションを表示する
$(elem).show();
} else {
// ②オプションを非表示にする
$(elem).hide();
}
});
});


動作確認をしよう

先ほど書いたコード、、、え?safari動かなくね?


調べてみた

。。。残念ながらsafari, IEでoptionのshow()/hide()は効かないらしい。。。

つまりdisplay: noneが適用できない。

そのほかにも、内側の要素にはshow()/hide()が効かないという報告の記事もあり(未検証)


代替案

1、非表示はremove()、表示はappend()/prepend()する

2、prop("disabled", true)で選択できなくする

3、都度検索してキャッシュやDBなどからoption全部を入れ替える

今回は1で実装

<label id="hidden_area" style="display:none"></label>

1,このlabelに一度要素を退避。

2,退避したoptionに対してeach。

3,select1のvalueに一致するoptionのみ元のselect2へprepend()する

の手順を踏む。


最終的なコード

$('#select1').on('change', evt => {

let val = $('#select1').val();
// 全て退避
$('select2').find('option').each((idx, elem) => {
$('#hidden_area').prepend(elem);
});
$('#hidden_area').find('option').each((idx, elem) => {
if($(elem).val().indexOf(val) != -1){
// オプションをselect2へ移動
$('#select2').prepend(elem);
}
});
});

ようやく動いた。。。

1度前に遭遇したことあったのだが、ハマるのが2度目だったのでメモ。。。。