[HTML] テーブルの行をクリックしたら色を変更する [radio, checkbox対応]

2021年12月9日木曜日

Web

本記事では、テーブルの行をクリックした際に、行の背景色や文字色を変更する方法をご紹介します。さらに行をクリックした際にラジオボタンなどのチェック状態を変更する方法も併せてご紹介します。

アイキャッチ

概要

はじめに、テーブルの行をクリックしたくなるケースを紹介します。 下記のようなラジオボタンやチェックボックスのように、テーブルに羅列された情報を選択したいようなケースがあるとします。

テーブル例

このようなUIを提供したい場合テーブルの行がクリックできないと、ユーザーはラジオボタンの選択範囲を正確に押す必要が発生します。なかなか選択範囲が小さく押しにくいですね。

選択範囲が小さく操作性の悪いテーブル例

こういった際に、行ごと選択範囲にしてクリックできると嬉しいですね。

行クリック可能なテーブル

早速本題の行クリック可能なテーブルの実装例をご紹介します。

See the Pen table_row_select by kaz12 Tech (@kaz12-Tech) on CodePen.

上記が行クリックが可能なテーブルの実装例です。

こちらは、行のクリックに対応して、行の背景色の変更行の文字色の変更ラジオボタンのチェックを行っています。先ほどのテーブルと異なり、選択範囲がラジオボタンから行全体に拡張されるため操作性が向上していますね。

また上記の実装例の内、CSSはテーブルのデザインを定義しているのみですので無視していただいて構いません。
大事な点はJavascriptの制御となります。

実装の解説

Javascriptの実装内容を解説していきます。

function preloader() {
  let table = document.getElementById("target-table");
  let rows = table.querySelectorAll("tbody tr");

  let backgroundcolor_dict = {};
  let tr_color = window.getComputedStyle(rows[0], "").color;

  rows.forEach((row) => {
    // 行ごとに背景色が異なるため全ての行の変更前の背景色を取得
    backgroundcolor_dict[String(row.rowIndex)] = window.getComputedStyle(
      row,
      ""
    ).backgroundColor;

    row.addEventListener(
      "click",
      function () {
        // 一度全て元の配色
        rows.forEach((click_row) => {
          click_row.style.backgroundColor =
            backgroundcolor_dict[String(row.rowIndex)];
          click_row.style.color = tr_color;
        });
        // 選択された行のみ配色変更
        row.style.backgroundColor = "#0A9BCD";
        row.style.color = "#FFFFFF";

        if (row.querySelector("input").type == "radio") {
          row.querySelector('input[type="radio"]').checked = true;
        }
        if (row.querySelector("input").type == "checkbox") {
          if (row.querySelector('input[type="checkbox"]').checked == false) {
            row.querySelector('input[type="checkbox"]').checked = true;
          } else {
            row.querySelector('input[type="checkbox"]').checked = false;
          }
        }
      },
      false
    );
  });
}

window.onload = preloader;

いきなりコード全てを記載しましたがそれほど複雑ではありません。
一つ一つ順を追ってみていきます。

window.onload = preloader;

上記のコードで、リソースの読み込みが完了した際にpreloader関数が呼び出されるように登録しています。
続いて、preloader関数の処理の中身を見ていきます

  // target-table内の全てのtbody trを取得
  let table = document.getElementById("target-table");
  let rows = table.querySelectorAll("tbody tr");
  // 選択前の背景色を記憶しておくdict
  let backgroundcolor_dict = {};
  // 選択前の文字色を取得
  let tr_color = window.getComputedStyle(rows[0], "").color;

上記のコードで、対象となるテーブルからtbody tr要素を取得した後に、 選択前の背景色のdictの定義、文字色を取得しています。

背景色がdictになっている理由ですが、これは行ごとに背景色が異なるテーブルに対応するためです。

前述のテーブルのように背景色が2色になっているケースも多く、3色以上のパターンも少なくないため、選択前に、 全ての行の背景色を記憶しておいてしまいます。

それが以下の処理です。

    // 行ごとに背景色が異なるため全ての行の変更前の背景色を取得
    backgroundcolor_dict[String(row.rowIndex)] = window.getComputedStyle(
      row,
      ""
    ).backgroundColor;

以上までが、選択される前のお膳立てですね。

最後に、クリックされた場合の振る舞いを定義します。

row.addEventListener(
      "click",
      function () {
        // 一度全て元の配色
        rows.forEach((click_row) => {
          click_row.style.backgroundColor =
            backgroundcolor_dict[String(row.rowIndex)];
          click_row.style.color = tr_color;
        });
        // 選択された行のみ配色変更
        row.style.backgroundColor = "#0A9BCD";
        row.style.color = "#FFFFFF";

        if (row.querySelector("input").type == "radio") {
          row.querySelector('input[type="radio"]').checked = true;
        }
        if (row.querySelector("input").type == "checkbox") {
          if (row.querySelector('input[type="checkbox"]').checked == false) {
            row.querySelector('input[type="checkbox"]').checked = true;
          } else {
            row.querySelector('input[type="checkbox"]').checked = false;
          }
        }
      },
      false
    );

行ごとにクリック時のイベントリスナーを登録しておきます。

そして行がクリックされた際に、クリックされた行の色を変更する前に、全ての行の色を事前に元に戻します。
この処理を入れておかないと、一度クリックされた行は変更後の配色から元に戻らなくなってしまいます。

その後、クリックされた行のみ配色変更し、radioボタンやチェックボックスのチェック状態を変更しています。

まとめ

本記事では、テーブルの行をクリックした際に配色を変更する方法をご紹介しました。
操作性を向上させるため、このような機能があるとシステムの印象がぐっと良くなりますね。

また、Webの知識はWebで得ることが多く、知識が散逸的になりがちです。
一度以下の書籍などで体系立てて知識を得られるとしっかりとした土台ができるのでお勧めです。

AIで副業ならココから!

まずは無料会員登録

プロフィール

メーカーで研究開発を行う現役エンジニア
組み込み機器開発や機会学習モデル開発に従事しています

本ブログでは最新AI技術を中心にソースコード付きでご紹介します


Twitter

カテゴリ

このブログを検索

ブログ アーカイブ

TeDokology