【jQuery/DataTables】行に応じて違うモーダル表示
もくじ
データの準備
私はLaravelで実装しているのでcontrollerなどでてきますが、データの準備だけなのでLaravelは関係なく実装できます。
この続きからはじめます。
前の記事まではIDをインデックス番号で取得していましたが、今後は配列にIDの項目を付与しておきます。
$data = [ [ 'ID' => 0001, 'name' => 'Wada', 'sex' => 'Male', 'age' => 35, ], [ 'ID' => 0002, 'name' => 'Sugiyama', 'sex' => 'Male', 'age' => 20, ], [ 'ID' => 0003, 'name' => 'Fukui', 'sex' => 'Female', 'age' => 49, ], [ 'ID' => 0004, 'name' => 'Ono', 'sex' => 'Female', 'age' => 33, ], ];
HTML
テーブル
<td>
タグについては、jQueryで設定するのでここでは不要です。
<table id="exampleTable" class="table hover nowrap"> <thead> <tr> <th scope="col">ID</th> <th scope="col">name</th> <th scope="col">sex</th> <th scope="col" class="ageColumn">age</th> <th scope="col">詳細</th> </tr> </thead> </table>
モーダル
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel"> // ★ <div class="modal-dialog modal-dialog-centered"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel"></h5> <button type="button" class="close" data-dismiss="modal" aria-label="閉じる"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">閉じる</button> </div> </div> </div> </div>
ここで重要なのは★のid="exampleModal"
です。jQueryで操作する時、このIDを読み取ってモーダル を実装します。
jQuery
json の定義
$(document).ready(function() { const json = @json($data) // DataTablesやモーダルの処理 }
jsonデータはDataTablesとモーダルの両方の処理内で使用するので、スコープを外に出しています。
DataTables
$('#exampleTable').DataTable({ data: json, columns: [ {data: 'ID' }, {data: 'name' }, {data: 'sex' }, {data: 'age' }, { bSortable: false, data: null, sDefaultContent:'', }, ], "fnCreatedRow": function( nRow, aData, iDataIndex ) { $('td:eq(4)', nRow).append(`<a href="" class="modalClick" data-toggle="modal" data-modal-type="example" data-index="${iDataIndex}" data-id="${aData.dataId}">詳細</a>`); }, columnDefs: [ { targets: 'ageColumn', width: 40 }, ], });
ちょっと詳しくみていきましょう。
// 行追加時イベント "fnCreatedRow": function( nRow, aData, iDataIndex ) { // nRow:追加された行のhtml要素 // aData:内部で保持している行の値 // iDataIndex:行番号 $('td:eq(4)', nRow).append(`<a href="" class="modalClick" data-toggle="modal" data-modal-type="example" data-index="${iDataIndex}" data-id="${aData.dataId}">詳細</a>`); }, // data-属性でデータをモーダルに渡す // 5列目(jqueryセレクタは0番から振られるので4)のtd要素を指定 // 指定したtd要素にappendメソッドでHTML要素を追加
bVisible: false
にされた列はnRow
には含まれませんので、指定している場合は注意です。
appendメソッドを使って、$('td:eq(4)', nRow)
に文字列を渡します。
$(‘セレクタ’).append(‘追加するもの’); $("ul").append("<li>追加</li>"); // 例
HTMLもタグとして挿入できます。ただし、更新ではなく下にどんどん追加されていきます。
クリックでモーダル表示
data-
属性で渡したデータを駆使します。
$('.modalClick').click('show.bs.modal', function (event) { const dataId = $(this).attr('data-id') const dataIndex = $(this).attr('data-index') const dataModalType = $(this).attr('data-modal-type') const clickButton = $(event.relatedTarget) const personalData = json[dataIndex] var modal = $(`#${dataModalType}Modal`) modal.find('.modal-title').text("ここはタイトルです") modal.find('.modal-body').html(`<p>名前は${personalData.name}です。</p><p>年齢は${personalData.age}です。</p>`) modal.modal(); });
ちょっと詳しくみていきましょう。
$(`#${dataModalType}Modal`)
は変数を埋め込んで、HTMLのモーダルで前述した★のid="exampleModal"
と連動させています。文字列の扱い方については↓。
const dataModalType = $(this).attr('data-modal-type') // data-modal-typeの「example」を変数に代入 var modal = $(`#${dataModalType}Modal`) // 文字列の連結を使い「#exampleModal」をjQueryのセレクタを指定
指定したクラスに、文字列を渡します。
modal.find('.modal-title').text("ここはタイトルです") // textメソッドは、htmlのタグを文字としてそのまま出力 modal.find('.modal-body').html(`<p>名前は${personalData.name}です。</p><p>年齢は${personalData.age}です。</p>`) // htmlメソッドは、htmlのタグを解釈して出力 // appendメソッドを使うと、クリックするたびに追加されていってしまうので、ここではhtmlメソッド使用 modal.modal(); // モーダルを表示
動作確認
ID列でソート
Wadaさんの行をクリックします。
age列でソート
ソートの列を変更しても(行番号が変わっても)問題ありません。
Sugiyamaさんの行をクリックします。
ちゃんと選択した行を認識して中身が変更されました!!
個人的にとっても苦労した実装でした。
課題
もともとやりたかった、行クリックしたときに同じような動作にしたいな。
失敗例
以前投稿した記事にミスがあったので、今回修正して動作確認もちゃんとしたものを再投稿しました。
↓過去記事
参考URL
Javascript(jQuery)でBootstrap4のモーダルを表示・非表示 - Symfoware