How to enable DHTMLX grid edit in single cell click

We are using DHTMLX v8 Grid and I need the grid to be editable. I have several editable columns, but currently a cell becomes editable only on double-click. I want to make it editable on single click instead.

I tried using this:

gridObj.events.on(“cellClick”, (row, column, event) => {
if (column.editable === true) {
cellClicked = true;
gridObj.editCell(row.id, column.id);
}
});

However, triggering editCell() inside cellClick also fires the afterEditEnd event immediately — and I don’t want that, because I have an AJAX save call in that listener.

Has anyone handled single-click editing in DHTMLX v8 without triggering afterEditEnd unintentionally? Any suggestions would be appreciated.

Hello Siva,

If your main goal is to avoid triggering an AJAX request when the value hasn’t actually changed, you can add a simple value-comparison check:

let previousValue = null;

grid.events.on("cellClick", (row, column) => {
	if (column.id !== "paid") {
		grid.editCell(row.id, column.id);
	}
});

grid.events.on("beforeEditStart", (row, column) => {
	previousValue = row[column.id];
});

grid.events.on("afterEditEnd", (value, row, column) => {
	if (value === previousValue) {
		return;
	}

	alert("afterEditEnd fired with real change");
	// here you can do your AJAX save instead of alert(...)
});

Example: DHTMLX Snippet Tool

If this still doesn’t match what you need, could you describe the exact scenario where the AJAX call should be skipped?

Hi Maksim_Lakatkou,

Thanks for your response. I’m actually using a similar value-comparison approach already, but I’m facing a different issue.

Here’s my setup:

  • The grid is editable on single click
  • I capture the old value in beforeEditStart
  • I compare old vs new value in afterEditEnd
let oldValueCache = null;

myGridObj.events.on("beforeEditStart", function(row, col) {
    oldValueCache = row[col.id] === null || row[col.id] === undefined ? "" : row[col.id];
});

myGridObj.events.on("cellClick", (row, column) => {
    if (column.editable === true) {
        myGridObj.editCell(row.id, column.id);
    }
});

myGridObj.events.on("afterEditEnd", function(value, row, col) {
    const original = oldValueCache;
    const updated = value ? value.trim() : "";

    // Do nothing if there is no real change
    if (updated === (original + "").trim() || (original === null && updated === "")) {
        return;
    }

    // AJAX save logic…
});

The issue is:
When the return statement inside afterEditEnd runs, the cursor disappears and editing stops.
Unlike beforeEditStart, the afterEditEnd event cannot prevent editing from ending — it always closes the editor first.

So the comparison works, but it doesn’t keep the cell in edit mode.

Just wanted to clarify this difference in behavior.

1 Like

Hello Siva,

Sorry for the late reply.

afterEditEnd fires after the user finishes editing the cell.
This happens when the user presses Enter or clicks another cell.

Could you describe in more detail what should happen when the user tries to leave the cell without changing the value?