回答受付が終了しました

htmlのチェックボックスについて質問です。

HTML、CSS | JavaScript167閲覧xmlns="http://www.w3.org/2000/svg">50

回答(2件)

0

■■■ 基本的な間違い ■■■ id, class 属性には、 ──────────────── ・使える文字は、半角英数字、ハイフン(-)、アンダーバー(_) ・先頭の文字は必ず半角アルファベット ──────────────── という命名規則があるんで、 id=10 のような id 属性の指定方法はNG。 どうしても、 要素に数値のマークを付けたい場合は、 ──────────────── <input type="checkbox" data-id="10"> ──────────────── のようにカスタムデータ属性を使う。 [ 参考:id, class の命名規則 ] https://html-coding.co.jp/knowhow/tips/naming-rule/ ■■■ 実施例 ■■■ コードが長くなるんで、 実施例を jsfiddle に上げておいた。 [ jsfiddle ] https://jsfiddle.net/Lkfp5y0t/ ■■■ ページ読み込み完了時に実行 ■■■ スクリプト内で <table> 要素を参照するんで、 <table> 要素が読み込まれる前に実行するとエラーになる。 <table> より後方に <script> タグを置いて、 そこにスクリプトを記述するのであれば問題ないが、 スクリプトの記述位置、読み込み位置が任意の場合は、 ページ読み込みが完了したとき(DOMContentLoaded)に実行する。 ──────────────── window.addEventListener( "DOMContentLoaded", ()=> { … 実行するスクリプト … }, false ) ──────────────── ■■■ テーブル要素を取得 ■■■ まず、 処理の対象である <table> 要素を変数に取得しておく。 querySelector() でも取得できるけど、 getElementsByTagName() の方が軽くて速い。 ──────────────── const table = document.getElementsByTagName( "table" ); ──────────────── ■■■ <input> 要素を取得 ■■■ 「あ:まとめ」~「う:まとめ」の <input> 要素リストを matomeRow とすると、 テーブルの最終行より前「 tr:not(:last-of-type) 」の 先頭のセル「 td:first-of-type 」にある「 input 」 要素だから、 ──────────────── const matomeRow = document.querySelectorAll( "tr:not( :nth-last-of-type ) td:first-of-type input" ); ──────────────── 「1:まとめ」~「4:まとめ」の <input> 要素リストを matomeCol とすると、 テーブルの最終行「 tr:last-of-type 」の 先頭セル以降「 td:not(:first-of-type) 」にある「 input 」要素だから、 ──────────────── const matomeCol = document.querySelectorAll( "tr:last-of-type td:not( :first-of-type ) input" ); ──────────────── 「全選択」の <input> 要素を matomeAll とすると、 テーブルの最終行「 tr:last-of-type 」の先頭セル「 td:first-of-type 」 にある「 input 」だから、 ──────────────── const matomeAll = document.querySelector( "tr:last-of-type td:first-of-type input" ); ──────────────── まとめ以外の <input> 要素リストを singleInput とすると、 テーブルの最終行より前「 tr:not(:last-of-type) 」の 先頭セル以降「 td:not(:first-of-type) 」にある「 input 」だから ──────────────── const singleInput = table.querySelectorAll( "tr:not( :last-of-type ) td:not( :first-of-type ) input" ); ──────────────── でそれぞれ取得できる。 各 <input> 要素のリストに対しては、 実行するスクリプトのなかで度々ループ処理を使うことになるから、 forEach() など配列のループ関数を使えるように、 Array.from() で配列化しておく。 ──────────────── //----] まとめ(行) const matomeRow = Array.from( table.querySelectorAll( "tr:not( :last-of-type ) td:first-of-type input" ) ); //----] まとめ(列) const matomeCol = Array.from( table.querySelectorAll( "tr:last-of-type td:not( :first-of-type ) input" ) ); //----] まとめ(全) const matomeAll = table.querySelector( "tr:last-of-type td:first-of-type input" ); //----] まとめ以外 const singleInput = Array.from( table.querySelectorAll( "tr:not( :last-of-type ) td:not( :first-of-type ) input" ) ); ──────────────── これらの <input> 要素に対して、 クリックしたときのイベントリスナーを登録していく。 ■■■ 関数:まとめ <input> を更新 ■■■ まとめの <input> 要素をクリックしたときは、 それと同じ行/列、または全部の <input> にチェックを入れるが、 逆に、 単独の <input> 要素をクリックしたときに、 それと同じ行/列、または全部の <input> のチェック状態に応じて、 対応するまとめの <input> のチェック状態を更新する必要がある。 単独の <input> 要素のチェック状態に応じて、 各まとめの <input> のチェック状態を更新する関数を updateCheck() として作成する。 ─[ ※1 ]─────────── function updateCheck() { ~ 各まとめ <input> のチェック状態を更新 ~ } ──────────────── >> 返信へつづく

【 まとめ(行)の更新 】 「行」まとめの <input> 要素は、 同じ行にある <input> すべてにチェックが入っていればチェック、 1つでもチェックなしの <input> があればチェックを外す。 この処理を、 matomeRow のリスト内の要素1つ1つに対して実行する。 ─[ ※2 ]─────────── matomeRow.forEach( matome => { ~ } ); ──────────────── 各「行」まとめ要素 matome のチェック状態 checked は、 同じ行の <input> すべてにチェックが入っていれば true; 1つでもチェックが入っていなければ false にする。

0

idが規則的に割り振られているので、チェックボックスをid指定して変更するのが一番簡単でしょう。 3,4分で書いたので間違いあるかもしれません。 変なところがあったら誰か指摘してくれるでしょう(丸投げゴメン)。 <script> // めとめ変更 function changeMatome() { const id = this.matome.id; const checked = this.matome.checked; if (id == 10) { // 「あ」まとめ changeCheck([11, 12, 13, 14], checked); } else if (id == 41) { // 「1」まとめ changeCheck([11, 21, 31], checked); } } // チェックボックスのon/off function changeCheck(ids, checked) { ids.map(function(id) { let element = document.querySelector('td input[id="' + id +'"]'); element.checked = checked; }); } // チェックボックス変更 const matomes = document.querySelectorAll('td input[type="checkbox"]'); Array.prototype.map.call(matomes, function(matome, index) { matome.addEventListener('change', {matome: matome, handleEvent: changeMatome}); }); </script>

ありがとうございます!!!ちゃんと動きました。 これを2~3分で書き上げるって本当にすごいです。 このシンプルのなものだと動くのですが、実際にはphp変数を活用してます。 実際コードを確認してちょっと加工すれば行けるかなと思いましたが、javascriptの壁は厚かったです。。。 よろしければ以下の場合はどうなるのか教えてもらえませんか?<table border="1"> <?php $y=['2021','2022','2023','2024','0'];$x=['0','1','2','3'] ?> <?php for ($iy = 0; $iy < count($y); $iy++) {?> <tr><?php for ($ix = 0; $ix < count($x); $ix++) { ?>