LoginSignup
0
3

More than 1 year has passed since last update.

【class属性でソート】JavaScriptを使ってクラス名だけでテーブルをソートする方法

Last updated at Posted at 2022-09-04

需要無い方法だったら脱ぎます。

2023-02-15 追記
脱ぎました。

2023-02-15 追記
この記事に頂いたコメントをお読みください。そちらの方がすごく使い勝手がいいです。
コメントしていただきありがとうございます!!

目次

1.やること
2.この方法を使うメリット・デメリット
3.前提
4.ソートするテーブル
5.解説
6.終わりに

1. やること

1662235838268.gif
色が揃うの気持ち良すぎだろ

2. この方法を使うメリット・デメリット

メリット

・テーブルの中身が何であろうと、データを好きなようにソートできる
 →クラス名でソートするのでテーブルの中身は関係なしに自由にソートができるってワケ。

・DOMをそのまま並び替えるだけなのでデータベースを通さない
 →爆速ソートができる
・文字コードや数字の大小に影響されずにソートできる

デメリット

・ページネーションには対応できない
・たぶん小規模開発向き
・ソートが一方通行(ソートを元に戻す処理を実装する必要あり)
・実用的なのか分からない

3. 前提

生のJavaScriptを使用しています。
Reactでも同じことができると思います。(この方法が必要かどうかはさておき)

4. ソートするテーブル

テーブル

英語長文の教材一覧を使っていきます。

こちらのテーブルを「教材レベル(上から基礎→標準→応用→発展の順)」でソートをします。

1662227159367.jpg

テーブルのHTML

<table>
    <thead>
        <tr>
            <th class="title-name">教材名</th>
            <th class="number-of-units">単元数</th>
            <th class="textboook-level" onclick="sortTableByLevel()">▼ 教材レベル</th>
        </tr>
    </thead>
<tbody id="textbook-list">
    <tr class="table-row 1" id="yatteokitai300">
        <td class="table__title">やっておきたい英語長文300</td>
        <td class="table__content-num">15</td>
        <td class="table__level level-1">基礎</td>
    </tr>
    <tr class="table-row 2" id="yetteokitai500">
        <td class="table__title">やっておきたい英語長文500</td>
        <td class="table__content-num">20</td>
        <td class="table__level level-2">標準</td>
    </tr>
    <tr class="table-row 3" id="yetteokitai700">
        <td class="table__title">やっておきたい英語長文700</td>
        <td class="table__content-num">15</td>
        <td class="table__level level-3">応用</td>
    </tr>
    <tr class="table-row 4" id="yetteokitai1000">
        <td class="table__title">やっておきたい英語長文1000</td>
        <td class="table__content-num">10</td>
        <td class="table__level level-4">発展</td>
    </tr>
    <tr class="table-row 1" id="s-lv-1">
        <td class="table__title">英語長文レベル別問題集① 超基礎編</td>
        <td class="table__content-num">12</td>
        <td class="table__level level-1">基礎</td>
    </tr>
    <tr class="table-row 1" id="s-lv-2">
        <td class="table__title">英語長文レベル別問題集② 基礎編</td>
        <td class="table__content-num">12</td>
        <td class="table__level level-1">基礎</td>
    </tr>
    <tr class="table-row 2" id="s-lv-3">
        <td class="table__title">英語長文レベル別問題集③ 標準編</td>
        <td class="table__content-num">12</td>
        <td class="table__level level-2">標準</td>
    </tr>
    <tr class="table-row 3" id="s-lv-4">
        <td class="table__title">英語長文レベル別問題集④ 中級編</td>
        <td class="table__content-num">12</td>
        <td class="table__level level-3">応用</td>
    </tr>
    <tr class="table-row 3" id="s-lv-5">
        <td class="table__title">英語長文レベル別問題集⑤ 上級編</td>
        <td class="table__content-num">12</td>
        <td class="table__level level-3">応用</td>
    </tr>
    <tr class="table-row 4" id="s-lv-6">
        <td class="table__title">英語長文レベル別問題集⑥ 難関編</td>
        <td class="table__content-num">10</td>
        <td class="table__level level-4">発展</td>
    </tr>
    <tr class="table-row 1" id="hypertraning-s1">
        <td class="table__title">英語長文ハイパートレーニング レベル1 超基礎編</td>
        <td class="table__content-num">12</td>
        <td class="table__level level-1">基礎</td>
    </tr>
    <tr class="table-row 2" id="hypertraning-s2">
        <td class="table__title">英語長文ハイパートレーニング レベル2 標準編</td>
        <td class="table__content-num">12</td>
        <td class="table__level level-2">標準</td>
    </tr>
    <tr class="table-row 3" id="hypertraning-s3">
        <td class="table__title">英語長文ハイパートレーニング レベル3 難関編</td>
        <td class="table__content-num">12</td>
        <td class="table__level level-3">応用</td>
    </tr>
    <tr class="table-row 1" id="kawai-basic">
        <td class="table__title">マーク式基礎問題集 英語 基礎</td>
        <td class="table__content-num">10</td>
        <td class="table__level level-1">基礎</td>
    </tr>
    <tr class="table-row 3" id="kawai-application">
        <td class="table__title">マーク式基礎問題集 英語 応用</td>
        <td class="table__content-num">10</td>
        <td class="table__level level-3">応用</td>
    </tr>
