Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

連動プルダウン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度目だったのでメモ。。。。

m-hatano
スタートアップの取締役CTO。少し前までは普通のwebエンジニア。大手SIerから3人スタートアップまで幅広経験。 自称フルスタックエンジニア(ビジネス、技術両方面) TwitterではエンジニアっぽくないCTO垢やってます。
https://note.com/hatamasa
anyinc
any株式会社のエンジニアチームです
http://anyinc.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away