よしだのブログ

サブタイトルはありません。

iPad Safari + javascript でプルダウンの値を変更できない(解決!)

ども。今日は技術ネタ。

未解決なので、解決したら更新しようと思います。 ※解決しました!&追記しました。

iPad Safari でプルダウンの値を javascript で変更しようとしたのですが、何故かうまく設定できない現象があり、はまっています。

要件

  • プルダウンがあり、オプションは2つ
  • ユーザーがプルダウンの選択されているオプションを変更できないようにしたい
  • プルダウンは有効なままにする(disableにしない)。
  • JavaScriptを使って、ユーザーがオプションを変更後に元のオプションに戻す方式で、実現したい

環境

コード

まず、HTML

<select id="deliveryType">
    <option value="sendto" selected>郵送</option>
    <option value="email">E-Mail</option>
</select>

以下に、うまくいかなかった例を記載します。全て表示上は、利用者がオプションを変更できました。JavaScriptで元に戻せていないように見えます。
ちなみに、PC版 Chrome / IE10 では全て問題なく動きました。

ダメな例① : prop で値を設定しても反映されない。

$('#deliveryType').change(function () {
    var index = $("#deliveryType").prop("selectedIndex");
    if(index == 0){
    $("#deliveryType").prop("selectedIndex",1);
    }
    else if(index == 1){
    $("#deliveryType").prop("selectedIndex",0);
    }
    else {
    $("#deliveryType").prop("selectedIndex",0);
    }
    return false;
});

ダメな例② : val() でもダメ。

$('#deliveryType').change(function () {
    var val = $("#deliveryType").val();
    if(val == 'sendto'){
    $("#deliveryType").val('email');
    }
    else if(val == 'email'){
    $("#deliveryType").val('sendto');
    }
    else {
    $("#deliveryType").val('sendto');
    }
    return false;
});

ダメな例③ : オプションの属性を直接変更する方法でもダメ。

$('#deliveryType').change(function () {
    var val = $("#deliveryType").val();
    if(val == 'sendto'){
    $("#deliveryType option[value=email]").attr('selected', 'selected');
    } else if(val == 'email'){
    $("#deliveryType option[value=sendto]").attr('selected', 'selected');
    } else {
    $("#deliveryType option[value=sendto]").attr('selected', 'selected');
    }
    return false;
});

解決!

オプションを全て削除してから再度追加し直す方法でうまく行きました。

$('#deliveryType').change(function () {
    var val = $("#deliveryType").val();
    $("#deliveryType option[value=email]").remove();
    $("#deliveryType option[value=sendto]").remove();
    if(val == 'sendto'){
        $("#deliveryType").append('<option value="sendto">郵送</option>');
        $("#deliveryType").append('<option value="email" selected>E-Mail</option>');
    } else if(val == 'email'){
        $("#deliveryType").append('<option value="sendto" selected>郵送</option>');
        $("#deliveryType").append('<option value="email">E-Mail</option>');
    } else {
        $("#deliveryType").append('<option value="sendto" selected>郵送</option>');
        $("#deliveryType").append('<option value="email">E-Mail</option>');
    }
    return false;
});

関連情報

下記のエントリでもあるように、JavaScriptでDOM操作をすると、iPadでは今回のケースのように再描画してくれないことが有るらしく、強制的に再レンダリングすることによって解決することがあるようです。

Ipad dropdown does not show selected value when set by JQuery .val() - Stack Overflow

また、jQuery Mobile では refresh メソッドがあり、こちらでも再描画させることができるので、jQuery Mobile を使えるのであればこちらがいいかもしれないです。

jQuery Mobile APIでもっとJavaScriptプログラミング ― − @IT