
九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて。最近になってですが、とあるブログで見た内容を思い出すことがありました。
その内容は要約すると、「VueやReactはすごい!でもちょっとしたものならjQueryのプラグインを使った方が早いよ。」といったものでした。
なぜこれを思い出したかというと、有名jQuery
プラグインの「DataTable」をがとても便利だと再認識したからです。
そして、今回はそんなDataTable
のユーザビリティを向上させるカスタマイズ法をご紹介したいと思います。
それは、
各行にチェックボックスをつけてデータを複数削除できるようにする機能
です。
つまり、これです。(いわゆるBulk Delete
と呼ばれる機能ですね)
このチェックボックスがあれば、一気にデータ削除できて便利ですし、削除ボタンは1つあればいいので省スペースも実現できると思います。
ということで、今回はこのチェックボックス+複数削除をVue
とDataTable
で連携させて実現してみます。(最後にソースコードをダウンロードできます)
ぜひ皆さんのお役に立てると嬉しいです
開発環境: Vue 2.6
目次 [非表示]
やりたいこと
具体的に今回実装する機能は次のとおりです。
- DataTableの各行にチェックボックスをつけて選択できるようにする
- 選択したデータのIDをVueの変数へ格納できるようにする
- 「全てをチェック」を使って全選択/全解除が可能
- チェックの状況によって、削除ボタンを表示/非表示
- 削除ボタンが押されたら特定のメソッドを実行する
では、順を追って見ていきましょう!
環境を整える
まずは、今回必要になるパッケージやCSS
を読み込むのですが、DataTable
は本家が用意してくれているこちらのCDNページから(Bootstrap 4
向け)を使うことにします。
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/dataTables.bootstrap4.min.css">
</head>
<body>
<div id="app" class="container">
<!-- ここにDataTableをつくる -->
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/dataTables.bootstrap4.min.js"></script>
<script>
new Vue({
el: '#app'
});
</script>
</body>
</html>
なお、Vueの基本形も同時につくっておきました。
DataTableを表示する
では、メインとなるDataTable
を表示してみましょう。
まずはHTMLコードです。
<div id="app" class="container">
<table id="table" class="table table-striped table-bordered table-sm">
<thead class="thead-dark">
<tr>
<th>
<label>
<input id="all_check" type="checkbox"> 全てをチェック
</label>
</th>
<th>ID</th>
<th>名前</th>
<th>年齢</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
ここで大事なのは後で利用するテーブルのid
とチェックボックスの全選択/解除をするためのチェックボックスです。
次に、ページが読み込まれたら実行されるmounted()
に以下のコードを追加します。
new Vue({
el: '#app',
mounted() {
$('#table').DataTable({
data: [
{ id: 1, name: '山田太郎', age: 25},
{ id: 2, name: '佐藤次郎', age: 33},
{ id: 3, name: '田中三郎', age: 15},
],
columns: [
{
data: 'id',
render: (id) => {
return '<input class="delete_check" type="checkbox" value="'+ id +'">';
},
orderable: false
},
{ data: 'id' },
{ data: 'name' },
{ data: 'age' },
],
order: [[ 1, 'asc' ]],
language: {
url: 'https://cdn.datatables.net/plug-ins/1.10.20/i18n/Japanese.json'
}
// ここでその他オプションを設定できます
});
}
});
ここで重要なのは、columns
内です。
DataTable
ではrender
を指定することで動的に表示内容を変更することができます。なので、この場所で後でセレクタとして使うclass="delete_check"
を指定し、value
に各IDをセットします。
そしてもう一つ、order
の部分ですが、この記述がないと0番目、つまりチェックボックスの列がデフォルトで並べ替えの対象になってしまうので、その隣の1番目(ゼロから始まる2番目の数字)を指定しています。
あとは、DataTable
の基本的な内容ですので、こちらのページ(英語)で確認するといいでしょう。(いつかこのブログでオプションもまとめたいと思います)
これを実行すると以下のようになります。
※ これだけのコードでここまで実現できるのはやっぱり開発者としては嬉しいですね。ちなみに、オプションを使えばAjaxでのデータ通信も可能です。詳しくは、LaravelとDataTable.jsをAjaxで連携させる方法をご覧ください
チェックボックスの全選択/解除ができるようにする
では、「全てをチェック」のすぐ横にあるチェックボックスがクリックされたら、全選択/解除ができるようにしていきましょう。
まずはチェックボックスの値が変更されたときのイベントcheckAll
を準備します。(ちなみに、Vue
では変数が必要ない場合は()
を省略できます)
<input id="all_check" type="checkbox" @change="checkAll"> 全てをチェック
そして、Vue
の中にmethods
をつくり、その中にcheckAll()
を用意します。
new Vue({
el: '#app',
methods: {
checkAll(e) {
const checked = $(e.target).prop('checked'); // 全選択/解除どちらか
$('.delete_check').each((i, element) => { // 全てのチェックボックスの値を変更
$(element).prop('checked', checked).change();
});
}
},
// 省略
});
checkAll()
の中身はjQuery
のみのコードになっています。(個人的には少し懐かしいです)
なお、このコードの中でchange()
をつけているのは、次の項目でつくるchange
イベントで起動するためです。
$(element).prop('checked', checked).change(); // changeイベントを送出
これで、全選択と解除ができるようになりました。
チェックされたIDをVueと連携させる
では、各行のチェックボックスのtrue
/false
が変更になった時に実行する部分をつくっていきます。
チェックされたIDを格納&取得するコードをつくる
まずはチェックされたIDに関する部分です。
new Vue({
el: '#app',
data: {
checkedIds: []
},
methods: {
// 省略
getCheckedIds() { // チェックされているIDを取得
let ids = [];
$('.delete_check:checked').each((i, element) => {
let id = $(element).val();
ids.push(id);
});
return ids;
}
},
// 省略
});
この中では、まずdata
にcheckedIds
という「今チェックされているID」を格納する変数を用意します。
そして、その変数のために「今チェックされているID」を取得するメソッドgetCheckedIds()
をつくります。
チェックボックスが変更されたときのchangeイベントをつくる
続いて、チェックボックスのtrue
/false
が変更された時に実行されるchange
イベントをつくります。
new Vue({
// 省略
mounted() {
// 省略
$(document).on('change', '.delete_check', () => {
this.checkedIds = this.getCheckedIds();
if(this.checkedIds.length === 0) {
$('#all_check').prop('checked', false);
}
});
}
});
ここで重要なのが、以下のようにセレクタを直接指定していないところです。
// これはうまく動きません
$('.delete_check').on('change', () => {
// 省略
});
なぜならこの書き方は「すでに存在している、セレクタが”.delete_check”のもの」にイベントをつけるという意味だからです。
つまり、DataTable
やVue
のv-for
のように後から要素がつくられる場合は、イベントをつけることができないわけです。
こんな場合はdocument
本体にイベントをつける書き方にすると、後から作成される要素であってもイベントが起動するようになります。
$(document).on('change', '.delete_check', () => {
// 省略
});
※ VueとjQueryの連携をする場合はこのテクニックはとても役に立ちます
また、このchange
イベントの中では先ほどのgetCheckedIds()
を使ってcheckIds
を更新し、さらにチェックされているものがなくなっている場合は、「全てをチェック」のチェックボックスも自動で解除するようにしています。
削除ボタンをつくる
では、最後にいづれかのチェックボックスがtrue
になった時に削除ボタンを表示できるようにしてみましょう(チェックされてなければ非表示にします)
まずはHTML側にボタンを用意します。
<div id="app" class="container">
<!-- 省略 -->
<div v-if="hasCheckedIds">
<button type="button" class="btn btn-primary" @click="onDelete">削除する</button>
</div>
</div>
そして、この中で指定したhasCheckedIds
をcomputed
に作成します。
new Vue({
// 省略
computed: {
hasCheckedIds() { // チェックされたものがあるかどうか
return (this.checkedIds.length);
}
},
// 省略
});
これでチェックの有無によって削除ボタンの表示/非表示が切り替わるようになりました。
そして、同じくこのボタンをクリックしたときに実行するonDelete
もつくっておきましょう。
new Vue({
// 省略
methods: {
// 省略
onDelete() {
const params = {
checked_ids: this.checkedIds
};
console.log(params)
// ここでaxiosなどでAjax送信して削除
// axios.post(url, params)
// .then((response) => {
//
//
//
// });
}
},
// 省略
});
はい!これで全て完了です。
お疲れ様でした
テストしてみる
では、今回のコードを実際に動かしてテストしてみます。
うまくいきました!
ダウンロードする
今回実際に開発した内容を以下からダウンロードすることができます。
※ パッケージは全てCDN経由なので展開したらすぐ実行できますよ!
Vue + DataTableにチェックボックスで複数削除の機能をつけるおわりに
ということで今回は、有名jQuery
プラグインのDataTable
に関する話題をお届けしました。
React
やAngular
、Vue
などのリアクティブなパッケージが登場したしたことでjQuery
は昔ほどの人気ではなくなっているとは思いますが、とはいえやはり開発に有効な手段であることに変わりはないな、と再認識しました。
特にに今のところBootstrap
はjQuery
が必須となっていますので、そうなるとDataTable
のようなプラグインも頭にいれておいて損はしないのではないと思います。
また、Vue
とjQuery
の連携は少しテクニックが必要ですが覚える内容はそれほど多くないですし、それほど手間もかからないです。
ぜひ皆さんも「適材適所」な開発をしてみてくださいね。
ではでは〜!