Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DataGrid: add Custom keyboard navigation topic #5573

Merged
merged 8 commits into from
Sep 18, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,4 @@ A user can use the following keys to interact with the DataGrid component:
</ol>
</div>

You can override these shortcuts or create your own shortcuts using the [onKeyDown](/api-reference/10%20UI%20Components/dxDataGrid/1%20Configuration/onKeyDown.md '/Documentation/ApiReference/UI_Components/dxDataGrid/Configuration/#onKeyDown') event handler.
You can override these shortcuts or create your own. Refer to the following help topic for more information: [Custom Keyboard Navigation](/Documentation/Guide/UI_Components/DataGrid/Custom_Keyboard_Navigation/).
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
You can use the [keyboardNavigation](/Documentation/ApiReference/UI_Components/dxDataGrid/Configuration/keyboardNavigation/) property to configure DataGrid [keyboard navigation](/Documentation/Guide/UI_Components/DataGrid/Accessibility/#Keyboard_Navigation). If the default behavior does not meet your requirements, implement a custom one.
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
To specify which cell should be focused next when a user navigates through DataGrid, use the [onFocusedCellChanging](https://js.devexpress.com/Documentation/ApiReference/UI_Components/dxDataGrid/Configuration/#onFocusedCellChanging) function. The code below uses `newColumnIndex` to set the column index of the next focused cell.
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved

---
##### jQuery

<!-- tab: index.js -->
$("#dataGridContainer").dxDataGrid({
// ...
onFocusedCellChanging: function (e) {
if (e.columns[e.newColumnIndex].dataField === "myField") { // Checks if the next focused cell will be in the 'myField' column
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
e.newColumnIndex++; // If so, proceed to the next column
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
}
}
});

##### Angular

<!-- tab: app.component.html -->
<dx-data-grid ...
(onFocusedCellChanging)="onFocusedCellChanging($event)">
</dx-data-grid>

<!-- tab: app.component.ts -->
import { Component } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})

