ラジオボタンのチェックを値で設定するときは配列で設定する!!

ラジオボタンの設定をjqueryスクリプトで行うときにハマるという話です。

問題の前提

ラジオボタンは通常複数の同一name属性をもつ要素が集まってできています。

<input type="radio" name="post_radio" value="val1" checked>要素1 <input type="radio" name="post_radio" value="val2">要素2 <input type="radio" name="post_radio" value="val3">要素3

こんな感じです。 ここで、要素3にチェックを入れるという設定をjqueryでやりたいという要求があるとします まず、

  let elms=$('input:radio[name="post_radio"]')

とやると変数elmsは配列となり、3つの要素が入ります。 そして、要素3にチェックを入れたいわけです。

eqメソッドによる設定

一つの方法としては 3番目の要素をeqメソッドで特定して、propメソッドでチェックを入れる方法。次のような感じです。

elms.eq(2).prop('checked',true);

しかし、この方法は「要素3」が3番目にあることがわかっていなければ成立しません。HTMLが書き換わり、要素の数が増えたり、順番が変わるとjqueryも書き換える必要があります。

値(value属性)で設定する

そこで、HTMLが変わってもjquery側に影響を及ぼさない方法としてもう一つの方法があります。 それはvalue属性で要素を特定するという方法です。もちろんこの方法でもvalue属性が書き換わればjqueryも書き換える必要が生じますが、要素の数が変わったり、順番が変わることの頻度に比べると少ないと思われます。また、スクリプトの可読性も高いと思います(何番目という指定より、〇〇というvalueをもつ要素というほうが分かりやすいでしょ。)。 そこでこんな書き方をします。

  $('input:radio[name="post_radio"]').val(['val3'])

これで要素3にチェックが入るのですが、ここで罠が潜んでいるのです。 よく見ればわかるのですが、valメソッドの引数が配列になっています。これがこの記事の結論です。

2つの失敗例

  $('input:radio[name=post_radio]').val('val3')

これだとチェックは入りません。中途半端に覚えているとこのように文字列を入れてしまうと思いませんか? このコードはラジオボタンvalue属性を変更しようとするものです。これを実行すると、チェックの状態は変わりませんが、全てのラジオボタンvalue属性は'val3'に変わってしまします。

  $('input:radio[name=post_radio]').val(['val3']).prop('checked', true);

これもダメです。これは最後のラジオボタンが選択状態になります。 今回の例はたまたま最後のラジオボタンにチェックを入れようとしているので結果オーライですが2番目に入れようと思って'val2'を指定しても要素3が選択状態になります。これは最初に value="val2" のラジオボタンが選択されるのですが、その後で全てのラジオボタンがチェックされようとします。しかし、ラジオボタンのグループに対して、一度に複数の要素をチェックすることはできません。結果的に最後のラジオボタンだけがチェックされた状態になります。

これ相当ハマりすよ。 ご注意ください。