【jQuery/DataTables】行に応じて違うモーダル表示

f:id:bonoponz:20201025190855p:plain

もくじ

データの準備

私はLaravelで実装しているのでcontrollerなどでてきますが、データの準備だけなのでLaravelは関係なく実装できます。

この続きからはじめます。

bonoponz.hatenablog.com

前の記事までは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">&times;</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"と連動させています。文字列の扱い方については↓。

bonoponz.hatenablog.com

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列でソート

f:id:bonoponz:20200904225337p:plain

Wadaさんの行をクリックします。

f:id:bonoponz:20200904225251p:plain

age列でソート

f:id:bonoponz:20200904225431p:plain

ソートの列を変更しても(行番号が変わっても)問題ありません。

Sugiyamaさんの行をクリックします。

f:id:bonoponz:20200904225441p:plain

ちゃんと選択した行を認識して中身が変更されました!!

個人的にとっても苦労した実装でした。

課題

もともとやりたかった、行クリックしたときに同じような動作にしたいな。

失敗例

以前投稿した記事にミスがあったので、今回修正して動作確認もちゃんとしたものを再投稿しました。

↓過去記事

bonoponz.hatenablog.com

参考URL

Javascript(jQuery)でBootstrap4のモーダルを表示・非表示 - Symfoware

jQueryプラグインのDataTablesでチェックボックスを表示 | 株式会社エイチ・オー・エス

jQuery textメソッドとhtmlメソッドの違いのサンプル | ITSakura