export class AppComponent {
onFocusedCellChanging(e) {
if (e.columns[e.newColumnIndex].dataField === "myField") { // Checks if the next focused cell will be in the 'myField' column
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
e.newColumnIndex++; // If so, proceed to the next column
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

##### Vue

<!-- tab: App.vue -->
<template>
<DxDataGrid ...
@focused-cell-changing="onFocusedCellChanging">
</DxDataGrid>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';
import DxDataGrid from 'devextreme-vue/data-grid';

export default {
components: {
DxDataGrid
},
// ...
methods: {
onFocusedCellChanging(e) {
if (e.columns[e.newColumnIndex].dataField === "myField") { // Checks if the next focused cell will be in the 'myField' column
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
e.newColumnIndex++; // If so, proceed to the next column
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}
</script>

##### React

<!-- tab: App.js -->
import React from 'react';
import 'devextreme/dist/css/dx.light.css';
import DataGrid from 'devextreme-react/data-grid';

const onFocusedCellChanging = (e) => {
if (e.columns[e.newColumnIndex].dataField === "myField") { // Checks if the next focused cell will be in the 'myField' column
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
e.newColumnIndex++; // If so, proceed to the next column
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
}
}

function App() {
return (
<DataGrid ...
onFocusedCellChanging={onFocusedCellChanging}>
</DataGrid>
);
}
export default App;

---
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
You can use the following methods to focus a specific cell:
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved

- [focus](/Documentation/ApiReference/UI_Components/dxDataGrid/Methods/#focuselement)
Allows you to set focus on a cell. You can use the [getCellElement](/Documentation/ApiReference/UI_Components/dxDataGrid/Methods/#getCellElementrowIndex_dataField) method to get elements of required cells.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Allows you to set focus on a cell. You can use the [getCellElement](/Documentation/ApiReference/UI_Components/dxDataGrid/Methods/#getCellElementrowIndex_dataField) method to get elements of required cells.
Allows you to move focus to a cell. You can call the [getCellElement](/Documentation/ApiReference/UI_Components/dxDataGrid/Methods/#getCellElementrowIndex_dataField) method to get elements of required cells.

P.S. What connection the mentioned getCellElement method has with the focus movement scenario we describe?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You call getCellElement to get a cell container so you can then call focus.
Like
const cell = e.getCellElement(); focus(cell);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it a mandatory or optional step? If it's optional, then this wording is probably fine as it is. Otherwise, we should state that one should call the mentioned methods in conjunction in order to achieve the desired result.

From what I gather, judging from your example, this is a mandatory step. Therefore, you first obtain this object/entity named "cell" whatever it is -- and then you pass it to the focus method as a parameter. Shouldn't we explain things here exactly as they are?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated this part


- [editCell](/Documentation/ApiReference/UI_Components/dxDataGrid/Methods/#editCellrowIndex_dataField)
Switches a cell to the editing state and moves the focus to this cell.
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
The [onKeyDown](/Documentation/ApiReference/UI_Components/dxDataGrid/Configuration/#onKeyDown) event handler allows you to track keys used while the UI component is in focus. You can use it to override the default keyboard support shortcuts, implement your own shortcuts, or extend existing ones.
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved

The following example shows how to override the **Space** key to switch a cell in cell/batch mode to the editing state instead of the current row being selected:
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved

---
##### jQuery

<!-- tab: index.js -->
$("#dataGridContainer").dxDataGrid({
// ...
onKeyDown: function (e) {
if (e.event.keyCode === 32) { // Space key
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
e.event.preventDefault(); // Prevent the default behavior
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
const focusedRowIndex = e.component.option("focusedRowIndex");
const focusedColumnIndex = e.component.option("focusedColumnIndex");
e.component.editCell(focusedRowIndex, focusedColumnIndex);
}
}
})

##### Angular

<!-- tab: app.component.html -->
<dx-data-grid ...
(onKeyDown)="onKeyDown($event)">
</dx-data-grid>

<!-- tab: app.component.ts -->
import { Component } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})

export class AppComponent {
onKeyDown(e) {
if (e.event.keyCode === 32) { // Space key
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
e.event.preventDefault(); // Prevent the default behavior
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
const focusedRowIndex = e.component.option("focusedRowIndex");
const focusedColumnIndex = e.component.option("focusedColumnIndex");
e.component.editCell(focusedRowIndex, focusedColumnIndex);
}
}
}

##### Vue

<!-- tab: App.vue -->
<template>
<DxDataGrid ...
@key-down="onKeyDown">
</DxDataGrid>
</template>

<script>
import 'devextreme/dist/css/dx.light.css';
import DxDataGrid from 'devextreme-vue/data-grid';

export default {
components: {
DxDataGrid
},
// ...
methods: {
onKeyDown(e) {
if (e.event.keyCode === 32) { // Space key
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
e.event.preventDefault(); // Prevent the default behavior
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
const focusedRowIndex = e.component.option("focusedRowIndex");
const focusedColumnIndex = e.component.option("focusedColumnIndex");
e.component.editCell(focusedRowIndex, focusedColumnIndex);
}
}
}
}
</script>

##### React

<!-- tab: App.js -->
import React from 'react';
import 'devextreme/dist/css/dx.light.css';
import DataGrid from 'devextreme-react/data-grid';

const onKeyDown = (e) => {
if (e.event.keyCode === 32) { // Space key
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
e.event.preventDefault(); // Prevent the default behavior
vladaskorohodova marked this conversation as resolved.
Show resolved Hide resolved
const focusedRowIndex = e.component.option("focusedRowIndex");
const focusedColumnIndex = e.component.option("focusedColumnIndex");
e.component.editCell(focusedRowIndex, focusedColumnIndex);
}
}

function App() {
return (
<DataGrid ...
onKeyDown={onKeyDown}>
</DataGrid>
);
}

export default App;

---
Loading