3
votes

In Electron, is there a way to enable/disable specific MenuItem in context menu, depending on the element that the user has right-clicked? Also I need information about which exact element was clicked and pass that info to context menu function.

For example, let's say I have this html in my renderer process:

<p id="p1">First paragraph</p>
<p id="p2">Second paragraph</p>
<p id="p3">Third paragraph</p>

And my context menu for that window looks like this:

var menu = new Menu();
menu.append(new MenuItem({label: "This menu item is always shown",}));
menu.append(new MenuItem({  // shown only when clicked on p1 or p3
  label: "This menu is not always shown",
  click: function(id){
    // I want variable id to be an id of paragraph that I have clicked on
  }
}));

So when I right click on first or third paragraph, a context menu with 2 items should pop up. But when I right click on second paragraph, a context menu with 1 item should pop up. Also, I want to pass the paragraph id as a parameter to a context menu function, so that I can know from there which paragraph I have clicked on.

1

1 Answers

4
votes

I would dynamically (re)create the context menu in a contextmenu event handler:

In your main process:

Do not turn on nodeIntegration if you load remote content!

const { app, BrowserWindow } = require('electron');

function createWindow () {
  let win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    }
  });

  win.loadFile('index.html');
}

app.whenReady().then(createWindow);

In your renderer process:

Note how I "remotely" load the Menu & MenuItem modules

<html>
  <head>
    <script>
      const { remote } = require('electron');
      const { Menu, MenuItem } = remote;

      window.addEventListener('contextmenu', (e) => {
        e.preventDefault();
        const menu = new Menu();
        menu.append(new MenuItem(new MenuItem({label: "This menu item is always shown"})));
        if (e.target.id === "p1" || e.target.id === "p3") {
          menu.append(new MenuItem({
            label: "This menu is not always shown",
            click: function(){
              alert(`you clicked on ${e.target.id}`);
            }
          }));
        }
        menu.popup({ window: remote.getCurrentWindow() })
      }, false)
    </script>
  </head>
  <body>
    <p id="p1">First paragraph</p>
    <p id="p2">Second paragraph</p>
    <p id="p3">Third paragraph</p>
  </body>
</html>  

enter image description here