質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

1090閲覧

【Javascript】各フォーム項目ごとにチェックボックスのチェックできる数を制限

ibis_masuda

総合スコア5

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2023/01/30 03:12

前提

Javascript初心者です。
Javascriptで、チェックボックスのチェックできる数を制限しています。

実現したいこと

質問事項が複数ある中で、各質問項目ごとにチェック数の制限をしたいです。
例:
質問1で、チェックを3つまで
質問2でも、チェックを3つまで

発生している問題・エラーメッセージ

全てのチェックボックスの中で3つまでとなってしまい、「各質問ごとに」という制限をする方法がわかりません。

foreachや、for文などで質問項目ごとに対して、要素の取得する時どのような考え方でコードを書いたら良いかいまいちわかりません。
どうか、アドバイス最適な実装方法をご教示いただけますと幸いです。

何卒よろしくお願いいたします。

該当のソースコード

【HTML】

<div class="q-block"> <div class="title">質問1(3つまで選択できます。)</div> <div class="checkbox-group js-check-limited"> <div class="checkbox-group__item"> <span class="checkbox-field"> <label> <input type="checkbox" name="test" class="js-check-item"> <span>選択肢1</span> </label> </span> </div> <div class="checkbox-group__item"> <span class="checkbox-field"> <label> <input type="checkbox" name="test" class="js-check-item"> <span>選択肢2</span> </label> </span> </div> <div class="checkbox-group__item"> <span class="checkbox-field"> <label> <input type="checkbox" name="test" class="js-check-item"> <span>選択肢3</span> </label> </span> </div> <div class="checkbox-group__item"> <span class="checkbox-field"> <label> <input type="checkbox" name="test" class="js-check-item"> <span>選択肢4</span> </label> </span> </div> <div class="checkbox-group__item"> <span class="checkbox-field"> <label> <input type="checkbox" name="test" class="js-check-item"> <span>選択肢5</span> </label> </span> </div> <div class="checkbox-group__item"> <span class="checkbox-field"> <label> <input type="checkbox" name="test" class="js-check-item"> <span>選択肢6</span> </label> </span> </div> </div> </div> <div class="q-block"> <div class="title">質問2(3つまで選択できます。)</div> <div class="checkbox-group js-check-limited"> <div class="checkbox-group__item"> <span class="checkbox-field"> <label> <input type="checkbox" name="test" class="js-check-item"> <span>選択肢6</span> </label> </span> </div> <div class="checkbox-group__item"> <span class="checkbox-field"> <label> <input type="checkbox" name="test" class="js-check-item"> <span>選択肢7</span> </label> </span> </div> <div class="checkbox-group__item"> <span class="checkbox-field"> <label> <input type="checkbox" name="test" class="js-check-item"> <span>選択肢8</span> </label> </span> </div> <div class="checkbox-group__item"> <span class="checkbox-field"> <label> <input type="checkbox" name="test" class="js-check-item"> <span>選択肢9</span> </label> </span> </div> <div class="checkbox-group__item"> <span class="checkbox-field"> <label> <input type="checkbox" name="test" class="js-check-item"> <span>選択肢10</span> </label> </span> </div> <div class="checkbox-group__item"> <span class="checkbox-field"> <label> <input type="checkbox" name="test" class="js-check-item"> <span>選択肢11</span> </label> </span> </div> </div> </div>

【javascript】

const checkMax = 3; const checkBoxes = document.querySelectorAll('.js-check-item'); function checkCount(target) { let checkCount = 0; checkBoxes.forEach(checkBox => { if (checkBox.checked) { checkCount++; } }); if (checkCount > checkMax) { alert('最大3つまで'); target.checked = false; } } checkBoxes.forEach(checkBox => { checkBox.addEventListener('change', () => { checkCount(checkBox); }) });

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ちょっと勝手に拡張してこんな感じで

javascript

