Ext JS に関しては,新しい記事は Sunvisor Lab. ExtJS 別館 にあります。そちらもよろしくお願いいたします。
EditorGridPanlでEnterキーの動作を変更する
ExtJSのEditorGridPanelを使うとWebブラウザがExcelみたいになります。スゴイですねぇ。EditorGridPanelでは,Enterキーを押すと,セルの編集ができて,またEnterキーを押すと編集モードが終了します。この動作,これはこれでいいのですが,
数値入力の際などに,縦方向に連続入力したいことってよくあります。そんな時は
<数値><Enter><数値><Enter><数値><Enter><数値><Enter><数値><Enter>
と入力したいのですが,EditorGridPanelだと
<数値><Enter><down><Enter><数値><Enter><down><Enter><数値><Enter><down><Enter><数値><Enter>
と入力しなければなりません。これがちょっと面倒だと言われそうなので解決方法を探してみました。
参考
http://www.sencha.com/forum/showthread.php?76375
方法
EditorGridPanelのSelectionModelのonEditorKeyメソッドを再定義します。(次の例は ExtJS 3.2)
sm.onEditorKey = function(field, e){ var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor; if(k == e.TAB){ if(e.shiftKey){ newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this); }else{ newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this); } e.stopEvent(); }else if(k == e.ENTER){ var s = this.selection; var r = s.cell[0], c = s.cell[1]; newCell = g.walkCells(r + 1, c, 1, this.isSelectable, this); this.select(newCell[0], newCell[1]); if( ed ) ed.completeEdit(); }else if(k == e.ESC){ e.stopEvent(); ed.cancelEdit(); } if(newCell){ g.startEditing(newCell[0], newCell[1]); ed = g.activeEditor; } };
オリジナルのハンドラのリストの11行目あたりからを変更しています。Enterキーが押された時に,もとのハンドラは単に編集を終了していただけでしたが,次の行にセル移動して編集モードに戻すことをしています。これで,<数値><Enter><数値><Enter><数値><Enter>というオペレーションができるようになりました。
この作業をしていて思ったのですが,15行目で if( ed ) がないとそこでエラーが発生しています。エディタの編集モードは,このハンドラに来たときにはすでに終了しているので,edがnullだからです。同様に18行目の ed.cancelEdit() もエラーで落ちます。この二つっていらないんじゃないかと思うんですがねぇ。どうなんでしょう。
※:上記は,Version 3.2 あたりの頃のソースを元に編集しています。 3.3 になったら,onEditorKey がえらく簡単になっています。
// private onEditorKey: function(field, e){ if(e.getKey() == e.TAB){ this.handleKeyDown(e); } },
TAB キーの時にだけ,handleKeyDown() をコールしています。この流儀で,onEditorKey イベントを書き換えましょう。ExtJS 3.3 の場合です。
sm.onEditorKey = function(field, e){ var k = e.getKey(), g = this.grid, ed = g.activeEditor, newCell; if(e.getKey() == e.TAB){ this.handleKeyDown(e); }else if(k == e.ENTER){ var s = this.selection; var r = s.cell[0], c = s.cell[1]; newCell = g.walkCells(r + 1, c, 1, this.isSelectable, this); if( newCell ){ this.select(newCell[0], newCell[1]); if( ed ) ed.completeEdit(); this.handleKeyDown(e); } }; };
イベント処理ルーチンをすげ替えてしまうという手法は,簡単に機能拡張や挙動の変更ができますが,ExtJS 自体のバージョンが変わると,すべて作り直す必要がある可能性があることがわかりました。禁じ手に近いのかな。