15
9

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 5 years have passed since last update.

DataTablesをkintoneライクにする魔法のコード

Last updated at Posted at 2018-08-28

はじめに

kintoneのカスタマイズでテーブルを使いたいときに便利なのがDataTables
そのまま使用するとkintoneのデザインに溶け込まず、イケてない感じになる。
そこで今回はDataTablesをkintoneライクにする魔法のコードを作ってみた。

CDN

参考:https://developer.cybozu.io/hc/ja/articles/202960194-Cybozu-CDN
DataTablesはCybozu CDNで公開されているので、こちらを使う。
DataTablesを使うためにはjQueryを読み込む必要があるのでこちらもCDNから読み込む。

JS

CSS

魔法のCSS

DataTablesのJS/CSSに加えて、下記のようなCSSを追加するとデザインがkintoneライクになる。

kintone-datatables.css

table.dataTable {
    font-size: 14px;
    margin: 0;
}

table.dataTable.no-footer {
    border-bottom: 1px solid #e3e7e8;
}

table.dataTable thead tr th:first-child,
table.dataTable thead tr td:first-child {
    border-left: 1px solid #e3e7e8;
}

table.dataTable tbody tr th:first-child,
table.dataTable tbody tr td:first-child {
    border-left: 1px solid #e3e7e8;
}

table.dataTable tr.odd {
    background-color: #f5f5f5;
}

table.dataTable tr.even {
    background-color: #fff;
}

table.dataTable thead th,
table.dataTable thead td {
    text-align: left;
    white-space: normal;
    overflow: hidden;
    margin-right: -5px;
    border-top: 1px solid #e3e7e8;
    border-right: 1px solid #e3e7e8;
    border-bottom: 1px solid #e3e7e8;
    background-color: #fff;
    letter-spacing: 0.1em;
    font-weight: 400;
}

table.dataTable tbody th,
table.dataTable tbody td {
    white-space: normal;
    overflow: hidden;
    border-right: 1px solid #e3e7e8;
}

table.dataTable tbody tr.selected {
    background-color: #e1f2f7;
}

.dataTables_wrapper.no-footer .dataTables_scrollBody {
    border-bottom: 1px solid #e3e7e8;
}

.dataTables_filter {
    text-align: right;
}

.dataTables_filter label {
    display: block;
    margin-bottom: 8px;
    font-family: "メイリオ", "Hiragino Kaku Gothic ProN", Meiryo, sans-serif;
    font-size: 14px;
}

.dataTables_filter input {
    height: 40px;
    display: inline-block;
    box-sizing: border-box;
    margin: 0;
    padding: 0 8px;
    border: 1px solid #e3e7e8;
    background-color: #fff;
    box-shadow: 2px 2px 4px #f5f5f5 inset, -2px -2px 4px #f5f5f5 inset;
    color: #888;
    font-size: 14px;
}

.dataTables_filter input:focus {
    background-color: #e2f2fe;
    box-shadow: none;
    color: #000;
}

日本語化オプション

