]> git.proxmox.com Git - proxmox-widget-toolkit.git/commitdiff
toolkit: fix #1510: don't scroll back to focus when view refreshes
authorThomas Lamprecht <t.lamprecht@proxmox.com>
Tue, 19 Dec 2017 07:16:13 +0000 (08:16 +0100)
committerDominik Csapak <d.csapak@proxmox.com>
Thu, 11 Jan 2018 13:45:48 +0000 (14:45 +0100)
adds a workaround, so that we restore the scroll position when we
restore the focus. Fixies an annoying issue where, if a user had an
ellemtn selected, scrolled down and then a store refresh re-rendered
the view it was scrolled back to the selected item and the user lost
his scrolling position.

Add also the 'jumpToFocus' flag to allow enabling the old behaviour

commit e6f2a94f4fff3c125e8406a21d8d6159aca1421e from pve-manager

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Toolkit.js

index 166da4d6ffeb88f56b73c175e1bfa2d3a4f97475..9e3735284df8ed090b44bae80536ed9c834645fc 100644 (file)
@@ -213,6 +213,79 @@ Ext.define('Proxmox.form.ComboBox', {
     }
 });
 
+// when refreshing a grid/tree view, restoring the focus moves the view back to
+// the previously focused item. Save scroll position before refocusing.
+Ext.define(null, {
+    override: 'Ext.view.Table',
+
+    jumpToFocus: false,
+
+    saveFocusState: function() {
+        var me = this,
+            store = me.dataSource,
+            actionableMode = me.actionableMode,
+            navModel = me.getNavigationModel(),
+            focusPosition = actionableMode ? me.actionPosition : navModel.getPosition(true),
+            refocusRow, refocusCol;
+
+        if (focusPosition) {
+            // Separate this from the instance that the nav model is using.
+            focusPosition = focusPosition.clone();
+
+            // Exit actionable mode.
+            // We must inform any Actionables that they must relinquish control.
+            // Tabbability must be reset.
+            if (actionableMode) {
+                me.ownerGrid.setActionableMode(false);
+            }
+
+            // Blur the focused descendant, but do not trigger focusLeave.
+            me.el.dom.focus();
+
+            // Exiting actionable mode navigates to the owning cell, so in either focus mode we must
+            // clear the navigation position
+            navModel.setPosition();
+
+            // The following function will attempt to refocus back in the same mode to the same cell
+            // as it was at before based upon the previous record (if it's still inthe store), or the row index.
+            return function() {
+                // If we still have data, attempt to refocus in the same mode.
+                if (store.getCount()) {
+
+                    // Adjust expectations of where we are able to refocus according to what kind of destruction
+                    // might have been wrought on this view's DOM during focus save.
+                    refocusRow = Math.min(focusPosition.rowIdx, me.all.getCount() - 1);
+                    refocusCol = Math.min(focusPosition.colIdx, me.getVisibleColumnManager().getColumns().length - 1);
+                    focusPosition = new Ext.grid.CellContext(me).setPosition(
+                            store.contains(focusPosition.record) ? focusPosition.record : refocusRow, refocusCol);
+
+                    if (actionableMode) {
+                        me.ownerGrid.setActionableMode(true, focusPosition);
+                    } else {
+                        me.cellFocused = true;
+
+                       // we sometimes want to scroll back to where we were
+                       var x = me.getScrollX();
+                       var y = me.getScrollY();
+
+                        // Pass "preventNavigation" as true so that that does not cause selection.
+                        navModel.setPosition(focusPosition, null, null, null, true);
+
+                       if (!me.jumpToFocus) {
+                           me.scrollTo(x,y);
+                       }
+                    }
+                }
+                // No rows - focus associated column header
+                else {
+                    focusPosition.column.focus();
+                }
+            };
+        }
+        return Ext.emptyFn;
+    }
+});
+
 // should be fixed with ExtJS 6.0.2, see:
 // https://www.sencha.com/forum/showthread.php?307244-Bug-with-datefield-in-window-with-scroll
 Ext.define('Proxmox.Datepicker', {