LoginSignup
0
0

More than 5 years have passed since last update.

Dojo1.8+のグリッドはイベントリスナーとの相性が悪い。 なので、時間差攻撃で無理からフォーカスしてやる。

Last updated at Posted at 2016-01-08

(DOJO1.9ですが、多分、レガシーでもconnect使えば大丈夫です。)

Dojo の グリッドはイベントリスナーとの相性が悪い。なので、時間差攻撃で無理からフォーカスしてやる。。。

ご存知のように、Data Grid, Enhanced Grid などはすでにイベントに関するマネジャーが存在するが、なかなか思うようにうごいてくれない。
書き込みが行われるときに使うのは、大体以下のイベントが主流なんじゃないかな。上から順に呼び出されます。
その時に、できればdojox.grid._Eventsを確認して欲しい。

onStartEdit: function(inCell, inRowIndex){
セルに内容を書き込む時にかならず最初に呼び出される。
inCell: オブジェクト
-- グリッドのコラムにあるプロパティーを含むセルのオブジェクト。
inRowIndex: Integer
-- 現在のグリッドの行のインデックス
},

onApplyCellEdit: function(inValue, inRowIndex, inFieldIndex){
実際にセルに内容を書き込む時に呼び出される。
inValue: String
-- 現在のセルエディターに登録されている値。
inRowIndex: Integer
-- 現在のグリッドの行のインデックス
inFieldIndex: String
-- すばらしい!グリッドのデータストアのインデックスがここにある!とういことは、ItemFileWriteStoreなどの『コラッ』系のメモリーオブジェクトにもつかえる!その場合は_arrayOfAllItemsや、_itemsByIdentityなどを使おう。
この場合、値がここで変更するたびに

if (inFieldIndex === "target"){
      yourobject.fetchItemByIdentity({
         identity : inRowIndex, 
         onItem : function (item) {
         yourobject.setValues(item, inFieldIndex, inValue);
         tabledata.items = yourobject._arrayOfAllItems;
         yourgrid.render();
   });
}

として"target"フィールドの変更をメモリーに書き込んでやってください。
tabledataは変更後のバックアップ。この状態だったらそのままItemFileWriteStoreに書き換えてやれるんで。。。と思ったんですが、この部分はちゃんと使えてないみたいですね。バラすのであれば、配列で十分だったかもです。でも、上のようにバックアップは簡単なんですねぇ。問題は最下部のメモリの更新です。memoryをつかってみたんですが、なぜかうまくいきませんでした。。。とほほ。。。
本当は、yourobject._arrayOfAllItems = tabledata.items こうしたかったんだよぉ~。

ところで、この場合、面倒でも下記の記述が必要になってきます。おかしいなぁ。。。DOJO指南書にはもっと簡単なように書いてあったと思ったけど、これしか上手くいかなかった。今度もうちょいつめてみたいと思います。とりあえず、今はフォーカスにフォーカスして。

var tabledata = { identifier:'id', items:[] };
var vYourData = [];

yourobject.save();
yourobject.close();
yourobject.clearOnClose = true;
vYourData = []; /* ここまでして、やっとオブジェクトのデータを変更できます。 */
for (var i=0;i<tabledata.items.length;i++){
   var vTarget = tabledata.items[i].target;
   var vTarget_2 = tabledata.items[i].target_2;
   vYourData.push({id:i,target:value1, target_2:value2});
}
yourobject.data = {identifier:'id',items:vYourData};
yourobject.save();
yourobject.close();
yourgrid.render();  

ってな具合です。。。
。。。そこでっ!!!(やっと本題に入れる)

タブなんかで次のセル(target_2)に入って出て、そして自動的にもう一行足して、その新しい行のフィールドのtargetにフォーカスして書き込み可にして。。。っえっ?できないっ!!!
。。。そうなんです。。。これなんです。

『Dojo の グリッドはイベントリスナーとの相性が悪い』

さぁ、ここで、時間差攻撃をしかけましょう!!!
フォーカスが必要な場合、もちろん、思ったようにオブジェクトがグリッドと連携して新しい行が作れない場合も、今回このちょっとした邪道ともいえる方法で乗り切ってみました。

window.setTimeout(function() {
   yourgrid.selection.setSelected(yourgrid.selection.selectedIndex, false); /* ここで一度現在行のフォーカスが外れます。必要あるときにどうぞ。 */
   yourgrid.focus.setFocusIndex(お好きなrowIndex, お好きなcell); /* セルのプロパティーにはすでにコラムのプロパティーも入っているのでフォーカスを直接してくれます。 */
   yourgrid.edit.setEditCell(現在フォーカスしてるcell, お好きなrowIndex);  /* ここで、書き込みモードのテキストウィジットをアクティブにしてくれます。 */
  /* これでもいいかな? */
   yourgrid.edit.setEditCell(yourgrid.focus.cell, お好きなrowIndex);  /* ここで、書き込みモードのテキストウィジットをアクティブにしてくれます。 */
  /* ************************ */
},30);

},

onApplyEdit: function(inRowIndex){
実際にセルに内容が承認された時に呼び出される。
inRowIndex: Integer
-- 現在のグリッドの行のインデックス
}

とにかく、グリッドはイベントリスナーと相性が悪いです。
このsetTimeoutを使ったとしても、どうしても長くほっとくと、javascript errorがでたりなんかもします。
単純なものであれば、dGridを使ったほうがよいかも。

読んでいただいてありがとうございました。

0
0
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
0
0