使用する際に以下のオプションを加えることで日本語化できる。
(参考:コピペで動くjQuery DataTablesの導入と日本語対応

sample.js
$('#example').DataTable({
    'language': {
        'url': '//cdn.datatables.net/plug-ins/3cfcc339e89/i18n/Japanese.json'
    },
    // その他オプション
});

結果

Before(CSS未適用)
before.PNG

After(CSS適用後)
after.PNG
※注意:DataTablesで作った一覧です(標準の一覧ではありません)

応用編

一覧画面にチェックボックス付きのDataTablesを配置し、選択したレコードの添付ファイルを一括でダウンロードするサンプル
view.PNG

使用するライブラリ

カスタマイズビュー

参考:カスタマイズビューを利用してみよう
アプリの設定からカスタマイズビューのHTMLを設定

カスタマイズビュー
<table id="view"></table>

customize_view.PNG

一覧IDをメモしておく。

Javascript

main.js
// チェックボックスのHTML
var checkboxHtml = '<div class="kintoneplugin-input-checkbox">' +
    '<span class="kintoneplugin-input-checkbox-item">' +
    '<input type="checkbox">' +
    '<label></label>' +
    '</span>' +
    '</div>';

// ボタンのHTML
var buttonHtml = '<button id="download" class="kintoneplugin-button-normal">ダウンロード</button>';

// 一覧の表示イベント
kintone.events.on(['app.record.index.show'], function (event) {

    // XXXXは一覧ID
    if (event.viewId !== XXXX) {
        return event;
    }

    // DataTablesの設定
    var table = $('#view').DataTable({
        // 日本語化
        language: {
            url: '//cdn.datatables.net/plug-ins/3cfcc339e89/i18n/Japanese.json'
        },
        data: event.records,
        columnDefs: [
            {
                targets: 0,
                title: '',
                defaultContent: checkboxHtml,
                className: 'control-cell',
                orderable: false
            },
            {
                targets: 1,
                title: '顧客ID',
                data: 'company_id.value',
                defaultContent: '',
                orderable: false
            },
            {
                targets: 2,
                title: '会社ID',
                data: 'company_name.value',
                defaultContent: '',
                orderable: false
            },
            {
                targets: 3,
                title: '業界',
                data: 'industry.value',
                defaultContent: '',
                orderable: false
            },
            {
                targets: 4,
                title: '氏名',
                data: 'name.value',
                defaultContent: '',
                orderable: false
            },
            {
                targets: 5,
                title: 'フリガナ',
                data: 'name_reading.value',
                defaultContent: '',
                orderable: false
            },
            {
                targets: 6,
                title: '性別',
                data: 'gender.value',
                defaultContent: '',
                orderable: false
            },
            {
                targets: 7,
                title: 'メールアドレス',
                data: 'mailaddress.value',
                defaultContent: '',
                orderable: false
            }
        ],
        paging: false,
        order: [],
        info: false,
        searching: false,
        createdRow: function (row, record, index) {

            // チェックボックス
            const $checkbox = $('.kintoneplugin-input-checkbox', row);

            // チェックボックス選択時に行にクラス名:`selected`を追加
            $checkbox.find('input')
                .attr('id', `checkbox-${index}`)
                .on('change', function (event) {

                    if ($(event.target).prop('checked')) {
                        $(row).addClass('selected');
                    } else {
                        $(row).removeClass('selected');
                    }

                });

            $checkbox.find('label')
                .attr('for', `checkbox-${index}`);

        },
        initComplete: function () {

            // 全選択用のチェックボックスを配置
            const $checkboxAll = $(checkboxHtml).appendTo(table.column(0).header());

            $checkboxAll.find('input')
                .attr('id', 'checkbox-all')
                .on('change', (event) => {

                    var checked = $(event.target).prop('checked');

                    for (var i = 0; i < table.data().count(); i++) {

                        var row = table.row(i);
                        var record = row.data();
                        var node = row.node();

                        $('.kintoneplugin-input-checkbox input', node)
                            .prop('checked', checked)
                            .trigger('change');

                    }

                });

            $checkboxAll.find('label')
                .attr('for', 'checkbox-all');

            table.on('search', function () {
                $checkboxAll.find('input').prop('checked', false);
            });

        }
    });

    $('#download').remove();

    // ボタン配置
    $(buttonHtml).on('click', function (event) {

        // クリックイベントで選択されたレコードを取得
        var selected = [];

        for (var i = 0; i < table.data().count(); i++) {

            var row = table.row(i);
            var record = row.data();
            var node = row.node();

            // 選択されたレコードを配列に追加
            if ($(node).hasClass('selected')) {
                selected.push(record);
            }

        }

        // 0件の場合、処理を終了
        if (selected.length === 0) {
            return;
        }

        // zipファイル作成
        var zip = new JSZip();

        Promise.all(selected.map(function (record) {

            // レコード番号でフォルダ作成
            var folder = zip.folder(record['$id'].value);

            return Promise.all(record['file'].value.map(function ({ name, fileKey }) {

                // ダウンロード
                return kintoneUtility.rest.downloadFile({ fileKey }).then(function (blob) {
                    // フォルダにファイルを追加
                    folder.file(name, blob);
                });

            }));

        })).then(function () {

            // blobを作成
            zip.generateAsync({ type: 'blob' }).then(function (content) {

                // 保存処理
                saveAs(content, 'files.zip');

            });

        });

    }).appendTo(kintone.app.getHeaderMenuSpaceElement());

});

CSS

main.css
table.dataTable tbody th.control-cell,
table.dataTable tbody td.control-cell,
table.dataTable thead th.control-cell,
table.dataTable thead td.control-cell {
    padding: 0;
    text-align: center;
}

.control-cell .kintoneplugin-input-checkbox {
    display: inline-block;
    margin: 0;
}

.control-cell .kintoneplugin-input-checkbox-item {
    margin: 0;
}

.gaia-app-indexview-customview-html table.dataTable thead tr:first-child th,
.gaia-app-indexview-customview-html table.dataTable thead tr:first-child td {
    border-top: 0;
}

JS/CSS設定

JS

CSS

最後に

DataTablesはテーブルで何かを見せたいときに非常に便利です。
kintoneライクになることで、より活用の幅が広がるのではないでしょうか。

15
9
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
15
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?