1<script> 2let jsCheckItemChecked; 3document.addEventListener('click', e=>{ 4 const t=e.target; 5 if(t.matches('.js-check-item')){ 6 const p=t.closest('[data-limit]'); 7 const flg=p.querySelectorAll('.js-check-item:checked').length>=p.dataset.limit; 8 p.querySelectorAll('.js-check-item:not(:checked)').forEach(x=>x.disabled=flg); 9 jsCheckItemChecked=[...document.querySelectorAll('.js-check-item')].map(x=>x.checked); 10 localStorage.jsCheckItemChecked=JSON.stringify(jsCheckItemChecked); 11 } 12}); 13const nav=performance.getEntriesByType("navigation")[0].type; 14window.addEventListener('DOMContentLoaded', ()=>{ 15 if(nav=="reload"){ 16 jsCheckItemChecked=JSON.parse(localStorage.jsCheckItemChecked??"[]"); 17 document.querySelectorAll('.js-check-item').forEach((x,y)=>x.checked=jsCheckItemChecked[y]); 18 const ce = new CustomEvent("HTMLEvents"); 19 ce.initEvent('click', true, true ); 20 document.querySelectorAll('[data-limit]').forEach(x=>x.querySelector('.js-check-item').dispatchEvent(ce)); 21 } 22}); 23</script> 24<div class="q-block"> 25 <div class="title">質問13つまで選択できます。)</div> 26 <div class="checkbox-group js-check-limited" data-limit="3"> 27 <div class="checkbox-group__item"> 28 <span class="checkbox-field"> 29 <label> 30 <input type="checkbox" name="test" class="js-check-item"> 31 <span>選択肢1</span> 32 </label> 33 </span> 34 </div> 35 <div class="checkbox-group__item"> 36 <span class="checkbox-field"> 37 <label> 38 <input type="checkbox" name="test" class="js-check-item"> 39 <span>選択肢2</span> 40 </label> 41 </span> 42 </div> 43 <div class="checkbox-group__item"> 44 <span class="checkbox-field"> 45 <label> 46 <input type="checkbox" name="test" class="js-check-item"> 47 <span>選択肢3</span> 48 </label> 49 </span> 50 </div> 51 <div class="checkbox-group__item"> 52 <span class="checkbox-field"> 53 <label> 54 <input type="checkbox" name="test" class="js-check-item"> 55 <span>選択肢4</span> 56 </label> 57 </span> 58 </div> 59 <div class="checkbox-group__item"> 60 <span class="checkbox-field"> 61 <label> 62 <input type="checkbox" name="test" class="js-check-item"> 63 <span>選択肢5</span> 64 </label> 65 </span> 66 </div> 67 <div class="checkbox-group__item"> 68 <span class="checkbox-field"> 69 <label> 70 <input type="checkbox" name="test" class="js-check-item"> 71 <span>選択肢6</span> 72 </label> 73 </span> 74 </div> 75 </div> 76</div> 77 78<div class="q-block"> 79 <div class="title">質問23つまで選択できます。)</div> 80 <div class="checkbox-group js-check-limited" data-limit="3"> 81 <div class="checkbox-group__item"> 82 <span class="checkbox-field"> 83 <label> 84 <input type="checkbox" name="test" class="js-check-item"> 85 <span>選択肢6</span> 86 </label> 87 </span> 88 </div> 89 <div class="checkbox-group__item"> 90 <span class="checkbox-field"> 91 <label> 92 <input type="checkbox" name="test" class="js-check-item"> 93 <span>選択肢7</span> 94 </label> 95 </span> 96 </div> 97 <div class="checkbox-group__item"> 98 <span class="checkbox-field"> 99 <label> 100 <input type="checkbox" name="test" class="js-check-item"> 101 <span>選択肢8</span> 102 </label> 103 </span> 104 </div> 105 <div class="checkbox-group__item"> 106 <span class="checkbox-field"> 107 <label> 108 <input type="checkbox" name="test" class="js-check-item"> 109 <span>選択肢9</span> 110 </label> 111 </span> 112 </div> 113 <div class="checkbox-group__item"> 114 <span class="checkbox-field"> 115 <label> 116 <input type="checkbox" name="test" class="js-check-item"> 117 <span>選択肢10</span> 118 </label> 119 </span> 120 </div> 121 <div class="checkbox-group__item"> 122 <span class="checkbox-field"> 123 <label> 124 <input type="checkbox" name="test" class="js-check-item"> 125 <span>選択肢11</span> 126 </label> 127 </span> 128 </div> 129 </div> 130</div>

参考

limitを超えたらalert

javascript