</tbody>
</table>

それでは、このテーブル及びHTMLを使用して手順を説明していきます。

5. 解説

あらかじめ、tr要素のクラス名に付けておいた1~4の数字を使ってソートしていきます。

各数字は「1: 基礎 2: 標準 3: 応用 4: 発展」に対応しています

↓ 上記のコードで言うところのコレです(緑色のとこ)

<tbody id="textbook-list">
    // classに付いてる数字をソートに使用します。 
+   <tr class="table-row 1" id="yatteokitai300">                      // 1
        <td class="table__title">やっておきたい英語長文300</td>
        <td class="table__content-num">15</td>
        <td class="table__level level-1">基礎</td>
    </tr>
+       <tr class="table-row 2" id="yetteokitai500">                  // 2
        <td class="table__title">やっておきたい英語長文500</td>
        <td class="table__content-num">20</td>
        <td class="table__level level-2">標準</td>
    </tr>
+   <tr class="table-row 3" id="yetteokitai700">                      // 3
        <td class="table__title">やっておきたい英語長文700</td>
        <td class="table__content-num">15</td>
        <td class="table__level level-3">応用</td>
    </tr>
+   <tr class="table-row 4" id="yetteokitai1000">                     // 4
        <td class="table__title">やっておきたい英語長文1000</td>
        <td class="table__content-num">10</td>
        <td class="table__level level-4">発展</td>
    </tr>
+   <tr class="table-row 1" id="s-lv-1">                              // 1
        <td class="table__title">英語長文レベル別問題集① 超基礎編</td>
        <td class="table__content-num">12</td>

                        ・
                        ・
                        ・

この数字はテーブルを生成する際に付与しました。

どう付与する?
今回はデータベースに数字で保存している「教材レベル」をそのままclassList.add()でクラス名に付与しました。

ソートをする(図解)

どうやってクラス名だけでソートするかを図解します。

①ソート前のtr要素をすべて取得する

今回は getElementsByClassName('table-row') で取得しました。
1662233201834.jpg

②tr要素をクラス名ごとに配列に入れる

クラス名に付いてる1,2,3,4の数字ごとに分けていきます。
1662233225675.jpg

③分けた配列を一つの配列にし、①で取得したテーブルに入れる

クラス名で分けたtr要素を一つの配列にします。
1662236445826.jpg

これで完成です。

それを実装したコードがこちら

//   難易度でのソート機能
function sortTableByLevel() {
    // テーブルを取得
  const table = document.getElementById("textbook-list");

    // テーブル内のtr要素を全て取得する
  const tr_elements = table.getElementsByClassName("table-row");

    // Array.prototype.slice.callで配列にする。
  const before_sorted_array = Array.prototype.slice.call(tr_elements);

  let array1 = [];  // 基礎(class名に 1 が付いたtr要素)を入れる配列
  let array2 = [];  // 標準(class名に 2 が付いたtr要素)を入れる配列
  let array3 = [];  // 応用(class名に 3 が付いたtr要素)を入れる配列
  let array4 = [];  // 発展(class名に 4 が付いたtr要素)を入れる配列

    // 一つずつtr要素を取り出して、クラス名に1,2,3,4のどれが含まれているかで条件分岐
  before_sorted_array.map((item) => {
    if (item.classList.contains("1")) {
      array1.push(item);
    } else if (item.classList.contains("2")) {
      array2.push(item);
    } else if (item.classList.contains("3")) {
      array3.push(item);
    } else if (item.classList.contains("4")) {
      array4.push(item);
    }
  });

    // array1にarray2, array3, array4の順で合体させてソートが終了
  const after_sorted_array = array1.concat(array2, array3, array4);

    // ソート前のテーブルをすべて削除してテーブルを空っぽにする
  while (table.firstChild) {
    table.removeChild(table.firstChild);
  }
    // 空っぽのテーブルにソートしたtr要素をテーブルにぶち込む
  after_sorted_array.forEach((item) => {
    table.appendChild(item);
  });

}

もう一度ソートをクリックしても元には戻りません。
元の並びを変数に入れたりなんなりしたら元に戻すことも実装できそうです。

終わりです。

class名でソートをすれば、どんなデータでも簡単(?)にお好みのソートができます。
クラス名でなくてもnameやidでも同じことができそうですし、if文の分岐を工夫すれば、クラス名は数字じゃなくても実装できそうです。

6. 終わりに

図解にある after_sorted_array って変数名おかしい。
array_after_sort(ソート後の配列)の方がしっくりきますねー。おーん。

0
3
4

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
0
3