Overview
A common request in Mendix development is to automatically select the first row in a DataGrid2 after data changes. While the predecessor of DataGrid2 had this functionality built-in, it's notably absent in the current version.This guide provides a JavaScript-based solution to automatically select a row in DataGrid2.
The Challenge
The main technical challenge is that the clickable class on DataGrid2 rows is not immediately available when the page loads. The class is added asynchronously after the mx.addOnLoad function executes, requiring a delayed execution approach.
Solution Architecture
The solution consists of four components:
JavaScript Implementation
Note: DataGrid2: Auto-Select First Row is now available as part of Convent Commons in the
Marketplace. See Convent Commons.
Code Structure below doesn't work with DataWidget version 3.8.0.
Convent Commons version 1.3.2 has an updated version compatibel with DataWidget
up to version 3.8.0.
Recently an identical solution for Gallery has been added to Convent Commons.
Code Structure
// This file was generated by Mendix Studio Pro.
//
// WARNING: Only the following code will be retained when actions are regenerated:
// - the import list
// - the code between BEGIN USER CODE and END USER CODE
// - the code between BEGIN EXTRA CODE and END EXTRA CODE
// Other code you write will be lost the next time you deploy the project.
import "mx-global";
import { Big } from "big.js";
// BEGIN EXTRA CODE
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// END EXTRA CODE
/**
* DataGrid 2 doesn't have a function to select the first row.
* This JavaScript action allows you to select a row in a DataGrid 2 when opening a page, and/or when a selection is changed.
*
* Parameters:
* - Datagrid2Name: Mendix name of the DataGrid 2 (without the class prefix "mx-name-").
* - Datagrid2Row: Number of the row to be selected. (1 for the first row.)
*
* Note: To my surprise, the "clickable" class names aren't yet present when mx.addOnLoad is executed.
* Therefore, a small delay of 100 milliseconds has been added and the test if "clickable" is present is repeadedly tested. When present, the clickElement function is invoked.
* @param {string} datagrid2Name - Name of the Datagrid2.
(The part "mx-name-"is added in the coding.)
* @param {string} datagrid2Row - Rownumber to select.
* @returns {Promise.<void>}
*/
export async function JS_DG2_SelectRow(datagrid2Name, datagrid2Row) {
// BEGIN USER CODE
mx.addOnLoad(function () {
const gridname = ".mx-name-" + datagrid2Name;
var tries = 0;
var content = null;
var clickelement = null;
// Wait until the gridtable is available
async function waitForContent() {
tries = 0;
do {
tries += 1;
if (tries > 50) {
console.log("JS_DG2_SelectRow: Giving up after 5 seconds waiting for datagrid content.");
return;
} // endif
await sleep(100);
const gridtable = document.querySelector(gridname);
if (gridtable) {
content = gridtable.querySelector(".widget-datagrid-grid-body");
} // endif
} // enddo
while (content == null);
} // end function waitForContent
// Wait until the clickable element is available
async function waitForClickable() {
tries = 0;
do {
tries += 1;
if (tries > 50) {
console.log("JS_DG2_SelectRow: Giving up after 5 seconds waiting for clickable element.");
return;
} // endif
await sleep(100);
const tablerow = content.querySelector(".tr:nth-child(" + datagrid2Row + ")");
if (tablerow) {
clickelement = tablerow.querySelector(".clickable");
} // endif
} // enddo
while (clickelement == null || clickelement == 'undefined');
} // end function waitForClickable
// First wait for content, then for clickable, then click it.
waitForContent().then(() => {
if (content != null) {
waitForClickable().then(() => {
if (clickelement != null) {
clickelement.click();
} // endif
}); // end then
} // endif
}); // end then
}); // end mx.addOnLoad
// END USER CODE
}
How It Works
Configuration in Mendix Studio Pro
JavaScript Action Parameters
Parameter Type Description
datagrid2Name String Name of the DataGrid2 (without "mx-name-" prefix)
datagrid2Row String Row number to select (typically "1" for first row)
Nanoflow Setup
Create a nanoflow named NF_DG2_SelectRow that:
Use Cases
1. Page Load Event
Use a Page Event widget (from Marketplace) to trigger selection when a page opens.
Configuration:
2. Master-Detail Grids
When a DataGrid2 listens to another grid (master-detail pattern).
Configuration:
3. Dropdown/Combobox Filtering
When a DataGrid2 is filtered by a dropdown selection.
Configuration:
Best Practices
Troubleshooting
Issue Cause Solution
Row not selected Grid name incorrect Verify exact DataGrid2 name (case-sensitive)
Wrong row selected Incorrect row parameter Check row number parameter value
No response JavaScript not executing Verify nanoflow is triggered correctly
Dependencies
Conclusion
This solution effectively restores the auto-select functionality missing from DataGrid2. By using a polling mechanism to wait for DOM readiness, it reliably selects rows across different scenarios and timing conditions.
The modular approach with separate JavaScript Action and nanoflow makes it reusable across your application and easy to maintain.