6
4

More than 1 year has passed since last update.

[改良版]JavaScriptで複数のチェックボックスのうち1つでも選択されていたらボタンを有効にする

Last updated at Posted at 2022-06-25

学習の過程を記載していきます。
完成形はこちらです。

1. 前回の完成形

sample.html
<form>
    <label><input type="checkbox" name="sample" value="1" onchange="change()">選択肢1</label><br>
    <label><input type="checkbox" name="sample" value="2" onchange="change()">選択肢2</label><br>
    <label><input type="checkbox" name="sample" value="3" onchange="change()">選択肢3</label><br>
    <input type="submit" id="button" value="送信" disabled>
</form>
sample.js
function change() {
	const submitBtn = document.getElementById('button');
	const checkboxes = document.querySelectorAll('input[name="sample"]:checked');
	if (checkboxes.length === 0) {
		submitBtn.disabled = true;
	} else {
		submitBtn.disabled = false;
	}
}

前回の記事でこのような実装となりました。
想定通りの挙動となり満足していましたが、ありがたいことにコメントでアドバイスをいただき改善点を教わったので早速取り入れてみました。

振り分けに必要な条件が選択済みチェックボックスの有無のみで具体的な個数は不要なのであれば、querySelectorAllで条件に一致する要素を全て取得しなくてもquerySelectorで1つ取得できるかどうかだけで判断できると思います。
選択済みチェックボックスがあればその要素のうち最初のひとつが、無ければnullが返ってくるので、それを!でbool値に変換及び反転をすることでボタン要素のdisabledプロパティにそのまま渡すこともできますので、ifでの条件分岐も省略できます。

とてもわかりやすいです。
参考にコードもつけていただいていています。
せっかくなので一旦コードを見ずに実装してみて、あとで答え合わせをしてみようと思います。

2. boolean型に変換する

いただいたコメントの中で、

!でbool値に変換及び反転

ここが理解できなかったので調べてみました。
辿り着いたのはBooleanメソッドというもので、引数の真偽を確認し、boolean型の値を返却するということでした。

文字列は空文字("")がfalseでそれ以外はtrue、数値は0がfalseでそれ以外はtrueとなります。

参考
const a = Boolean("");          //false
const b = Boolean("sample");    //true
const c = Boolean(0);           //false
const d = Boolean(1);           //true
const e = Boolean(null);        //false

3. 答え合わせ

調べたことを参考に作り直したコードがこちら

sample.js
function change() {
	const submitBtn = document.getElementById('button');
	const hasChecked = !Boolean(document.querySelector('input[name="sample"]:checked'));
	submitBtn.disabled = hasChecked;
}

とてもスッキリしました。

const hasChecked = !Boolean(document.querySelector('input[name="sample"]:checked'));

ここでは選択済みになっているチェックボックスの最初の一つの要素(なければnull)を取得し、Booleanメソッドでboolean型の値をで反転させて変数に代入しています。
これならif文で条件分岐させる必要もなくなりました。
かなり自信あります。
答え合わせします。

・・・

全然違う!!!

参考として教えていただいたコードはこちらです。

const f = document.querySelector('form');
f.addEventListener('input', () =>
  f.querySelector('#button').disabled = !f.querySelector('[type=checkbox]:checked'));

・・・全くわかりません!笑
少しずつ解明していきます。

4. 少しずつ紐解く

const f = document.querySelector('form');

まず、form要素を丸ごと取得して変数に代入しています。

f.addEventListener('input', () =>
  // 処理
);

アロー関数を使用してaddEventListenerを設定しています。
addEventListenerでは第一引数で指定したイベントが実行されるたびに第二引数で指定した関数が呼び出されます。
ここではinputイベントを指定して、チェックボックスが選択されるたびに関数が呼び出されるようになります。
この方法だとチェックボックスのinputタグにonchange属性を指定する必要がなくなります。

f.querySelector('#button').disabled = !f.querySelector('[type=checkbox]:checked')

ここで送信ボタンを非活性とするかどうかを指定します。
f.querySelector('[type=checkbox]:checked')で選択済みになっているチェックボックスの最初の一つの要素(なければnull)を取得しているのですが、ここではboolean型に変換する必要があります。
しかし、「2. boolean型に変換する」で習得したBooleanメソッドを使用していません。
!を使用することで暗黙の型変換が行われるようです。

!でbool値に変換及び反転

というのはこういうことだったのだと理解できました。

参考
f.querySelector('[type=checkbox]:checked')    // 最初の要素 or null

!f.querySelector('[type=checkbox]:checked')   // false or true

5. 完成形

sample.html
<form>
  <label><input type='checkbox' value='1'>選択肢1</label><br>
  <label><input type='checkbox' value='2'>選択肢2</label><br>
  <label><input type='checkbox' value='3'>選択肢3</label><br>
  <input type='submit' id='button' value='送信' disabled>
</form>

<script>
const f = document.querySelector('form');
f.addEventListener('input', () =>
  f.querySelector('#button').disabled = !f.querySelector('[type=checkbox]:checked'));
</script>

See the Pen Untitled (@katao_eng) on CodePen.

とてもシンプルなコードですが内容が詰まっていてとても勉強になりました。
アドバイスいただき本当にありがとうございました。
これを自力で実装できる実力にはまだまだ至りません。

  • 関数
  • アロー関数
  • addEventListener
  • querySelector

そもそも基本的な知識がまだまだ足りていません。
次回はJavaScriptの基礎を習得してまとめていきたいと思います。

参考記事

JavaScriptのboolean型に変換する方法を現役エンジニアが解説【初心者向け】 | TechAcademyマガジン
【JavaScript】addEventListenerの使い方
JavaScript | inputイベント:フォームで文字が入力されたとき
EventTarget.addEventListener() - Web API | MDN
論理否定 (!) - JavaScript | MDN
型変換のいろいろ - Qiita
暗黙的な型変換 · JavaScript Primer #jsprimer

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4