はじめに
jQueryの便利なライブラリの一つにDataTablesがあります。bootstrapと組み合わせられて、ソートや検索、ページング機能を自動でいい感じの見た目の表に出力してくれる優れものです。
例えば
[
{id:1,japanese:"走る",english:"run",pos:"動詞"},
{id:2,japanese:"歩く",english:"walk",pos:"動詞"},
{id:3,japanese:"鉛筆",english:"pencil",pos:"名詞"},
{id:4,japanese:"夢",english:"dream",pos:"名詞"},
]
のような形のjsonデータがあったとして、それをどうdataTablesを使ってきれいな表にしていくかについて解説します。
はじめのコード
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css"/>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<!-- 追加のCSS -->
<style>
</style>
<table class='table table-stripe' id="lingTable">
<thead>
<tr><th>#</th><th>日本語</th><th>英語</th>
<th>品詞</th></tr>
</thead>
</table>
<!-- dataTables bootstrap4を使うためのJSファイル -->
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap4.min.js"></script>
<!-- 独自定義JS -->
<script type="text/javascript">
const lingData=[
{id:1,japanese:"走る",english:"run",pos:"動詞"},
{id:2,japanese:"歩く",english:"walk",pos:"動詞"},
{id:3,japanese:"鉛筆",english:"pencil",pos:"名詞"},
{id:4,japanese:"夢",english:"dream",pos:"名詞"},
]
const dtSetting={
destroy: true,
data: lingData,
language: {
url: "https://cdn.datatables.net/plug-ins/3cfcc339e89/i18n/Japanese.json"
},
columns: [
{data:"id"},
{ data: "japanese"},
{ data: "english"},
{ data: "pos"}
]
};
$('#lingTable').DataTable(dtSetting);
</script>
</body>
</html>
とりあえずこのコードをコピペして好きな名前のhtmlファイルを作ってGoogle Chromeなどのブラウザで開いてみてください。
成功すると次のような表が表示されます。
ソートや検索機能などが実装されています。細かい調整はDataTablesの使い方を参照してください。
さて、独自定義JSと書かれた中を見てください。
-
const lingData=[...]
で先程のjsonを定義しています。通常の運用ではajax
などを使って取ってくるでしょう。 - その下の
const dtSetting={...}
というオブジェクトがDataTablesに渡す設定オブジェクトです。 -
destroy:true
は再描画を可能にするためのもので、trueにしておいたほうが便利です。(後ほど出てくるので今は何を言っているかわからなくてもあまり気にしないでください。) -
data:lingData
でlingDataの中身を読み込むと設定しています。 - 次の
language:...
は日本語表記にする設定でこれがないとX件表示などが英語表記になってしまいます。 - 最後の
columns:[]
でどの列にどの要素を指定するかを順番に定義しています。列の数を増やすためには個々の要素の数を増やすと同時に、<thead>
タグ内の<th>
タグの数を増やす必要があります。そうしないとエラーします。よくエラーするポイントです。
columns: [
{ data: "id"},
{ data: "japanese"},
{ data: "english"},
{ data: "pos"},
{ data: "pos"} /*追加*/
]
のように追加するならば、
<thead>
<tr><th>#</th><th>日本語</th><th>英語</th>
<th>品詞</th><th>品詞2</th></tr>
</thead>
としないといけないということです。(<th>品詞2</th>
を追加しました。)
表の出力はこんな感じになります。
render要素
さて、動詞だけ色を付けて強調してみましょう。
columns
のrender
要素に関数オブジェクト(function(){...}
のかたちで作られるオブジェクト)を付加します。
関数オブジェクトについてはこのリンクに詳しく解説されています。オブジェクトはJavaScriptを使う上で非常に重要になる概念です。
コード全体です。
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css"/>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<!-- 追加のCSS -->
<style>
body{
margin:20px;
}
</style>
<table class='table table-stripe' id="lingTable">
<thead>
<tr><th>#</th><th>日本語</th><th>英語</th>
<th>品詞</th></tr>
</thead>
</table>
<!-- dataTables bootstrap4を使うためのJSファイル -->
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap4.min.js"></script>
<!-- 独自定義JS -->
<script type="text/javascript">
const lingData=[
{id:1,japanese:"走る",english:"run",pos:"動詞"},
{id:2,japanese:"歩く",english:"walk",pos:"動詞"},
{id:3,japanese:"鉛筆",english:"pencil",pos:"名詞"},
{id:4,japanese:"夢",english:"dream",pos:"名詞"},
]
const dtSetting={
destroy: true,
data: lingData,
language: {
url: "https://cdn.datatables.net/plug-ins/3cfcc339e89/i18n/Japanese.json"
},
columns: [
{ data:"id"},
{ data: "japanese"},
{ data: "english"},
{ data: "pos", render:function(arg){
if(arg=="動詞"){
return `<span style='color:red;'>${arg}</span>`;
}else{
return arg;
}}
}
]
};
$('#lingTable').DataTable(dtSetting);
</script>
</body>
</html>
関数オブジェクトに慣れていない人は次のように書いたほうがわかりやすいかもしれません。
<script type="text/javascript">
const lingData=[
{id:1,japanese:"走る",english:"run",pos:"動詞"},
{id:2,japanese:"歩く",english:"walk",pos:"動詞"},
{id:3,japanese:"鉛筆",english:"pencil",pos:"名詞"},
{id:4,japanese:"夢",english:"dream",pos:"名詞"},
]
const verbred=function(arg){
if(arg=="動詞"){
return `<span style='color:red;'>${arg}</span>`;
}else{
return arg;
}
};
const dtSetting={
destroy: true,
data: lingData,
language: {
url: "https://cdn.datatables.net/plug-ins/3cfcc339e89/i18n/Japanese.json"
},
columns: [
{data:"id"},
{ data: "japanese"},
{ data: "english"},
{ data: "pos", render:verbred }
]
};
$('#lingTable').DataTable(dtSetting);
</script>
いったん変数verbred
に関数オブジェクトを代入して使っています。
row ~複数列(キー)のデータを使う~
複数の列のデータを使いたいというシチュエーションはよく出てきます。今回は品詞が動詞だったときに単語を青くすることを考えましょう。次のようにします。
<script type="text/javascript">
const lingData=[
{id:1,japanese:"走る",english:"run",pos:"動詞"},
{id:2,japanese:"歩く",english:"walk",pos:"動詞"},
{id:3,japanese:"鉛筆",english:"pencil",pos:"名詞"},
{id:4,japanese:"夢",english:"dream",pos:"名詞"},
]
const dtSetting={
destroy: true,
data: lingData,
language: {
url: "https://cdn.datatables.net/plug-ins/3cfcc339e89/i18n/Japanese.json"
},
columns: [
{data:"id"},
{ data: "japanese"},
{ data: "english",
render:function(data,type,row){
if(row.pos=="動詞"){
return `<span style='color:blue;'>${data}</span>`;
}else{
return data; //row.englishでも良い。
}
}
},
{ data: "pos", render:function(arg){
if(arg=="動詞"){
return `<span style='color:red;'>${arg}</span>`;
}else{
return arg;
}}
}
]
};
$('#lingTable').DataTable(dtSetting);
</script>
render
に3引数を持つ関数オブジェクトを登録することで、3つめの引数row
から自分以外のキーのデータにアクセスできます。関数オブジェクト内でconsole.log(row);
などしてやるとよくわかるかもしれません。
meta ~jsonの中で何行目のデータか探る~
ボタンをつけて、ボタンを押したらその行のデータを整形して表示するようにしましょう。ボタン自身が属する列のデータが、元データlingData
の中の何個目のデータなのかがボタンに付加しておきたい情報です。次のようになります。
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css"/>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<!-- 追加のCSS -->
<style>
body{
margin:20px;
}
</style>
<table class='table table-stripe' id="lingTable">
<thead>
<tr><th>#</th><th>日本語</th><th>英語</th>
<th>品詞</th><th>出力</th></tr>
</thead>
</table>
<!-- dataTables bootstrap4を使うためのJSファイル -->
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap4.min.js"></script>
<!-- 独自定義JS -->
<script type="text/javascript">
const lingData=[
{id:1,japanese:"走る",english:"run",pos:"動詞"},
{id:2,japanese:"歩く",english:"walk",pos:"動詞"},
{id:3,japanese:"鉛筆",english:"pencil",pos:"名詞"},
{id:4,japanese:"夢",english:"dream",pos:"名詞"},
]
const dtSetting={
destroy: true,
data: lingData,
language: {
url: "https://cdn.datatables.net/plug-ins/3cfcc339e89/i18n/Japanese.json"
},
columns: [
{ data:"id"},
{ data: "japanese"},
{ data: "english",
render:function(data,type,row){
if(row.pos=="動詞"){
return `<span style='color:blue;'>${data}</span>`;
}else{
return data; //row.englishでも良い。
}
}
},
{ data: "pos", render:function(arg){
if(arg=="動詞"){
return `<span style='color:red;'>${arg}</span>`;
}else{
return arg;
}}
},
{data:"id",
render:function(data,type,row,meta){
return `<button class="btn btn-danger output" data-jnum="${meta.row}">出力</button>`;
}
},
]
};
$('#lingTable').DataTable(dtSetting);
$(document).on('click','.output',function(){
const jnum=$(this).data('jnum');
alert(`日本語表記:${lingData[jnum]["japanese"]},英語表記:${lingData[jnum]["english"]},品詞:${lingData[jnum]["pos"]}`);
})
</script>
</body>
</html>
関数オブジェクトに第4引数meta
を追加するとmeta.row
で今回欲しい情報が取ってこれます。
アラートを出すところは$(document).on(...
で定義しています。output
クラスはDataTable関数によって後から作られるので、$('.output').on(...
では動きません。
jQueryの便利機能、data-xxx
の形のattributeの値は、$(...).data('xxx')
で取得できることを利用しています。
これを応用すると編集機能などが作れます。
※2020/5/5 追記
同様の機能はフレームワークvueとそのUIフレームワークvuetifyを用いても実現できます。vuetifyのdatatableを使って作るのが最近のマイブームです。