WebDirect contextual menus disabled

FMS 22 (2025) now supports contextual menus:

Right-click contextual menus are supported, allowing users to access common operations like copy and paste directly from the context menu. Right-click contextual menus are also supported for additional field types including drop-down lists, pop-up menus, drop-down calendars, and concealed edit boxes, with various UI and state management improvements.

However in my WebDirect solution, they are always disabled:

I would like to enable these, but I do not want the menu bar to be enabled otherwise.

I haven't played with these new options yet. What's the purpose of allowing copy/paste in a context menu but not allowing it through the main menus?

1 Like

I don't really understand what Claris was thinking.

I tried a simple test database with one layout and a couple of fields in WebDirect, and on that test database the contextual menus are not disabled, even with running:

Show/Hide Menubar  [Lock:On ; Hide]
Show/Hide Toolbars [Lock; Hide]

So there must be some other setting(s) in my real database which is causing the contextual menus to be disabled.

I think I figured it out, it seems to be a bug with calculated record Edit privileges.

In this example, the WebDirect [Guest] account has a privilege set where the Record edit permission is set to a calculation (in this case, a simple 0 or 1 based on a Field with Global storage).

In WebDirect...

When edit permission is not allowed, and you try to edit text in a field, you get the error as expected:

And you can Copy, but not Paste from the popup menu, as expected.

And when Record editing is allowed, you can edit the record, as expected:

However, even when record editing is allowed, the Paste item is improperly disabled:

So, it seems to be a permissions bug in WebDirect.

Reported to Claris here: Claris Community (English)

1 Like

I’ve never understood why copy/paste was such a big deal in Webdirect for Claris, or why they even had to build their own menu.

"data:text/html,<html><head><script>function activateContext(){if (top.window.contextMenuOverride) return; top.document.addEventListener('DOMNodeInserted', (e) => {e.relatedNode.oncontextmenu = null;}); [...top.document.querySelectorAll('*')].forEach((el) => el.oncontextmenu = null); top.window.contextMenuOverride = true;} activateContext();</script></head><body></body></html>"

Chuck the above code into a custom function, and then put that custom function in a web viewer. hang the WV off the right edge of the layout so it’s at least 1 pixel on-screen so it loads.

This code will execute and enable the standard browser context menu in WebDirect, which includes cut/copy/paste etc.

It only needs to be loaded once from memory, so usually throw it on your start/home layout. I’ve never had any issues with the above code.

the CF only needs to run in WebDirect, so you can either hide the WV in other platforms, or put that logic into the CF

Pretty sure this originally came from @jwilling :+1:

3 Likes

Very helpful, thanks!

For those following along, here's how this works:

Background:

  • WebDirect uses HTML, CSS, and JavaScript.
  • in WebDirect, a WebViewer is implemented as an IFrame (basically like a separate child HTML document inside the parent one.) Inside an iFrame, javascript code can use top.window or top.document to refer back to the parent HTML window and document.

Here's the javascript deconstructed and cleaned up a bit for clarity:

function disableFileMakerContextMenus() {

  // if this script has already run before, then bail out
  if (top.window.contextMenuOverride) return; 

  // create a listener function which will be run any time a new node
  // is added to the HTML.
  top.document.addEventListener ('DOMNodeInserted', (e) =>  
     { 
       // e is the event, so we use relatedNote to get the actual node
       // oncontextmenu is the eventHandler for when you right-click
       // setting it back to 'null' clears out the FileMaker function 
       e.relatedNode.oncontextmenu = null;
     }
   ); 

  // the prior code will handle any new nodes
  // but we also need to clear out any pre-existing nodes 
  // so we run the same function as above, but on 
  // every pre-existing node in the document

  // this [...].forEach syntax is a fancy way to say 
  // for every node in the document, do this...

  [...top.document.querySelectorAll('*')].forEach( (el) =>
     // clear the context menu handler
    el.oncontextmenu = null 
    ); 

  // set a property on top.window to remind us we have done the task
  top.window.contextMenuOverride = true;
 } 

 // run the function
 disableFileMakerContextMenus();

2 Likes