4
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PureJSでExcelライクなセル編集UIを実装

Posted at

※本記事の実装コードはこちらhttps://jsfiddle.net/jnado3g5/1/

はじめに

個人的な興味がきっかけですが、Excelライクなセル編集UIをJavaScriptで作成する際の課題として、「キー押下と同時にセル編集を開始する」という仕様をどう実現するか、少々難しい問題があります。
厄介なのが日本語入力で、実際、(おそらく)有名な商用ライブラリであるWijimo FlexGridでも、日本語入力を含むキー押下とセル編集開始は同時に行えないみたいです。
しかし、Googleスプレッドシートではそれが実現されているため、技術的に不可能ではなさそうです。

そこで、「キー押下と同時にセル編集を開始する方法」を調べて、実際に検証を行った結果を記します。

仕様

メインは「キー押下と同時にセル編集を行う方法」ですが、せっかくなので編集に関わるUIを一通り検証実装してみました。
なお、編集機能に焦点を当てているため、それ以外(行列追加削除等)は一切考えていません。

セル選択イメージ:
image.png

入力イメージ:
image.png

  • セル対してmousedownするとセルが選択されます
  • セル選択された状態で次の動作をします
  • F2キーで既存の値の編集開始します
  • 通常の入力(Backspace、数値、アルファベット、日本語等)で新規入力開始します
  • セルをダブルクリックすると既存の値の編集開始します
  • Delキーで既存の値をクリアします(編集開始しません)
  • セルからフォーカスが外れる(セル部分以外をmousedownする)と、上記のようなセル編集開始が行われなくなります(編集開始には再度フォーカスが必要)
  • セル編集中、次の動作をします
  • Enterキーを押されると入力終了して、入力された値をセルに反映します
  • Escapeキーを押されると入力終了して、入力された値を破棄します
  • フォーカスが外れると入力終了して、入力された値をセルに反映します

動作確認環境

次の環境で動作確認を行いました。なおOSはWindows10です。

  • Chrome
  • FireFox
  • Edge
  • IE11
  • Opera

キー押下と同時にセル編集を開始する方法

わかりやすく、実際は隠れている(y座標位置が-10000px)input要素を目に見えるようにすると、セル選択時は次のような状態になっています。
image.png

input要素にフォーカスが当たっているので、要素に対するinputイベントが拾えます。
初回inputイベント発生時、input要素をセルの位置に移動させれば、あたかも「キー押下と同時にセル編集を開始する」ようなUIが出来上がります。
image.png

ただし、Backspaceキーではinputイベントが拾えないので、別途keydownイベントを拾って制御します。

その他工夫

上記の方法で実装を行う場合、input要素に対して「編集前の待機状態 → 編集中 → 編集完了」と状態が遷移し、各状態で必要なイベントが異なります。
そのため、「次の状態に移ったら前の状態で登録していたイベントは破棄する」といった実装を組み込んでみました。
結果、ソースコードの見通しが良くなったかなという個人的な感想を持っています。

おわりに

目指せ!個人開発でWijimo FlexGrid越え!(厳しい)

4
6
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
4
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?