Posted 20 January 2026, 9:28 am EST
Hi,
Thank you for reaching out! I understand you’re experiencing an issue where the context menu persists when right-clicking locked cells after initially right-clicking an unlocked cell.
The solution you need is to intercept the context menu event at the host element level and check if the clicked cell is locked. Here’s the recommended approach:
import * as GC from "@mescius/spread-sheets";
const spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
// Add context menu event listener to the spread host
spread.getHost().addEventListener("contextmenu", (e) => {
// Get the click coordinates relative to the spread container
const offsetEle = spread.getHost();
const x = e.pageX - offsetEle.offsetLeft;
const y = e.pageY - offsetEle.offsetTop;
// Perform hit test to identify the clicked element
const target = spread.hitTest(x, y);
const sheet = spread.getActiveSheet();
const rowIndex = target.worksheetHitInfo.row;
const colIndex = target.worksheetHitInfo.col;
// Check if click is in viewport area and cell is locked
if (target.worksheetHitInfo.hitTestType === GC.Spread.Sheets.SheetArea.viewport
&& sheet.getCell(rowIndex, colIndex).locked()) {
e.stopPropagation();
e.preventDefault();
}
}, true); // Important: use capture phase
const sheet = spread.getActiveSheet();
// Example: Set up locked and unlocked cells
sheet.getCell(1, 1).locked(false);
sheet.getCell(1, 1).backColor("green");
sheet.getCell(2, 2).locked(true);
sheet.getCell(2, 2).backColor("red");
Key Points:
-
Event Listener on Host Element: The
contextmenu
event is attached directly to the spread host element, ensuring it captures all right-click events before SpreadJS processes them.
-
Hit Test: Using
spread.hitTest()
with the click coordinates allows you to accurately determine which cell was clicked, regardless of the selection state.
-
Capture Phase: The third parameter
true
in addEventListener
ensures the event is captured in the capture phase, giving your handler priority over SpreadJS’s internal handlers.
-
Conditional Prevention: The context menu is only prevented when:
- The click is in the viewport area (not headers or other areas)
- The target cell’s
locked()
property returns true
Why This Works:
Unlike the
SelectionChanging
event approach, this method doesn’t rely on cell selection state. It directly intercepts the context menu event and checks the locked state of the specific cell that was right-clicked, preventing the issue you experienced where the context menu would persist after clicking from an unlocked to a locked cell.
This solution works consistently regardless of selection order or state changes.
Sample: https://jscodemine.mescius.io/share/5PTBROmkXUCv9hMH-UxVWA/?defaultOpen={"OpenedFileName"%3A["%2Findex.html"%2C"%2Fpackage.json"%2C"%2Fsystemjs.config.js"%2C"%2Fsrc%2Fdata.js"%2C"%2Fsrc%2Fapp.js"]%2C"ActiveFile"%3A"%2Fsrc%2Fapp.js"}
Regards,
Priyam