Sometimes small changes make all the difference. In this post I’ll introduce several new properties, events and methods of our Data Grid and Tree List widgets, which were implemented to support a Focused Row, a Focused Column, and related keyboard navigation functionality. These changes enable many important new features for your applications, improving its usability and making it more accessible.
The new functionality described in this post applies to all platforms supported by DevExtreme, including Angular, Vue, React, jQuery and ASP.NET MVC and ASP.NET Core.
Focused Row
Before v18.2, the Data Grid and Tree List widgets did not support the idea of focusing a row independently of the row selection feature. We had many requests about scenarios where end users would be able to focus a row and move that focus using keyboard or mouse. Workarounds were available, but they were not optimal and took additional time to implement.
Now you can activate row focusing by setting the focusedRowEnabled property. By default, the end user can use the mouse to focus a row, but they can also navigate up and down in the Data Grid or Tree List using the cursor up
and down
keys.
You can focus a row from code by setting the properties focusedRowIndex or focusedRowKey, or by calling the method navigateToRow. If you use paging or one of the advanced scrolling modes where the grid shows a subset of available rows, the required data is loaded automatically to focus the row.
Note that the focusedRowIndex
is local to the visible page when paging.enabled
is true
. In other modes, including Virtual and Infinite scrolling modes, focusedRowIndex
is global.
Focused Column
When focusedRowEnabled
is set to true
, column focusing can be enabled by setting focusedColumnIndex to a value >= 0
. Its default value is -1
, which means that column focusing is switched off. The end user can use the cursor keys left
and right
to change column focus when this mode is active, or focus a cell by selecting it with the mouse.
Enhanced Keyboard Navigation
As I described, the new focusing features come with keyboard support sufficient for many use cases. However, we also introduced four new events that enable you to react to focus changes and modify the behavior. In addition, you can use the method isRowFocused(key) to find out whether a row with a specific key is already focused.
For row focus, the events are onFocusedRowChanging and onFocusedRowChanged, for cell focus there are onFocusedCellChanging and onFocusedCellChanged. As usual, the xxxChanging
events are fired during the process, before the actual change occurs, while xxxChanged
indicates that the change is complete. All events receive numerous parameters that your code can use to analyze what happened, and the xxxChanging
events have a cancel
property which you can set to prevent the focus change. To visually highlight the focused cell, you need to set e.isHighlighted
to true
.
Demos
You can find a demo of an advanced row focusing implementation by following this link. Be sure to check out the code! You can see how the events onFocusedRowChanging
and onFocusedRowChanged
are handled. The first event implements automatic page changes when the user navigates to the top or the bottom of a page. The second event is used to extract details from the focused row after a change and display them separately.
A demo for column focusing is available in this CodePen. The onFocusedCellChanging
event is implemented here to wrap column focus from one row to the next or previous, when you use the keyboard to navigate past the left and right edges. The isHighlighted
property is used to make the focused cell visible.
Further Plans
We maintain a planning document on GitHub that describes the features we now implemented, but some additional features also included in that document are not done yet. In a nutshell, we plan to extend keyboard navigation to visual elements of the widgets (such as headers, filtering controls, etc), and to enable cell navigation between rows for an Excel-like editing experience.
Please feel free to let us know your thoughts! You can leave comments on the GitHub page, or of course using the comment box below. Do you like the new features? Are they relevant to your use cases? Are we missing anything important?