Handsontableライブラリの更新時に気をつけるべきこと

v7.0.0 以降 MIT ライセンスではなくなったので、GROWI は v6.2.2 に留まり、以降のバージョンアップは諦める -- 2019.08.17 Yuki Takei

相談はSlackで@utsushiiroにメンションください.

今の仕様

Context Menu について

Context Menuは右クリックしたときにでてくるやつ.

全部で7項目あるが, 以下の6項目はHandsontableが提供している機能をそのまま使っている. 各種操作による動作はそれぞれ名前の通り.

  • insert row above
  • insert row below
  • insert column left
  • insert column right
  • remove row
  • remove column

Align columnsについては自作. これによって現在選択しているセルが含まれる各カラムについてのアラインメントを一括変更できる.

アラインメントについて

  • 新規テーブル作成時は指定なし(左揃え)になっている.
  • 既存のテーブルを読み込んで起動した場合は, 既存のアラインメントが反映された状態で表示される.
  • カラムをドラッグによって移動させてもアラインメントは保持される
  • Context Menuによって選択セルが含まれるカラムのアラインメントを変更できる
  • ツールバーにあるボタンによって選択セルが含まれるカラムのアラインメントを変更できる
  • Context Menuにあるinsert rowで挿入したrowの各セルのアラインメントはそのセルのカラムのアラインメントとは同期されず, 必ず左揃えで表示される. ただしsaveすると反映される.

カラムとローの移動について

  • カラムのヘッダー部分を選択して左右にドラッグさせることでカラムの位置を変更できる
  • ローのヘッダー部分を選択して上下にドラッグさせることでローの位置を変更できる

カラムの移動については, 移動を行ったあとにImport機能でテーブルデータをインポートするとインポートしたデータのカラムの並びがインポート前の移動操作の影響を受けて並び変えられてしまう.

以下のようなテーブルを

col1col2col3
123

次のように2列目, 3列目を入れ替えた上で

col1col3col2
132

以下のようなテーブル(ここではcsv)をImportで読み込ませると

col1, col2, col3 a, b, c

このようにはならずに

col1col2col3
abc

こうなる

col1col3col2
acb

Import機能について

ツールバーのImport Dataを押すとアコーディオンでImportゾーンがでてくる. CSV, TSV, HTML形式で表現されるデータを読み取れる.

サイズ調整について

デフォルトでは各カラムのサイズ(width)、各ローのサイズは(height)は内容に応じて自動調節される. ただし自動調節ではwidthは80px ~ 400pxの値に制限される.

各カラムやローのヘッダーの境界線部分を左右にドラッグすることによりサイズ調節することができる. これによってサイズを調節したカラムは以後サイズの自動調節がオフになる. ただし, カラムの移動を行った場合, すべてのカラムについて再度自動調節がオンになる.

リセットボタンの挙動について

モーダル右下にあるResetボタンによってテーブルのデータをもとに戻すことができる. ただし, 以下の点に注意.

  • テーブルデータをImport機能でImportして上書きした場合, 以降のResetではそのImportしたデータに戻る
  • ドラッグによるカラムとローの移動を行った場合, それらの操作による位置関係の変更はリセットされない

後者の例としては, 以下のようなテーブルを

col1col2col3
123

次のように2列目, 3列目を入れ替えた上で値を一部変更する

col1col3col2
13222

ここでResetすると以下のようにはならずに

col1col2col3
123

このようになる

col1col3col2
132

現在の仕様に関連したウォッチするべきHandsontableのIssue

beforeColumnResizeHandlerの引数バグのIssue

https://github.com/handsontable/handsontable/issues/3328 external_link

これはカラムとローの移動についての実装に影響を与えている. このIssueにあるようにbeforeColumnResizeHandlerに正しい情報(操作しているカラムインデックス)がわたってこないため, 代わりにafterColumnResizeHandlerを利用している. このIssueがfixされると, 処理をbeforeColumnResizeHandlerにうつして, おそらくforce re-renderしている処理を消しても動くようになる.

HandsonModal.jsxから抜粋
beforeColumnResizeHandler(currentColumn) { /* * The following bug disturbs to use 'beforeColumnResizeHandler' to store column index -- 2018.10.23 Yuki Takei * https://github.com/handsontable/handsontable/issues/3328 * * At the moment, using 'afterColumnResizeHandler' instead. */ // store column index // this.manuallyResizedColumnIndicesSet.add(currentColumn); } afterColumnResizeHandler(currentColumn) { /* * The following bug disturbs to use 'beforeColumnResizeHandler' to store column index -- 2018.10.23 Yuki Takei * https://github.com/handsontable/handsontable/issues/3328 * * At the moment, using 'afterColumnResizeHandler' instead. */ // store column index this.manuallyResizedColumnIndicesSet.add(currentColumn); // force re-render const hotInstance = this.hotTable.hotInstance; hotInstance.render(); }

manualColumnMoveの仕様についてのIssue

https://github.com/handsontable/handsontable/issues/5591 external_link

これはカラムとローの移動についてリセットボタンの挙動についての仕様に影響を与えている. 具体的には,

カラムの移動については, 移動を行ったあとにImport機能でテーブルデータをインポートするとインポートしたデータのカラムの並びがインポート前の移動操作の影響を受けて並び変えられてしまう.

ドラッグによるカラムとローの移動を行った場合, それらの操作による位置関係の変更はリセットされない

なお, このIssueがfixされる, つまりloadData の仕様が変わる場合内部実装の大部分に影響を与えると思われるので要注意. たぶん下に書いているようにほぼ作り直す必要がでてくる.

内部仕様について

基本的にHandsontableModal.jsxにめちゃ詳しくコメント書いてあるので読んで. 読めばわかる.

現状HandsontableModal(React)側で管理している値(ステート)とHandsontableの内部の値を各種操作時にできる限り同期させているが, ReactのライフサイクルとHandsontable内部のライフサイクルがあまりうまく同期させれない & ちょくちょくHandsontableのフック周りにバグがあったりで正直起動時と保存時だけ同期するようにしちゃった方がいい気がする.