DataTables.js のレスポンシブ機能をハックしてフリースペースとして使う方法

##この記事について

jQueryのプラグイン DataTables の応用方法を紹介します。

[画像イメージ]
![image.png](https://qiita-image-store.s3.amazonaws.com/0/217094/7a701c82-dbff-072d-2b3d-63fdd97eab80.png)


DataTables はテーブル装飾用のプラグインなのでフラットなデータしか扱えないように思われますが、工夫次第でテーブルの中に階層化したデータを表示することができます。
セルの中に出力するデータを自分で作ったHTMLで置き換えることができるので、応用範囲は広いです。

### Datatablesについて

公式：https://datatables.net/

基本の使い方：https://qiita.com/nissuk/items/7ac59af5de427c0585c5

##サンプルコード

サンプルページ
https://okoppe8.github.io/datatables_responsive_hack/index.html

サンプルコード
[github](https://github.com/okoppe8/datatables_responsive_hack)

## やりかた

### 入れ子になったJSONを用意する。

今回はレシートをイメージしたサンプルを作りました

```json
{
    "data": [
        {   "id":1,
            "cashier": "山田 花子",
            "time": "10:55",
            "summary": 1920,
            "items": [
                {
                    "item": "幕の内弁当",
                    "price": 1050
                },
                {
                    "item": "サービス弁当",
                    "price": 600
                },
                {
                    "item": "グリーンサラダ小",
                    "price": 150
                },
                {
                    "item": "ウーロン茶",
                    "price": 120
                }
            ]
        },
        {   "id":2,
            "cashier": "鈴木 大介",
            "time": "11:21",
            "summary": 770,
            "items": [
                {
                    "item": "のり弁当",
                    "price": 400
                },
                {
                    "item": "とりから揚げ",
                    "price": 250
                },
                {
                    "item": "コカコーラ",
                    "price": 120
                }
            ]
        }
    ]
}
```
DataTablesはAjaxでJSONを読み込むため、WebAPIからJSONを取得することも可能です。
  
### 公式サイトよりDataTables をダウンロードする

https://datatables.net/download/index

ダウンロードでもCDNでも使えます。
構成の指定では「Extensions」のResponsiveにチェックを入れてください。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/217094/a5ccdda4-df76-7cec-1d95-f9c54641b42d.png)


### DataTables を設定する
  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/217094/090e62a9-32ec-fd4d-0d55-28b6ee748b37.png)

https://datatables.net/extensions/responsive/examples/styling/bootstrap.html


  DataTables の レスポンシブ機能は、幅が狭くて表示きれなかったカラムを落とし、２行目の明細行にリストで表示させる仕組みです。
  この２行目の明細行を、DataTablesにもともとある内容の装飾機能を使って上書きしてしまうのが今回の趣旨となります。
  
  全体はサンプルページを見てもらうとして要旨のみ説明します。
  
  まず「responsive.details」のフィールドで明細行の状態を設定します。
  本来アコーディオンで開くものを最初から開きっぱなしにさせます
  
```js

// レスポンシブ設定
responsive: {
    // 明細行（２行目）の設定
    details: {
        // 最初から開いた状態にする
        display: $.fn.dataTable.Responsive.display.childRowImmediate,

        // 開閉機能を無効にしている。
        type: 'column', // 開閉マークを消す
        target: '', // 列をタッチしても無反応にする
    }
},
```

そしてcolumnsの設定で、明細行に表示させたいフィールドを指定します。
フィールドのclassName属性を"none"に指定すると表示先が２行目になります。

あとはrender属性にHTMLを返す関数を設定してください。
サンプルでは配列を持つフィールドのデータを基にtableを作成しています。

```js
{
    data: "items",
    className: "none", //noneを設定すると初期表示で明細行に表示される
    render: function (items) {

        rows = ""
        items.forEach(
            function (item, index) {
                rows += "<tr><td>" + item.item + '</dt><td class="right">' + item.price + "</td></tr>"
            }
        )
        return '<table class="childtable table-striped table-bordered"><tbody>' + rows + '</tbody></table>'
    }
}
```

あとはCSSで微妙に詰まったり間延びしたところを修正します。

```css
.dtr-details,
.childtable {
    width: 100%
}

.dtr-title {
    display: none !important;
}
```

工夫すれば何にでも使えると思います。
この状態でも明細の内容に対して検索がかかるのが便利ですね。