ラジオボタンをクリックで解除可能にする

ラジオボタンをクリックで解除可能にする
Image by AlexLoban from Pixabay

2021.04.10(更新日:2021.04.11)

フォームで使われるラジオボタン。
一度選択してしまうと再読み込みでもしない限り、選択解除出来ない。
そこでチェックボックスのように再クリックで解除出来るようにしてみた。

この記事は1年以上経過しています。内容的に古い場合があります。

jQueryを使わずに実現させてみる

HTMLは普通に書くのでOK。とりあえずradioにlabelを付ける。

/* HTML */
<form name="demoform">
  <label><input type="radio" name="item" value="1">item1</label><br>
  <label><input type="radio" name="item" value="2">item2</label><br>
  <label><input type="radio" name="item" value="3">item3</label><br>
</form>

JSは以下。body閉じタグの前にでも入れておく場合は、scriptで囲むのを忘れずに。

/* javascript */
const item = document.demoform.querySelectorAll("label");
for( let i = 0; i < item.length; i++ ){
  let checkbox = item[i].querySelector("input[type='radio']");
  //labelにdata-statusを付加して値を0に
  checkbox.dataset.status = 0;
  checkbox.addEventListener('click', function() {
    let state = checkbox.dataset.status;
    //data-statusが1で、ラジオボタンがchecked状態で解除
    if( state == "1" && checkbox.checked == true ){
      checkbox.checked = false;
      checkbox.dataset.status = "0";
    } else {
      //data-statusが0の場合、ラジオボタンがchecked、data-statusを1に変更
      checkbox.checked = true;
      checkbox.dataset.status = "1";
    }
  });
};

解説

イベント(clickやchange)後「checkされてたら解除、されてなければcheck」と単純な仕組みで考える。
その場合イベント発火直後、ラジオボタンが有無を言わせずchecked状態になるので「その前の状態」が取得出来ない。クリックしたら常にchecked状態しか返ってこないので比較が出来ない。
てなわけで、labelにイベント前の状態を持たせて比較させ処理させている。

まとめ

もっと秀逸なコードも存在するだろうけど、まあ動いたからOK。
しかしjQueryを使った方が何んとなく「簡単、簡潔」のような気がしたのであった。

/* use jQuery */
$(function(){
  var status = $("input[name='item']:checked").val();
  $("input[name='item']").on("click", function(){
    if($(this).val() == status) {
      $(this).prop("checked", false);
      status = false;
    } else {
      status = $(this).val();
    }
  });
})(jQuery);