LoginSignup
10
9

More than 5 years have passed since last update.

SlickGridで行をフィルタリングするサンプル

Last updated at Posted at 2014-01-18

SlickGridのコンテキストメニューで行の追加と削除のサンプルの続きです。

フィルタリングのサンプル

本家ではmleibman.github.io/SlickGrid/examples/example-header-row.htmlにフィルタリングのサンプルがあります。

私が書いたフィルタリングのサンプルは
http://hnakamur.github.io/slickgrid_example/
にあります(ソースは https://github.com/hnakamur/slickgrid_example/

フィルタのテキスト入力欄の作成方法

グリッドの showHeaderRow オプションを指定すると列ヘッダー行の下にスクロール固定の行が1行追加されます。これのことをheaderRowと呼んでいます(列ヘッダーと紛らわしいですが)。 headerRowHeight オプションでその行の高さを指定します。

通常の行の高さはGrid Options · mleibman/SlickGrid WikiheaderRowHeightオプションのデフォルト値で25pxとなっています。

ここでは、フィルタ用にテキストフィールドを入れるので headerRowHeight はそれより大きめの30pxを指定しています。

js/example.js
  var options = {
    editable: true,
    autoEdit: false,
    multiColumnSort: true,
    showHeaderRow: true,
    headerRowHeight: 30,
    explicitInitialization: true
  };

headerRow の中身にテキストフィールドを作るためには上記のように explicitInitialization オプションをtrueにする必要があります。

そして、grid.onHeaderRowCellRendered にテキストフィールドを作る処理を記述します。その後、grid.init()を呼び出します。

js/example.js
  grid.onHeaderRowCellRendered.subscribe(function (e, args) {
    if (args.column.id === "id") return;
    var cell = $(args.node);
    cell.empty();
    $(document.createElement("input"))
      .attr("type", "text")
      .data("columnId", args.column.id)
      .val(columnFilters[args.column.id])
      .appendTo(cell);
  });

  grid.init();

データをフィルタリングする処理の実装

フィルタリングの実装は以下のようにします。ここではテキストフィールドに入力した値が部分一致していたらマッチとし、そうでない行は除外するようにしています。

js/example.js
  var columnFilters = {};
  function filter(item) {
    for (var columnId in columnFilters) {
      if (columnId !== undefined && columnFilters[columnId] !== "") {
        var c = grid.getColumns()[grid.getColumnIndex(columnId)];
        var val = item[c.field];
        if (val === undefined || val.indexOf(columnFilters[columnId]) === -1) {
          return false;
        }
      }
    }
    return true;
  }

フィルタリングのイベントハンドラの設定

フィルタリングのイベントハンドラを設定する処理は本家の例では以下のようなコードで、キーを押すたびにフィルタリングするようになっています。

  $(grid.getHeaderRow()).delegate(":input", "change keyup", function (e) {
    var columnId = $(this).data("columnId");
    if (columnId != null) {
      columnFilters[columnId] = $.trim($(this).val());
      dataView.refresh();
    }
  });

最後に、フィルタをDataViewに適用するためにsetFilterを呼びます。

js/example.js
  dataView.setFilter(filter);

jquery.japanese-input-changeプラグインを使った改良版

本家の例の実装だと、日本語の場合はIMEで変換中にもkeyupイベントが発火して、変換中の文字列でフィルタリングが実行され1件もヒットせずに全ての行が非表示になってしまうので使い勝手が悪いです。

冒頭に上げた私が書いたフィルタリングのサンプルではjquery.japanese-input-changeプラグインを使って、IMEで未確定な場合とキー入力が続いている場合はフィルタリングを実行しないようにしています。IME確定済みでキー入力が落ち着いてから0.5秒後にフィルタリングが実行されます。

フィルタリングのイベントハンドラは以下のようにして設定します。jQueryのライブイベントを使うように指定しているので、grid.init()の前で実行しても問題ありません。

https
  function updateFilters() {
    var columnId = $(this).data("columnId");
    if (columnId != null) {
      columnFilters[columnId] = $.trim($(this).val());
      dataView.refresh();
    }
  }
  $(grid.getHeaderRow()).japaneseInputChange('input[type=text]', 500,
      updateFilters);

  grid.init();

jquery.japanese-input-changeプラグインについては、日本語入力環境でキー入力が一段落したらハンドラを実行するjQueryプラグインを作ってみた - Qiitaをご参照ください。

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