Training
Learning path
Use advance techniques in canvas apps to perform custom updates and optimization - Training
Use advance techniques in canvas apps to perform custom updates and optimization
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
When some functionality in your add-in should only be available in certain contexts, you can programmatically configure your custom add-in commands to only be available in these contexts. For example, a function that changes the header of a table should only be available when the cursor is in a table.
Note
You can programmatically change the availability of an add-in command for the following capabilities.
The following table outlines the Office applications that support configuring the availability of add-in commands. It also lists the requirement sets needed to use the API.
Add-in command capability | Requirement set | Supported Office applications |
---|---|---|
Ribbon buttons, menus, and tabs | RibbonApi 1.1 |
|
Context menu items | ContextMenuApi 1.1 |
|
Tip
To learn how to test for platform support with requirement sets, see Office versions and requirement sets.
To change the availability of a ribbon or context menu control or item, the manifest of your add-in must first be configured to use a shared runtime. For guidance on how to set up a shared runtime, see Configure your Office Add-in to use a shared runtime.
Note
Only the controls on the ribbon can be deactivated when the Office application starts. You can't deactivate custom controls added to a context menu at launch.
By default, a custom button or menu item on the ribbon is available for use when the Office application launches. To deactivate it when Office starts, you must specify this in the manifest. The process depends on which type of manifest your add-in uses.
Note
The unified manifest for Microsoft 365 can be used in production Outlook add-ins. It's available only as a preview for Excel, PowerPoint, and Word add-ins.
Just add an "enabled" property with the value false
to the control or menu item object. The following shows the basic structure.
"extensions": [
...
{
...
"ribbons": [
...
{
...
"tabs": [
{
"id": "MyTab",
"groups": [
{
...
"controls": [
{
"id": "Contoso.MyButton1",
...
"enabled": false
}
]
}
]
}
]
}
]
}
]
Just add an Enabled element immediately below (not inside) the Action element of the control item. Then, set its value to false
.
The following shows the basic structure of a manifest that configures the <Enabled> element.
<OfficeApp ...>
...
<VersionOverrides ...>
...
<Hosts>
<Host ...>
...
<DesktopFormFactor>
<ExtensionPoint ...>
<CustomTab ...>
...
<Group ...>
...
<Control ... id="Contoso.MyButton3">
...
<Action ...>
<Enabled>false</Enabled>
...
</OfficeApp>
To update the availability of a button or menu item on the ribbon, perform the following steps.
The following is a simple example. Note that "MyButton", "OfficeAddinTab1", and "CustomGroup111" are copied from the manifest.
function enableButton() {
const ribbonUpdaterData = {
tabs: [
{
id: "OfficeAppTab1",
groups: [
{
id: "CustomGroup111",
controls: [
{
id: "MyButton",
enabled: true
}
]
}
]
}
]
};
Office.ribbon.requestUpdate(ribbonUpdaterData);
}
There are several interfaces (types) to make it easier to construct the RibbonUpdateData object.
The following is the equivalent example in TypeScript and it makes use of these types.
const enableButton = async () => {
const button: Control = { id: "MyButton", enabled: true };
const parentGroup: Group = { id: "CustomGroup111", controls: [button] };
const parentTab: Tab = { id: "OfficeAddinTab1", groups: [parentGroup] };
const ribbonUpdater: RibbonUpdaterData = { tabs: [parentTab] };
Office.ribbon.requestUpdate(ribbonUpdater);
}
Tip
You can await
the call of requestUpdate() if the parent function is asynchronous, but note that the Office application controls when it updates the state of the ribbon. The requestUpdate() method queues a request to update. The method will resolve the promise object as soon as it has queued the request, not when the ribbon actually updates.
The requestUpdate method is also used to toggle the visibility of a custom contextual tab. For details about this and example code, see Create custom contextual tabs in Office Add-ins.
A common scenario in which the state of a ribbon or context menu control should change is when a user-initiated event changes the add-in context. Consider a scenario in which a button should be available when, and only when, a chart is activated. Although the following example uses ribbon controls, a similar implementation can be applied to custom items on a context menu.
First, set the <Enabled> element for the button in the manifest to false
. For guidance on how to configure this, see Deactivate ribbon controls at launch.
Then, assign handlers. This is commonly done in the Office.onReady function as in the following example. In the example, handlers (created in a later step) are assigned to the onActivated and onDeactivated events of all the charts in an Excel worksheet.
Office.onReady(async () => {
await Excel.run((context) => {
const charts = context.workbook.worksheets
.getActiveWorksheet()
.charts;
charts.onActivated.add(enableChartFormat);
charts.onDeactivated.add(disableChartFormat);
return context.sync();
});
});
Define the enableChartFormat
handler. The following is a simple example. For a more robust way of changing a control's status, see Best practice: Test for control status errors.
function enableChartFormat() {
const button =
{
id: "ChartFormatButton",
enabled: true
};
const parentGroup =
{
id: "MyGroup",
controls: [button]
};
const parentTab =
{
id: "CustomChartTab",
groups: [parentGroup]
};
const ribbonUpdater = { tabs: [parentTab] };
Office.ribbon.requestUpdate(ribbonUpdater);
}
Define the disableChartFormat
handler. It's identical to the enableChartFormat
handler, except that the enabled property of the button object is set to false
.
In some circumstances, the ribbon or context menu doesn't repaint after requestUpdate
is called, so the control's clickable status doesn't change. For this reason it's a best practice for the add-in to keep track of the status of its controls. The add-in should conform to the following rules.
requestUpdate
is called, the code should record the intended state of the custom buttons and menu items.The following example shows a function that deactivates a button on the ribbon and records the button's status. In this example, chartFormatButtonEnabled
is a global boolean variable that's initialized to the same value as the Enabled element for the button in the add-in's manifest. Although the example uses a ribbon button, a similar implementation can be applied to custom items on a context menu.
function disableChartFormat() {
const button =
{
id: "ChartFormatButton",
enabled: false
};
const parentGroup =
{
id: "MyGroup",
controls: [button]
};
const parentTab =
{
id: "CustomChartTab",
groups: [parentGroup]
};
const ribbonUpdater = { tabs: [parentTab] };
Office.ribbon.requestUpdate(ribbonUpdater);
chartFormatButtonEnabled = false;
}
The following example shows how the button's handler tests for an incorrect state of the button. Note that reportError
is a function that shows or logs an error.
function chartFormatButtonHandler() {
if (chartFormatButtonEnabled) {
// Do work here.
} else {
// Report the error and try to make the button unavailable again.
reportError("That action is not possible at this time.");
disableChartFormat();
}
}
In some scenarios, Office is unable to update the ribbon or context menu and will return an error. For example, if the add-in is upgraded and the upgraded add-in has a different set of custom add-in commands, then the Office application must be closed and reopened. Until it is, the requestUpdate
method will return the error HostRestartNeeded
. The following is an example of how to handle this error. In this case, the reportError
method displays the error to the user. Although the example uses a ribbon button, a similar implementation can be applied to custom items on a context menu.
function disableChartFormat() {
try {
const button =
{
id: "ChartFormatButton",
enabled: false
};
const parentGroup =
{
id: "MyGroup",
controls: [button]
};
const parentTab =
{
id: "CustomChartTab",
groups: [parentGroup]
};
const ribbonUpdater = { tabs: [parentTab] };
Office.ribbon.requestUpdate(ribbonUpdater);
chartFormatButtonEnabled = false;
}
catch(error) {
if (error.code == "HostRestartNeeded"){
reportError("Contoso Awesome Add-in has been upgraded. Please save your work, close the Office application, and restart it.");
}
}
}
Office Add-ins feedback
Office Add-ins is an open source project. Select a link to provide feedback:
Training
Learning path
Use advance techniques in canvas apps to perform custom updates and optimization - Training
Use advance techniques in canvas apps to perform custom updates and optimization