2017年9月30日土曜日

DataTablesに追加した独自の検索情報をsaveStateで管理する方法


実現までに調査と時間を要したので、メモを共有します。

背景

DataTablesとは、一覧表示をサポートしてくれる、jsのライブラリです。


DataTablesにはsaveStateというオプションがあり、これを有効にするとブラウザのローカルストレージに情報を自動で保存してくれます。
そのため、ページを更新したり、別のページに移動して戻ってきても、参照元のデータが変わっていなければ、前回表示したのと同じ情報を表示してくれます。

そんな便利なsaveStateオプションなのですが、ajax通信に追加した独自のパラメータはローカルストレージに保存されません。
そのため、独自パラメータを設定した一覧は、ページの更新などをすると更新前とは違う一覧が表示されてしまいます。

色々調べた結果、stateLoadParamsとstateSaveParamsを利用して自分の期待する一覧を作れました。
その方法をザックリと共有します。

実現方法

コードはこちらです。
<select name="country_id" id="country_id">
  <option value="">please select</option>
  <option value="1">Country A</option>
  <option value="2">Country B</option>
  <option value="3">Country C</option>
</select>

<table id="admin-shops">
  <thead>
    <tr>
      <th>name</th>
    </tr>
  </thead>
</table>

<script>
  $('#country_id').change(() => {
    dataTable.draw()
  })
  var getExtraSearchParams = () => {
    return {
      country_id: $('#country_id').val()
    }
  }
  var initExtraSearchInputs = (ex_params) => {
    if (ex_params === undefined) return
    if (ex_params.country_id) {
      $('#country_id').val(ex_params.country_id)
    }
  }
  dataTable = $('#admin-shops').DataTable({
    stateSave: true,
    processing: true,
    serverSide: true,
    stateLoadParams: (settings, data) => {
      initExtraSearchInputs(data.extra_search_params)
    },
    stateSaveParams: (settings, data) => {
      data.extra_search_params = getExtraSearchParams()
    },
    ajax: {
      url: "/admin/shops.json",
      data: (data) => {
        data.extra_search_params = getExtraSearchParams()
      }
    },
    columns: [
      {data: "name"}
    ]
  })
</script>

getExtraSearchParamsを利用して、stateSaveParamsとajax.dataにextra_search_paramsを設定しています。
initExtraSearchInputsを利用して、stateLoadParamsから保存されたextra_search_paramsを取得し、inputを初期化しています。

ajaxの通信先のサーバーのコードは複雑なのでここでは紹介できませんが、下記のような想定です。
  • リクエストのcountry_idがcountry Aのid -> country Aに属するshopだけを返す
  • リクエストのcountry_idがcountry Bのid -> country Bに属するshopだけを返す
  • リクエストのcountry_idが空の場合 -> countryに関するフィルタリングは行わない

まとめ

DataTablesでsaveStateの機能を利用して、独自の検索フォームの情報も一覧読み込み時に再現することができました。
ただし、getExternalSearchParamsを2箇所で呼び出しているのが気になるので、1箇所の設定で済む方法をご存知の方がいらっしゃれば、コメント欄か公式フォームに回答していただけると嬉しいです。

共有する情報は以上です。

0 件のコメント :

コメントを投稿