onAppMenuItemClick
Category: Events
Namespace: web.events.onAppMenuItemClick
Description
Fires when the user clicks any item in the native application menu bar created via web.appMenu.createMenu. The callback receives the integer id of the clicked menu item.
Critical: This handler must be set in the Builder's "BEFORE DOM Exists JS" slot (the
JavaScript/ NavigationStarting field), NOT inside the HTML page's<script>tag. The Delphi bridge callback wiring happens during NavigationStarting — setting the handler in page JS silently fails.
Syntax
web.events.onAppMenuItemClick = async function(menuId) {
// menuId is the integer id assigned in web.appMenu.createMenu()
};
Parameters
The callback receives one argument:
- menuId
number— The integeridof the menu item that was clicked, matching theidused when building the menu structure
Returns
Nothing. This is an event handler assignment, not a function call.
Examples
Basic usage
// Goes in Builder's "BEFORE DOM Exists JS" slot
web.events.onAppMenuItemClick = function(menuId) {
console.log('Menu item clicked:', menuId);
};
Full menu setup with handler
// Goes in Builder's "BEFORE DOM Exists JS" slot
web.events.onAppMenuItemClick = async function(menuId) {
switch (menuId) {
case 1: // File > New
newDocument();
break;
case 2: // File > Open
const file = await web.dialogs.openFile();
if (file) openDocument(file);
break;
case 3: // File > Save
await saveDocument();
break;
case 9: // File > Exit
await web.app.close();
break;
case 10: // Help > About
await web.app.showAbout();
break;
}
};
if (!window.menuCreated) {
window.menuCreated = true;
web.appMenu.createMenu({
items: JSON.stringify([
{
id: 100, caption: 'File',
items: [
{ id: 1, caption: 'New' },
{ id: 2, caption: 'Open...' },
{ id: 3, caption: 'Save' },
{ separator: true },
{ id: 9, caption: 'Exit' }
]
},
{
id: 200, caption: 'Help',
items: [
{ id: 10, caption: 'About' }
]
}
])
});
}
Enable/disable items based on state
// Goes in Builder's "BEFORE DOM Exists JS" slot
web.events.onAppMenuItemClick = async function(menuId) {
if (menuId === 2) { // Save
await saveCurrentFile();
} else if (menuId === 3) { // Close
currentFile = null;
// Disable save after close
await web.appMenu.updateMenu({
items: JSON.stringify([{ id: 2, enabled: false }])
});
}
};
Placement Rule
| Where | Works? |
|---|---|
| Builder "BEFORE DOM Exists JS" slot | ✅ Yes — correct |
Inside HTML <script> tag |
❌ No — silently fails |
Inside DOMContentLoaded listener |
❌ No — silently fails |
Always register onAppMenuItemClick before calling createMenu, and both must be in the NavigationStarting JS slot.
Use Cases
- Handle File > New, Open, Save, Exit actions
- Toggle fullscreen, zoom, or other view settings
- Open Help/About dialogs
- Enable or disable menu items in response to app state changes
Notes
- Menu item
idvalues must be integers — string IDs throw"'x' is not a valid integer value" - Register the handler before calling
web.appMenu.createMenu()— not after - Use
window.menuCreatedguard to prevent double-creation on page reloads - Only one handler can be assigned at a time — reassigning replaces the previous handler
- Top-level parent items (e.g. "File", "Help") do not fire the callback when clicked — only leaf items do
- See
web.appMenu.createMenufor building the menu structure - See
web.appMenu.updateMenufor changing item state (enabled/visible/caption) after creation