0

I'm trying to make the TAB key navigate on my dGrid. I have used as a base the solution found at Dgrid set focus on cell, but there are a couple of issues I'm running into which I couldn't solve so far.

Below you can find the block I'm using now; Not all columns have editors, so for I added a var do the element definition to select the next column instead of doing a right. I also added support for SHIFT+TAB to make backwards navigation possible. MT4.prje.grids[gridId]is the dGrid instance. There might be various on the page.

The grid is created with

MT4.prje.grids[gridId] = new (declare([OnDemandGrid, Keyboard, Selection, CellSelection]))(gridInfo, gridId);

where gridInfo has the column definitions and the store. The store is created as:

new Observable(new Memory({'data': {}, 'idProperty': 'id'}));

The editors are usually TextBox, NumberTextBox and Select dijit widgets, all set to autoSave.

aspect.after(MT4.prje.grids[gridId], "edit", function (promise, cellNode) {
    if (promise === null) return;

    promise.then(function (widget) {
        if (!widget._editorKeypressHandle) {
            widget._editorKeypressHandle = on(widget, "keypress", function (e) {

                for (var rowId in MT4.prje.grids[gridId].selection) {
                    break;
                }
                for (var columnId in MT4.prje.grids[gridId].selection[rowId]) {
                    break;
                }

                if (e.charOrCode == keys.TAB) {
                    e.preventDefault();

                    var cellToEdit = null,
                        cellEdited = MT4.prje.grids[gridId].cell(rowId, columnId);

                    if (e.shiftKey) {
                        if (cellEdited.column.previousEditor === undefined) {
                            rowId = parseInt(rowId) - 1;
                            if (MT4.prje.grids[gridId].row(rowId).element !== null) {
                                for (var lastColumnId in MT4.prje.grids[gridId].columns) {}
                                cellToEdit = MT4.prje.grids[gridId].cell(rowId, lastColumnId);
                            }
                        } else {
                            cellToEdit = MT4.prje.grids[gridId].cell(rowId, cellEdited.column.previousEditor);
                        }
                    } else {
                        if (cellEdited.column.nextEditor === undefined) {
                            var firstColumnId = null;
                            rowId = parseInt(rowId) + 1;
                            if (MT4.prje.grids[gridId].row(rowId).element === null) {
                                var fields = {};
                                for (var cId in MT4.prje.grids[gridId].columns) {
                                    if ((cId != 'excluir') && (firstColumnId === null)) {
                                        firstColumnId = cId;
                                    }
                                    fields[cId] = '';
                                }
                                MT4.prje.addRowToGrid(gridId, fields);
                            } else {
                                for (var cId in MT4.prje.grids[gridId].columns) {
                                    if (cId != 'excluir') {
                                        firstColumnId = cId;
                                        break;
                                    }
                                }
                            }

                            cellToEdit = MT4.prje.grids[gridId].cell(rowId, firstColumnId);
                        } else {
                            cellToEdit = MT4.prje.grids[gridId].cell(rowId, cellEdited.column.nextEditor);
                        }
                    }

                    if (cellToEdit) {
                        MT4.prje.grids[gridId].deselect(cellEdited);
                        MT4.prje.grids[gridId].select(cellToEdit);
                        MT4.prje.grids[gridId].edit(cellToEdit);

                    }
                }
            });
        }
    });
});

Even ignoring the new line part, there are a couple of errors that happen. First of all, the editor barely pops into existence and them disappears, together with the selection. Sometimes when tabbing to an empty column, the editor will be filled with the values of the previous editor. Is there a way to do it more consistently?

What I'm figuring is that there is a race condition happening on the sharedEditor (they are set to editOn: focus). I tried wrapping the deselect/select on a dojo.on('blur') and emit it. But that doesn't get consistently correct with the dijit/form/Select widgets. Is there a better event that I can call for it?

I also tried changing the final block to:

if (cellToEdit) {
    on(cellToEdit.element, 'focus', function(){
        MT4.prje.grids[gridId].select(cellToEdit);
    });

    on(cellEdited.element, 'blur', function(){
        MT4.prje.grids[gridId].deselect(cellEdited);
        on.emit(cellToEdit.element, 'focus', {'bubble': true, 'cancelable': false});
    });

    on.emit(cellEdited.element, 'blur', {'bubble': true, 'cancelable': false});
}

But that gives two errors:

  1. If I do make changes to a cell it does not go to the next editor. Does not even select it.
  2. The first time I move from an empty cell to another empty cell it doesn't work either.

Anyone got any ideas?

Community
  • 1
  • 1
Yohan Leafheart
  • 860
  • 1
  • 11
  • 27
  • Autosave doesn't work well with tabbing on dgrid at the moment you might want to try the dev version because some patches to fix some of these problem have recently been merged. https://github.com/SitePen/dgrid/pull/632. If that doesn't work, I'll share what I've come up with. – Richard Ayotte Oct 22 '13 at 15:56
  • K, should be able to try that tomorrow. I will post what happened. – Yohan Leafheart Oct 22 '13 at 20:34
  • No, not working yet. Here is what happens. It randomly does not triggers the select on the next editor of the list. It starts editing the next cell but there is no cell selected, so I can't tab from there. – Yohan Leafheart Oct 25 '13 at 21:52

1 Answers1

0

This fix works on dgrid 0.3.11.

Add to your dgrid's postCreate.

postCreate: function() {
    var that = this;
    this.inherited(arguments);

    this.on('dgrid-datachange', function(evt) {
        that._selectedCell = that.cell(evt);
    });

    aspect.after(this, 'save', function(dfd) {
        dfd.then(function() {
            var nextCell = that.right(that.cell(that._selectedCell.row.id, that._selectedCell.column.id));
            that.edit(nextCell);
            // Bonus Fix. Workaround dgrid bug that blocks field text to be selected on focus.
            nextCell.element.widget && nextCell.element.widget.textbox && nextCell.element.widget.textbox.select();
        });
    });
}
Richard Ayotte
  • 5,021
  • 1
  • 36
  • 34