カテゴリー
IT programming wordpress

TablePressのセルの値によって背景の色を動的に変える方法

wordpressのプラグインTablePressにて、セルの値に応じて、動的にセルの色を変える方法について考えます。

目的と背景

https://1-10000th.com/how-to-change-color-of-html-table/

上記の記事は、HTMLのテーブルのセルの値によって背景の色を動的に変える方法(特にセル内の順位付け)についてのものですが、当該記事にて下記のコメントをいただきましたので、実際にこのブログ(wordpress)内で試してみます。

はじめまして。

ワードプレスでTablePressというプラグインを使っているのですが、記事のようにセルの背景を動的に変えたいのですが、可能でしょうか?

具体的には入力した数字の範囲(40〜50は赤、51〜60は青といった具合です。)で、指定した色が自動で振り分けられるようにしたいです。

wordpressにおけるTablePressのCSSセレクタの確認

まずはTablePressをプラグインで検索してインストール。その後、TablePressで適当にテーブルを作って記事に張り付けたのが以下です。

ABCDE
23423431433234
234343-2
0432-33
132232242
233232424
44353344
gd3243242432
dfg434a
443454
434234d52

このテーブルをブラウザのデベロッパーツールで確認しますと、tableタグのIDは”tablepress-1“(ハイフン以降の数字はTablePressのテーブルIDだと思われます)、そして1列目に”column-1“、2列目に”column-2“などが入るようです。

セルの値の順位にで背景に色をつけるjavascriptの実装

それでは、このテーブルの情報がわかりましたので、Javascriptを適用します。

TablePressのすぐ下に「カスタムHTML」に下記のコードを入力して挿入します。以前の記事からの変更点は、最後の列のセレクタ名(#tablepress-1 .column-1の部分)だけです。

<script>
// tableに色を塗る
    function setcolor(classname) {
      var rank = $(classname);

      var arr = [];
      $.each(rank, function(_, v) {
        var num = parseFloat($(v).text());
        if (num) {
          arr.push(num);
        }
      });

      // 一番大きい
      var first = Math.max.apply(Math, arr);

      // 一番大きいのを配列から削除
      arr = arr.filter(function(x) {
        return x != first
      });

      // 2番目に大きい
      var second = Math.max.apply(Math, arr);

      // 2番大きいのを配列から削除
      arr = arr.filter(function(x) {
        return x != second
      });

      // 3番目に大きい
      var third = Math.max.apply(Math, arr);

      // 3番大きいのを配列から削除
      arr = arr.filter(function(x) {
        return x != third
      });

      // 4番目に大きい
      var fourth = Math.max.apply(Math, arr);

      // CSSをつける
      $.each(rank, function(_, v) {
        var num = parseFloat($(v).text());
        if (num == first) $(v).css('background-color', '#FFC0CB');
        if (num == second) $(v).css('background-color', '#FFCC99');
        if (num == third) $(v).css('background-color', '#C0F0FF');
        if (num == fourth) $(v).css('background-color', '#E6E6FA');
      });
    }

    setcolor("#tablepress-1 .column-1"); // テーブルの列のCSS(1列目)
    setcolor("#tablepress-1 .column-2"); // テーブルの列のCSS(2列目)
    setcolor("#tablepress-1 .column-3"); // テーブルの列のCSS(3列目)
    setcolor("#tablepress-1 .column-4"); // テーブルの列のCSS(4列目)
    setcolor("#tablepress-1 .column-5"); // テーブルの列のCSS(5列目)
</script>

そしてプレビューしますと下記のようになりきちんとCSSが反映されています。

ABCDE
23423431433234
234343-2
0432-33
132232242
233232424
44353344
gd3243242432
dfg434a
443454
434234d52

最近(?)のwordpressでは、カスタムHTML等でコードっぽいのを記入する際に、勝手に「&」や「<」みたいな特殊文字を「&lt;」や「&amp;」に変換してしまうようです。これではコードを正確に読み込んでくれませんので、なんとかする必要があります。今回も、なぜかnum = 50 は動くのに、num < 50にすると何故か動かなくなり、結構悩みました。

解決方法の詳細は私は詳しくはGoogle先生で「wordpress 特殊文字 変換させない」あたりで検索してください。

私は、テーマのfunctions.php(テーマエディターから)に

add_filter( "run_wptexturize", "__return_false" );

と書いたら無駄に変換されなくなりました。自己責任で。

セルの値によって背景に色をつけるjavascriptの実装

ご質問のような、ランクによる色付けでなく、単に値による色付けであればより簡単で、セルの値をループする際に、if文でCSSをつけてあげればOKです。

下記がサンプルコードです。関数名が上とかぶらないようにsetcolor2にしています。同じようにTablePressのすぐ下に「カスタムHTML」に下記のコードを入力して挿入。

<script>
// tableに色を塗る
    function setcolor2(classname) {
      var rank = $(classname);

      // CSSをつける
      $.each(rank, function(_, v) {
        var num = parseFloat($(v).text());
        if (40 <= num && num < 50) $(v).css('background-color', '#FFC0CB');
        if (50 <= num && num < 60) $(v).css('background-color', '#FFCC99');
      });
    }

    setcolor2("#tablepress-1 .column-1"); // テーブルの列のCSS(1列目)
    setcolor2("#tablepress-1 .column-2"); // テーブルの列のCSS(2列目)
    setcolor2("#tablepress-1 .column-3"); // テーブルの列のCSS(3列目)
    setcolor2("#tablepress-1 .column-4"); // テーブルの列のCSS(4列目)
    setcolor2("#tablepress-1 .column-5"); // テーブルの列のCSS(5列目)
</script>

結果以下のような感じ(40~50、50~60で分岐)。

ABCDE
23423431433234
234343-2
0432-33
132232242
233232424
44353344
gd3243242432
dfg434a
443454
434234d52

課題

今回の手法は、テーブルが静的である場合に限り有効です。何らかのタイミングでテーブルが更新される場合、javascriptの実行を再度行わないといけないことに注意です。

そういう意味も含めて、TablePressは今回初めて使いましたので、実は何か他のより良い方法があるかもしれません。特に、TablePressはdatatablesと連携が取れるようなプラグインっぽいので、例えばdatatablesのdrawcallbackのようなことが実装できれば、動的なテーブルにも応用できるかとは思います(でも https://datatables.net/forums/discussion/57707/use-datatables-in-tablepress-to-create-sports-cup-standings のコメントによればできないっぽいかな?)。