SitePen / dgrid

A lightweight, mobile-ready, data-driven, modular grid widget designed for use with dstore
http://dgrid.io/
Other
628 stars 295 forks source link

Keyboard focus restoration fails in edge case #1266

Closed kfranqueiro closed 8 years ago

kfranqueiro commented 8 years ago

Ran into this in an app I have been working on... originally suspected a far less obscure/rare edge case than this ends up being.

Steps:

  1. Remove an item from a grid's store while the grid is not focused
  2. Immediately (on the same turn) call grid.focus()
  3. The content node ends up being focused instead of a neighboring row

This happens because _restoreFocus gets fooled - since the grid wasn't focused when _removedFocus was populated, its active flag is false, but then when focus gets called, _focusedNode is null because _restoreFocus only gets called on next turn for the removal case (in order to allow re-insertion of the same item to take precedence). Since active is false, _restoreFocus doesn't properly reset active focus.

This might be resolvable as simply as flipping the active flag if focus gets called while _removedFocus is set.

Repro:

<div id="grid"></div>
<button type="button" id="remove">Remove</button>
require([
    'dojo/_base/declare',
    'dgrid/OnDemandGrid',
    'dgrid/Keyboard',
    'dgrid/Selection',
    'dgrid/test/data/createSyncStore'
], function (
    declare,
    OnDemandGrid,
    Keyboard,
    Selection,
    createSyncStore
) {
    var data = [];
    for (var i = 1; i <= 10; i++) {
        data.push({ id: i });
    }
    var store = createSyncStore({ data: data });
    var grid = new (declare([ OnDemandGrid, Keyboard, Selection ]))({
        collection: store,
        columns: { id: 'ID' },
        selectionType: 'single'
    }, 'grid');

    document.getElementById('remove').onclick = function () {
        var selected = Object.keys(grid.selection)[0];
        if (selected) {
            store.removeSync(grid.row(selected).id);
            grid.focus();
        }
    };
});