Search code examples
office-jsoffice-addinsexcel-addinsribbonxexcel-web-addins

Excel Office.js - Enable/Disable Multiple Context Menu Items on right click


I'm working on a new feature for an existing Excel office add-in. This feature requires a new context menu item and Sub-menu Items under the menu item.

I want to enable/disable the Sub-Menu Item based on the worksheet or a specific cell within a sheet.

Can someone please let me know if there is such a feature available with Excel Office JS?

I am aware that there is such an option for Ribbons inside a Custom Tab but I dont see any documentation for Contextual Menu(Right Click)

    <ExtensionPoint xsi:type="ContextMenu">
                      <OfficeMenu id="ContextMenuCell">
                        <Control xsi:type="Menu" id="Menu">
                                            <Label resid="Dropdown.Label" />
                                            <Supertip>
                                                <Title resid="Dropdown.Label" />
                                                <Description resid="Dropdown.Tooltip" />
                                            </Supertip>
                                            
                                            <Items>
                                                <Item id="Menu.Item1">
                                                    <Label resid="Item1.Label"/>
                                                    <Supertip>
                                                        <Title resid="Item1.Label" />
                                                        <Description resid="Item1.Tooltip" />
                                                    </Supertip>
                                                    
                                                <Action xsi:type="ExecuteFunction">
                                                    <FunctionName>signOff</FunctionName>
                                                </Action>
                                           <Enabled>false</Enabled>
                                                </Item>
                                                <Item id="Menu.Item2">
                                                <Label resid="Item2.Label"/>
                                                <Supertip>
                                                    <Title resid="Item2.Label" />
                                                    <Description resid="Item2.Tooltip" />
                                                </Supertip>
                                                
                                           <Action xsi:type="ExecuteFunction">
                                                <FunctionName>signOff2</FunctionName>
                                            </Action>
                                            </Item>
                            
                                            </Items>
                                        </Control>
                      </OfficeMenu>
                  </ExtensionPoint>

EDIT 1

AS per the suggestion below, I tried using the same code which OfficeJS documentation is suggesting for Enabling/Disabling Ribbon Buttons.

My Code:

async function signOff(args) {
  console.log("SignOff 1 started");
  Office.ribbon.requestUpdate({
    tabs: [
        {
            id: 'ContextMenuCell',
            controls: [
                {
                    id: 'Menu.Item1',
                    enabled: true
                }
            ]
        }
    ]
});
  args.completed();
}
Office.actions.associate("signOff", signOff);

But I get the following error

  Uncaught (in promise) RichApi.Error: ControlIdNotFound
    at new n (excel-win32-16.01.js:25:257638)
    at i.processRequestExecutorResponseMessage (excel-win32-16.01.js:25:321804)
    at excel-win32-16.01.js:25:319867

The requestupdate() method of the OfficeJS, which on the first look makes it pretty clear that this is for Ribbon as it is supposed to be called using Office.ribbon.requestUpdate(input: RibbonUpdaterData)

Just in case my requirement isn't very clear.

I have the below 'Sub-Menu 1' and 'Sub-Menu 2' items in my Contextual Menu. My Contextual Menu(Right-Click)

I want to enable/disable these submenus based on different business requirements i.e. based on worksheet or based on cell or cell range etc.

EDIT 2

Can we at least separate the submenu items like how Excel provides for Paste options? refer the image below

Menu Group Label

Can we add a separator between 2 sub-menu items like how excel provides for menu items? refer image below

Group Separator


Solution

  • It doesn't matter whether you deal with a context menu or custom ribbon tab. You can customize context menus in Office web add-ins:

    <ExtensionPoint xsi:type="ContextMenu">
      <OfficeMenu id="ContextMenuCell">
        <Control xsi:type="Menu" id="ContextMenu2">
                <!-- information about the control -->
        </Control>
        <!-- other controls, as needed -->
      </OfficeMenu>
    

    If you want a custom button or menu item to be disabled when the Office application launches, you specify this in the manifest. Just add an Enabled element (with the value false) immediately below (not inside) the Action element in the declaration of the control.

    If you want to change the state dynamically you need to use the requestUpdate method of the Office.Ribbon interface, see Change the state in response to an event for more information. Read more about supported ribbon extensibility in the Enable and Disable Add-in Commands and Create custom contextual tabs in Office Add-ins articles.

    Note, you can post or vote for an existing feature request on Tech Community where they are considered when the Office dev team goes through the planning process.