1let jsCheckItemChecked; 2document.addEventListener('click', e=>{ 3 const t=e.target; 4 if(t.matches('.js-check-item')){ 5 const p=t.closest('[data-limit]'); 6 const flg=p.querySelectorAll('.js-check-item:checked').length>=p.dataset.limit; 7 if(p.dataset.limit<p.querySelectorAll('.js-check-item:checked').length){ 8 alert(`${p.dataset.limit}個まで`); 9 e.preventDefault(); 10 }else{ 11 jsCheckItemChecked=[...document.querySelectorAll('.js-check-item')].map(x=>x.checked); 12 localStorage.jsCheckItemChecked=JSON.stringify(jsCheckItemChecked); 13 } 14 } 15}); 16const nav=performance.getEntriesByType("navigation")[0].type; 17window.addEventListener('DOMContentLoaded', ()=>{ 18 if(nav=="reload"){ 19 jsCheckItemChecked=JSON.parse(localStorage.jsCheckItemChecked??"[]"); 20 document.querySelectorAll('.js-check-item').forEach((x,y)=>x.checked=jsCheckItemChecked[y]); 21 } 22});

投稿2023/01/30 04:16

編集2023/01/30 05:26
yambejp

総合スコア114829

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ibis_masuda

2023/01/30 04:33

yambejp様 コメントありがとうございます。 こちらで気持ちよく、実装できました!! とても助かりました。 ありがとうございます。
ibis_masuda

2023/01/30 05:09

ちなみにこちらは、alertを出したいときはどうしたらよろしいでしょうか…。
yambejp

2023/01/30 05:27 編集

> alertを出したいとき 他のチェックボックスをdisableにしているのでalertはでませんね disableされたチェックボックスはさわれないので。 disabledをやめてサワれるけどチェックできないというUIを希望でしょうか? それは感覚的にあまり良い方法だとは思えませんが? (参考データを追記しておきました)
ibis_masuda

2023/01/30 05:56

ご回答いただきありがとうございます。 さわれないことで選択できないということがわかれば、確かにalartは、不要かもしれないですね。 どのようなユーザーが使うかを想定して、どちらにするか決めたいと思います。 参考データもありがとうございます。 本当に助かりました!!! このような初歩的な内容にもかかわらずご丁寧に迅速にお答えいただき本当に感謝いたします。
guest

0

ベストアンサー

まず、質問1と質問2つのチェックボックスを区別できるようにしましょう。現在のコードではすべて name="test" となってますが、たとえば「質問1のチェックボックスは name="test1"、質問2のチェックボックスは name="test2"」とします。

JavaScriptのコードでは、target.name と同じname属性を持ったチェックボックスに限定して集計しましょう。

let checkCount = document.querySelectorAll(`.js-check-item[name="${target.name}"]:checked`).length;

投稿2023/01/30 03:24

int32_t

総合スコア20872

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ibis_masuda

2023/01/30 04:37

int32_t様 コメントありがとございます。 nameの値を質問ごとにそろえ、上記の通り記述してみたのですが思うような動きにならないようでした。 こちらもスマートに実装できそうな感じを受けましたが、私の理解が乏しく原因がわかりません…。 お時間がよろしければまたご教示いただけますと幸いです。 本当に勉強になり、感謝いたします。 ありがとうございます!
int32_t

2023/01/30 04:40 編集

回答の1行で「let checkCount = 0;」を置き換えます。 変数 checkBoxes の宣言や checkBoxes.forEach(...); はまるごと不要です。 もしこの指摘が的外れでしたら、現状のコードを見せていただければ助言できると思います。
ibis_masuda

2023/01/30 05:26

ご確認ありがとうございます。 現状のコードは以下の通りでございます。 const checkMax = 3; function checkCount(target) { let checkCount = document.querySelectorAll(`.js-check-item[name="${target.name}"]:checked`).length; if (checkCount > checkMax) { alert('最大3つまで'); target.checked = false; } } お手数をお掛けいたしますが、よろしければご確認いただけますと幸いです。 よろしくお願いいたします。
int32_t

2023/01/30 05:59

おっと、失礼しました。 addEventListener() の方のループは必要でしたね。変数 checkBoxes の宣言と checkCount() の外の checkBoxes.forEach() は戻してください。
ibis_masuda

2023/01/30 09:48

int32_t様 ありがとうございます! とても短くて、すっきり分かりやすいコードで実装できました! お時間いただき、ご回答いただきまして本当にありがとうございます!!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問