Keyboard shortcuts to jump to sections of the View?

Our views normally inherit from VerticalLayout and contain something like this:

  • navigator (FlexLayout)
  • result list (Grid)
  • tabs (Tabsheet)
    • detail (Normally a form of some kind, but can also be another Grid, or anything really)

I thought it would be nice to allow our users to jump between these sections.
So, ctrl-1 jumps to the navigator, ctrl-2 jumps to the result list, ctrl-3 jumps to the tabs themselves and ctrl-4 jumps to the content of the current tab.

Tried with a quick proof-of-concept and ran into an issue with Grid;
Grid implements Focusable, but nothing seem to happen when I call it.
The field that has focus doesn’t lose it and the Grid doesn’t gain it.

There is also the question of what “set focus on grid” should do; Is it the outer grid, the row or the cell that should get focus (or the grid editor, if it has any)
I’m actually not sure what would make most sense.
The use-case would be to change row or to open context menu on the current selection.

Anyone done something like this?

I remember saving component references to some weak hashmap (from grid columns) and focusing them.

I made a quick test with “dummy Grid” and I think you found a bug with Grid not even gaining focus. By setting tabIndex = -1 seems to make it “work”, existing focus is moved to Grid and it gains a “focus ring”.

    public static class FocusGrid extends VGrid<String> {
        public FocusGrid() {
            super();
            setItems("One", "Two", "Three");
            addColumn(s -> s).setHeader("Name");
            addFocusListener(e -> {
                System.out.println("Focus");
            });
            setTabIndex(-1);
        }
    }

Testing bit more: it doesn’t actually get the focus ring until on presses some other key (tried arrow down to see if a row would be focus or contents scrolled, but nothing happened).

And now found out that once there is the focus (without the focus ring) one can click tab → it gets into the table (header frist), then to row and then you can scroll/select etc :muscle: But the initial focus should be fixed somehow…

A workaround :


    public static class FocusGrid extends VGrid<String> {
        public FocusGrid() {
            super();
            setItems("One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen");
            addColumn(s -> s).setHeader("Name");
            addColumn(s -> s).setHeader("Name2");
            addFocusListener(e -> {
                System.out.println("Focus");
            });
        }

        @Override
        public void focus() {
            getElement().executeJs("""
                $0.shadowRoot.querySelector("tr").focus();
            """);
        }
    }

Just remembered that I’ve encountered this before…

I wanted to have filter-field + a grid below it, and when user pressed arrow-down in filter I wanted to move into grid, so I tried grid.focus(), which didn’t work then either.

That lead me to this: Grid#focus() seems to be broken · Issue #2180 · vaadin/flow-components · GitHub
@Tatu2 suggested a workaround which solved my immediate concern then (Though timeout==0 didn’t work, but 100 did)

The issue is still open

I think for me this would be just “nice to have”, so I’ll leave it there for now

Yeah, found that ancient issue as well when I was about to add a new one…

Timeout probably needed if the method is called in constructor/init as Grid is doing something lazily…