【WordPressも対応】htmlのテーブル表でヘッダ行や列の固定、並び替えをする【DataTables】
htmlの表テーブルでヘッダ行や列の固定、並び替えをする
htmlでテーブル表は説明をわかりやすくするためにとっても便利です。
ただ、行や列を多く含む場合にはスマホで見にくかったり、ヘッダが固定されていないので「今どの列見てるんだっけ?」など困ったりすることも多いです。
そんな時、こんな表があったら便利ではないでしょうか?
まずはデモを用意してみたので下記のテーブルを見てみて下さい。
こんな感じのテーブル表を作れます!(サンプルデモ)
拡張テーブルサンプルデモ
※キーワード検索で表示の絞り込みが可能
※最初の行を固定して縦スクロール可能
※左2列を固定して横スクロール可能
※各列で昇順、降順の並び替え可能
※ページング(ページネーション)機能ON/OFF
テーマ名 | 順位 | 採用数 | 価格 | 発売 | ジャンル | デモの内容 | 画像1 | 画像2 | 画像3 |
---|---|---|---|---|---|---|---|---|---|
NANO | 1 | 24 | 34800 | 2018年 | コーポレート(企業) | 医療分野のコーポレートサイト | |||
Opinion | 2 | 17 | 11980 | 2014年 | ニュース・メディア | 様々なカテゴリの本格的ニュースメディア | |||
GENSEN | 3 | 17 | 39800 | 2017年 | 旅行、アフィリエイト | 複数の検索条件から探せる温泉旅行サイト | |||
Precious | 4 | 15 | 9980 | 2014年 | コーポレート(企業) | インテリア商品の紹介サイト(カート機能なし) | |||
LUXE | 5 | 11 | 10980 | 2015年 | コーポレート(企業)、ホテル、店舗 | リゾートホテルのサイト | |||
SOURCE | 6 | 10 | 13980 | 2017年 | コーポレート(企業)、ランディングページ | web制作会社のコーポレートサイト | |||
OOPS! | 6 | 10 | 19800 | 2017年 | コーポレート(企業)、ランディングページ | ミュージックアプリのブランディング&紹介サイト | |||
NOEL | 8 | 9 | 34800 | 2019年 | コーポレート(企業)、美容・サロン、病院・クリニック、店舗 | 美容クリニック紹介サイト | |||
NEXTAGE | 9 | 8 | 9980 | 2014年 | コーポレート(企業) | ベーシックな固いイメージのコーポレートサイト | |||
RUMBLE | 10 | 7 | 19800 | 2018年 | ニュース・メディア | モノトーン基調のニュースサイト | |||
Switch | 10 | 7 | 24800 | 2018年 | コーポレート(企業)、ランディングページ、店舗 | コワーキングスペースの紹介サイト | |||
ORION | 12 | 6 | 12980 | 2016年 | コーポレート(企業) | トップページに動画再生される旅紹介サイト | |||
STORY | 12 | 6 | 12980 | 2016年 | コーポレート(企業)、レストラン | 結婚式・ブライダルプランニングのサイト | |||
VOGUE | 12 | 6 | 19800 | 2017年 | コーポレート(企業) | 住宅販売のブランディングサイト | |||
Bloom | 12 | 6 | 16800 | 2017年 | ブログ、ニュース・メディア | 淡い色使いのブログニュースサイト | |||
Gorgeous | 16 | 5 | 8980 | 2013年 | ブログ、ニュース・メディア | 洗練されたイメージのブログメディア | |||
CORE | 16 | 5 | 11980 | 2015年 | ブログ、ニュース・メディア | 旅・食・生活などのブログメディア | |||
LAW | 16 | 5 | 11980 | 2016年 | コーポレート(企業)、士業・事務所 | 弁護士事務所のサイト | |||
AVANT | 16 | 5 | 24800 | 2018年 | ニュース・メディア | スケジュール表示できるイベントニュースサイト | |||
MONOLITH | 20 | 4 | 12980 | 2016年 | コーポレート(企業) | 住宅販売のブランディングサイト |
どうですか?
便利でワクワクしませんか?
簡単に実装できるのでぜひ読んでみてください。
通常のhtmlに貼り付けるだけでも実装できますし、WordPressの対応方法も解説します!
※カラムなどの多少のズレなど気になるかもしれませんが、横スクロールや並び替え、ページング対応を実装していて、ズレが起こらないライブラリは他にもないので今のところこれくらいは我慢が必要そうです。
DataTables
DataTablesというJavaScriptライブラリを使って実装します。
【公式サイト】https://datatables.net/
DataTablesの使い方なども補足しながら説明します。
実装方法① とりあえずHTMLに貼って実装
お使いのhtmlに以下のコードを貼るだけで、以下の機能が実現できます。
オプション設定などは適宜書き換えてください。
- キーワード検索で表示の絞り込み
- 最初の行を固定して縦スクロール
- 左列を固定して横スクロール
- 各列で昇順、降順の並び替え可能
- ページング(ページネーション)機能
<!-- dataTables本体CSS -->
<link href="//cdn.datatables.net/1.11.3/css/jquery.dataTables.min.css" rel="stylesheet">
<!-- dataTables本体JS -->
<script src="//cdn.datatables.net/1.11.3/js/jquery.dataTables.min.js"></script>
<!-- dataTablesカラム固定JS -->
<script src="//cdn.datatables.net/fixedcolumns/3.2.1/js/dataTables.fixedColumns.min.js"></script>
<style>
/* テーブル拡張 */
/* dataTables CSS微調整 */
.post_content td, .post_content th{
background-color: initial;
}
.wp-block-table{
overflow: initial;
}
table{
width: 100% !important; /* Xスクロールonで幅狭いときに崩れる */
}
.dataTables_filter{
margin: 0.5rem auto;
}
table.dataTable thead th, table.dataTable thead td {
font-weight: bold;
white-space: nowrap;
border-bottom: 0px solid #bbb;
}
table.dataTable.compact thead th, table.dataTable.compact thead td {
padding: 4px 17px 4px 4px;
font-weight: bold;
white-space: nowrap;
}
.DTFC_ScrollWrapper{
border: 1px solid #bbb !important;
outline: 0px solid #bbb !important;align-content
/* 上下 */
}
.dataTables_scroll{
border: 0px solid #bbb !important;
border-top: 0px solid #bbb !important;
border-right: 0px solid #bbb !important;
border-bottom: 0px solid #bbb !important;
border-left: 0px solid #bbb !important;
outline: 0px solid #bbb !important;align-content
/* 上下 */
}
table.dataTable.no-footer{
/* ヘッダ左の下と右(スクロール時内側) */
}
.dataTables_wrapper.no-footer .dataTables_scrollBody {
border: 1px solid #bbb !important;
/* ヘッダ右の下と右ボディの上下 */
}
.dataTables_scrollBody{
/* 変化なし */
}
table.dataTable.DTFC_Cloned {
border-right: 1px solid #bbb !important;
border-bottom: 0px solid #bbb !important;
/* 変化なし */
}
.DTFC_LeftHeadWrapper{
/* ヘッダ左の上右 */
}
.DTFC_LeftHeadWrapper table.dataTable.DTFC_Cloned th{
/* ヘッダ 左の真ん中だけ */
}
.DTFC_LeftBodyWrapper{
border: 0px solid #bbb !important;
border-top: 1px solid #bbb !important;
border-right: 0px solid #bbb !important;
border-bottom: 1px solid #bbb !important;
border-left: 0px solid #bbb !important;
outline: 0px solid #f00 !important;
/* ボディ左の上右 */
}
.DTFC_LeftBodyLiner{
border: 0px solid #bbb !important;
border-top: 0px solid #bbb !important;
border-right: 0px solid #bbb !important;
border-bottom: 0px solid #bbb !important;
border-left: 0px solid #bbb !important;
outline: 0px solid #bbb !important;
/* 変化なし */
overflow-x: hidden;
}
table.dataTable thead .sorting {
border-bottom: 0px solid #bbb !important;
/* ヘッダ右の右下 */
}
</style>
<script type="text/javascript">
// ==============================================
// DataTable()のオプション
// https://datatables.net/reference/option/
// ※対象のテーブルには thead,tbodyを両方使うこと
// ==============================================
dataTableOptionsMapDefault =
{
"table": {
//order: [ 0, "asc" ], //並び替え初期状態
//stateSave: true, //並び替えなどの状態を保存
paging: false, //ページング
pagingType: "full_numbers", //ページングにページ番号リンク出す
scrollX: true, //X方向のスクロール有効
scrollY: false, //Y方向のスクロール。vh指定で縦幅の70%
scrollCollapse: true, //行少ない時にレイアウト崩れを防ぐ
fixedColumns: {
leftColumns: 1, //左からいくつの列を固定するか
},
searching: false, //検索フィルタ実装
ordering: false, //並び替えの実装
columnDefs: [
{
targets: 0, //設定対象の列index
//width: 100,
}
],
language: {
url: "//cdn.datatables.net/plug-ins/3cfcc339e89/i18n/Japanese.json" //日本語化
},
}
};
if(typeof dataTableOptionsMap == "undefined" || dataTableOptionsMap == null){
dataTableOptionsMap = {};
}
dataTableOptionsMap = Object.assign(dataTableOptionsMapDefault, dataTableOptionsMap);
console.log(dataTableOptionsMapDefault);
console.log(dataTableOptionsMap);
// ==============================================
// 表の見栄えのためのクラス
// https://datatables.net/manual/styling/theme-creator#Result
// ==============================================
if(typeof dataTableClass == "undefined" || dataTableClass == null){
dataTableClass = "";
}
dataTableClass += " display"; //以下4オプションのセットstripe, hover, row-border, order-column
//dataTableClass += " cell-border"; //セルの線あり
dataTableClass += " compact"; //小さいセルサイズ
//dataTableClass += " hover"; //マウスオーバーで行の色変化
//dataTableClass += " nowrap"; //改行なし
//dataTableClass += " order-column"; //並び替え列協調
//dataTableClass += " row-border"; //行の線あり
//dataTableClass += " stripe"; //行ごとに色替え
// ==============================================
// DataTablesを適用する表のセレクタ
// ==============================================
if(typeof dataTableSelectorList == "undefined" || dataTableSelectorList == null){
dataTableSelectorList = ["table"];
}
jQuery(function(){
console.log(dataTableSelectorList);
// ==============================================
// Tableタグ調整(tbodyはブラウザ側が勝手に付ける)
// ==============================================
for(let idx=0; idx<dataTableSelectorList.length; ++idx){
let dataTableSelector = dataTableSelectorList[idx];
jQuery(dataTableSelector).each(function(index ,element){
console.log(index + " " + dataTableSelector);
first = jQuery(this).find("*:first-child");
if(first.prop("tagName") == "tbody"){
console.log("処理する");
tr = jQuery(this).find("tr:first-child");
console.log(tr.html());
tr.remove();
jQuery(this).prepend("<thead>" + tr.html() + "</thead>");
}else{
console.log("処理しない");
}
});
// ==============================================
// DataTables適用開始
// ==============================================
let dataTableOptions = {};
if(dataTableSelector in dataTableOptionsMap){
dataTableOptions = dataTableOptionsMap[dataTableSelector];
}else{
dataTableOptions = dataTableOptionsMapDefault["table"];
}
console.log("対象table: " + dataTableSelector + " " + jQuery(dataTableSelector).length);
console.log(dataTableClass);
console.log(dataTableOptions);
jQuery(dataTableSelector).addClass(dataTableClass); //クラスをセット
jQuery(dataTableSelector).DataTable(dataTableOptions); //DataTable実行
}
});
</script>
実装方法② WordPressで使うための設定
WordPress上でも①の方法で実装できますが、より簡単に繰り返し使うためにショートコード化して実装してみます。
記事内に[table_ex]と記述するだけで、普通のtableタグに拡張機能が実装されるようになります。
functions.phpにショートコード実装
以下のコードをfunctions.phpにコピペして追記します。
functions.phpの編集方法がわからない方は以下を参考にしてください。
functions.phpの場所、編集方法
functions.phpはWordPressの機能追加をするためのPHPファイルです。
functions.phpの場所は
「外観>テーマエディター」から
テーマファイルのfuncstions.phpを選びます。
また、直接functions.phpを編集するよりもこちらのプラグインで編集した方が便利なので参考にしてみてください。
functions.phpに貼り付けるスクリプト
/*
* **********************************
* テーブル表拡張ショートコード
* **********************************
*/
function table_ex($atts){
extract(shortcode_atts(array(
), $atts));
$html =<<<EOF
<!-- dataTables本体CSS -->
<link href="//cdn.datatables.net/1.11.3/css/jquery.dataTables.min.css" rel="stylesheet">
<!-- dataTables本体JS -->
<script src="//cdn.datatables.net/1.11.3/js/jquery.dataTables.min.js"></script>
<!-- dataTablesカラム固定JS -->
<script src="//cdn.datatables.net/fixedcolumns/3.2.1/js/dataTables.fixedColumns.min.js"></script>
<style>
/* テーブル拡張 */
/* dataTables CSS微調整 */
.post_content td, .post_content th{
background-color: initial;
}
.wp-block-table{
overflow: initial;
}
table{
width: 100% !important; /* Xスクロールonで幅狭いときに崩れる */
}
.dataTables_filter{
margin: 0.5rem auto;
}
table.dataTable thead th, table.dataTable thead td {
font-weight: bold;
white-space: nowrap;
border-bottom: 0px solid #bbb;
}
table.dataTable.compact thead th, table.dataTable.compact thead td {
padding: 4px 17px 4px 4px;
font-weight: bold;
white-space: nowrap;
}
.DTFC_ScrollWrapper{
border: 1px solid #bbb !important;
outline: 0px solid #bbb !important;align-content
/* 上下 */
}
.dataTables_scroll{
border: 0px solid #bbb !important;
border-top: 0px solid #bbb !important;
border-right: 0px solid #bbb !important;
border-bottom: 0px solid #bbb !important;
border-left: 0px solid #bbb !important;
outline: 0px solid #bbb !important;align-content
/* 上下 */
}
table.dataTable.no-footer{
/* ヘッダ左の下と右(スクロール時内側) */
}
.dataTables_wrapper.no-footer .dataTables_scrollBody {
border: 1px solid #bbb !important;
/* ヘッダ右の下と右ボディの上下 */
}
.dataTables_scrollBody{
/* 変化なし */
}
table.dataTable.DTFC_Cloned {
border-right: 1px solid #bbb !important;
border-bottom: 0px solid #bbb !important;
/* 変化なし */
}
.DTFC_LeftHeadWrapper{
/* ヘッダ左の上右 */
}
.DTFC_LeftHeadWrapper table.dataTable.DTFC_Cloned th{
/* ヘッダ 左の真ん中だけ */
}
.DTFC_LeftBodyWrapper{
border: 0px solid #bbb !important;
border-top: 1px solid #bbb !important;
border-right: 0px solid #bbb !important;
border-bottom: 1px solid #bbb !important;
border-left: 0px solid #bbb !important;
outline: 0px solid #f00 !important;
/* ボディ左の上右 */
}
.DTFC_LeftBodyLiner{
border: 0px solid #bbb !important;
border-top: 0px solid #bbb !important;
border-right: 0px solid #bbb !important;
border-bottom: 0px solid #bbb !important;
border-left: 0px solid #bbb !important;
outline: 0px solid #bbb !important;
/* 変化なし */
overflow-x: hidden;
}
table.dataTable thead .sorting {
border-bottom: 0px solid #bbb !important;
/* ヘッダ右の右下 */
}
</style>
<script type="text/javascript">
// ==============================================
// DataTable()のオプション
// https://datatables.net/reference/option/
// ※対象のテーブルには thead,tbodyを両方使うこと
// ==============================================
dataTableOptionsMapDefault =
{
"table": {
//order: [ 0, "asc" ], //並び替え初期状態
//stateSave: true, //並び替えなどの状態を保存
paging: false, //ページング
pagingType: "full_numbers", //ページングにページ番号リンク出す
scrollX: true, //X方向のスクロール有効
scrollY: false, //Y方向のスクロール。vh指定で縦幅の70%
scrollCollapse: true, //行少ない時にレイアウト崩れを防ぐ
fixedColumns: {
leftColumns: 1, //左からいくつの列を固定するか
},
searching: false, //検索フィルタ実装
ordering: false, //並び替えの実装
columnDefs: [
{
targets: 0, //設定対象の列index
//width: 100,
}
],
language: {
url: "//cdn.datatables.net/plug-ins/3cfcc339e89/i18n/Japanese.json" //日本語化
},
}
};
if(typeof dataTableOptionsMap == "undefined" || dataTableOptionsMap == null){
dataTableOptionsMap = {};
}
dataTableOptionsMap = Object.assign(dataTableOptionsMapDefault, dataTableOptionsMap);
console.log(dataTableOptionsMapDefault);
console.log(dataTableOptionsMap);
// ==============================================
// 表の見栄えのためのクラス
// https://datatables.net/manual/styling/theme-creator#Result
// ==============================================
if(typeof dataTableClass == "undefined" || dataTableClass == null){
dataTableClass = "";
}
dataTableClass += " display"; //以下4オプションのセットstripe, hover, row-border, order-column
//dataTableClass += " cell-border"; //セルの線あり
dataTableClass += " compact"; //小さいセルサイズ
//dataTableClass += " hover"; //マウスオーバーで行の色変化
//dataTableClass += " nowrap"; //改行なし
//dataTableClass += " order-column"; //並び替え列協調
//dataTableClass += " row-border"; //行の線あり
//dataTableClass += " stripe"; //行ごとに色替え
// ==============================================
// DataTablesを適用する表のセレクタ
// ==============================================
if(typeof dataTableSelectorList == "undefined" || dataTableSelectorList == null){
dataTableSelectorList = ["table"];
}
jQuery(function(){
console.log(dataTableSelectorList);
// ==============================================
// Tableタグ調整(tbodyはブラウザ側が勝手に付ける)
// ==============================================
for(let idx=0; idx<dataTableSelectorList.length; ++idx){
let dataTableSelector = dataTableSelectorList[idx];
jQuery(dataTableSelector).each(function(index ,element){
console.log(index + " " + dataTableSelector);
first = jQuery(this).find("*:first-child");
if(first.prop("tagName") == "tbody"){
console.log("処理する");
tr = jQuery(this).find("tr:first-child");
console.log(tr.html());
tr.remove();
jQuery(this).prepend("<thead>" + tr.html() + "</thead>");
}else{
console.log("処理しない");
}
});
// ==============================================
// DataTables適用開始
// ==============================================
let dataTableOptions = {};
if(dataTableSelector in dataTableOptionsMap){
dataTableOptions = dataTableOptionsMap[dataTableSelector];
}else{
dataTableOptions = dataTableOptionsMapDefault["table"];
}
console.log("対象table: " + dataTableSelector + " " + jQuery(dataTableSelector).length);
console.log(dataTableClass);
console.log(dataTableOptions);
jQuery(dataTableSelector).addClass(dataTableClass); //クラスをセット
jQuery(dataTableSelector).DataTable(dataTableOptions); //DataTable実行
}
});
</script>
EOF;
return $html;
}
add_shortcode('table_ex', 'table_ex');
使い方
まず、記事内にショートコード[table_ex]と記述します。
これだけで全ての表が拡張されます。
デフォルトの設定を変更
適用するテーブルを限定したい場合や、DataTablesのオプションを変更したい場合は、投稿画面で「カスタムhtml」ブロックに後述のスクリプトを貼り付けることで可能です。
dataTableSelectorList , dataTableClass , dataTableOptionsMap の3つの変数を上書きすることでオプション設定の修正ができます。
※ショートコード[table_ex]より前に貼り付けないと反映されません。
カスタムhtmlの中に以下のスクリプトを貼り付けてください。
(内容に関しては元のソースを参考にして適宜追加してください)
全てのテーブルに同じオプションを上書き設定をする
ページ内の全ての表に同じ設定を適用する場合はこちらをカスタムhtmlの中に貼り付けてください。
<script type="text/javascript">
//=================================
// DataTablesを適用する表の条件を上書き指定
// (拡張する対象の表をjqueryセレクタで記述)
//=================================
dataTableSelectorList = ["table"];
//=================================
// 表の見栄えオプションを上書き
// (classの中の内容を記述)
//=================================
dataTableClass = "display compact";
//=================================
// DataTable()の実行オプションを追記・上書き
// (キーはdataTableSelectorListで設定したセレクタの値を使う)
//=================================
dataTableOptionsMap = {
"table": {
//scrollY: "50vh",
paging: true,
searching: true,
ordering: true,
fixedColumns: {
leftColumns: 1,
},
language: {
url: "//cdn.datatables.net/plug-ins/3cfcc339e89/i18n/Japanese.json" //日本語化
},
},
};
</script>
テーブルごとに違うオプションの上書き設定をする
テーブル表が複数あって個別に設定をしたい場合はこちらをカスタムhtmlの中に貼り付けてください。
<script type="text/javascript">
//=================================
// DataTablesを適用する表の条件を上書き指定
// (拡張する対象の表をjqueryセレクタで記述)
//=================================
dataTableSelectorList = ["#all-tcd-themes+* table", "#tcd-info+* table"];
//=================================
// 表の見栄えオプションを上書き
// (classの中の内容を記述)
//=================================
dataTableClass = "display compact";
//=================================
// DataTable()の実行オプションを追記・上書き
// (キーはdataTableSelectorListで設定したセレクタの値を使う)
//=================================
dataTableOptionsMap = {
"#all-tcd-themes+* table": {
//order: [ 0, "asc" ], //並び替え初期状態
//stateSave: true, //並び替えなどの状態を保存
paging: false, //ページング
pagingType: "full_numbers", //ページングにページ番号リンク出す
scrollX: true, //X方向のスクロール有効
scrollY: "80vh", //Y方向のスクロール。vh指定で縦幅の70%
scrollCollapse: true, //行少ない時にレイアウト崩れを防ぐ
fixedColumns: {
leftColumns: 2, //左からいくつの列を固定するか
},
searching: true, //検索フィルタ実装
ordering: true, //並び替えの実装
columnDefs: [
{
targets: 0, //設定対象の列index
//width: 100,
}
],
language: {
url: "//cdn.datatables.net/plug-ins/3cfcc339e89/i18n/Japanese.json" //日本語化
},
},
"#tcd-info+* table": {
//scrollY: "50vh",
paging: true,
searching: true,
ordering: true,
fixedColumns: {
leftColumns: 1,
},
language: {
url: "//cdn.datatables.net/plug-ins/3cfcc339e89/i18n/Japanese.json" //日本語化
},
},
};
</script>
CSSでテーブルの見た目も調整する
CSSも同様にスクリプトと同じ場所に貼り付けてください。
え?styleタグはheadタグの中でないとダメ?
それは少し昔の話。今は出来ます。大丈夫です。
<style>
table.dataTable th, table.dataTable td {
min-width: 30px; /* 最低限のセル幅 */
}
</style>
【おまけ】トラブルシューティング
DataTablesで以下のようなエラーが出ることがあります。
jquery.dataTables.min.js:105 Uncaught TypeError: Cannot read properties of undefined (reading 'mData')
これは対象としたtable内にtheadやtbodyがないことが原因ですが、ここで紹介した方法ではエラーが発生しないよう調整してあります。