Fix click propagation for non-editable cells with editors#4891
Conversation
#4421) Add a failing unit test demonstrating that when a column defines an editor but the cell is not editable, the edit click handler calls e.stopPropagation() before checking editability. This swallows the click so it never reaches the table-level listener that powers the cellClick callback.
The edit click handler called e.stopPropagation() unconditionally whenever a column had an editor defined, before checking whether the cell was actually editable. When the cell was not editable the click was swallowed and never reached the table-level listener that powers the cellClick callback, so it never fired (regression since 5.6). Move the stopPropagation() call inside the editability check so it only runs when the cell will actually be edited, allowing clicks on non-editable cells to propagate normally.
5bfae87 to
8f21a88
Compare
Root cause of #4421 and why this behavior change is correctWhere the bug came fromThis is an accidental regression introduced by the In 5.5.4 (working), element.addEventListener("click", function(e){
if(!element.classList.contains("tabulator-editing")){
element.focus({preventScroll: true}); // click ONLY focuses
}
});
element.addEventListener("focus", function(e){
if(!self.recursionBlock){
self.edit(cell, e, false); // edit() gets the FOCUS event
}
});So In 5.6.0, the if(this.options("editTriggerEvent") === "focus" || this.options("editTriggerEvent") === "click"){
element.addEventListener("click", function(e){
if(!element.classList.contains("tabulator-editing")){
element.focus({preventScroll: true});
self.edit(cell, e, false); // edit() now gets the CLICK event
}
});
}Now the same old if(!cell.column.modules.edit.blocked){
if(e){ e.stopPropagation(); } // swallows the click...
allowEdit = this.allowEdit(cell); // ...even when this is false
...
}For a cell that has an editor defined but is not editable, the click is swallowed before it can reach the table-level listener, so Why changing the behavior is correct
One thing worth flaggingRestoring propagation means it isn't only Covered by a regression test in Generated by Claude Code |
| const ancestorClickHandler = jest.fn(); | ||
| const ancestor = document.createElement("div"); | ||
| document.body.appendChild(ancestor); | ||
| ancestor.appendChild(cellElement); |
There was a problem hiding this comment.
I don't think this is correct. We should just listen to the cell click event from the table instance.
…4421) Per review feedback, test the actual cellClick event from the table instance instead of a stand-in ancestor listener. Using a fixed height with basic vertical rendering forces rows to lay out in the DOM under jsdom, so a real click bubbles to the table-level listener and both the column cellClick callback and the external cellClick event are observed.
Summary
Fixed an issue where click events on non-editable cells were being stopped from propagating, preventing the
cellClickcallback from firing when a column had an editor defined but the cell itself was not editable.Changes
e.stopPropagation()call to only execute after confirming the cell is actually editable. Previously, the propagation was stopped before checking editability, which swallowed clicks on non-editable cells and prevented them from reaching parent listeners.Implementation Details
The fix ensures that:
cellClickcallback to firestopPropagation()is called relative to theallowEdit()checkThis resolves issue #4421 where the
cellClickevent was not firing for cells in columns with editors defined but marked as non-editable.https://claude.ai/code/session_01Nt4ggeWkoLbhrLcYwciwts