48
52

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

jQuery DataTables の使い方 render, row, meta...

Last updated at Posted at 2019-06-18

はじめに

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などのブラウザで開いてみてください。
成功すると次のような表が表示されます。
image.png
ソートや検索機能などが実装されています。細かい調整は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>を追加しました。)
表の出力はこんな感じになります。
image.png

render要素

さて、動詞だけ色を付けて強調してみましょう。
columnsrender要素に関数オブジェクト(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に関数オブジェクトを代入して使っています。

いずれの場合でも次のような結果になります。
image.png

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')で取得できることを利用しています。

image.png
出力ボタンを押すと次のようなアラートが出ます。
image.png

これを応用すると編集機能などが作れます。

※2020/5/5 追記

同様の機能はフレームワークvueとそのUIフレームワークvuetifyを用いても実現できます。vuetifyのdatatableを使って作るのが最近のマイブームです。

48
52
0

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
48
52

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?