Search code examples
ribbonoffice-js

Create a Custom Tab


When I start a new Excel Web Add-in, by default the blank project has a MyAppName.xml file that declares the ribbon. The declaration sets a custom group and a custom control under the native Home Excel tab.

What I want is to create a separate tab for my Addin. In the file project itself, there are these code lines:

<!-- Use OfficeTab to extend an existing Tab. Use CustomTab to create a new tab. -->
<OfficeTab id="TabHome">

So I changed OfficeTab for CustomTab, but now I get the message in the error list:

The element 'CustomTab' in namespace 'http://schemas.microsoft.com/office/taskpaneappversionoverrides' has incomplete content. List of possible elements expected: 'Group, Label' in namespace 'http://schemas.microsoft.com/office/taskpaneappversionoverrides'.

Do you know how I can create a custom tab? What am I doing wrong?

I'm using: Microsoft Visual Studio Enterprise 2017 Version 15.2 (26430.12) Release VisualStudio.15.Release/15.2.0+26430.12

Thanks.


Solution

  • Below is an example manifest that uses CustomTab. Can you compare your's with the example and see what might be different? Are you giving the CustomTab a unique ID? Does it have Group and Label child elements?

    <?xml version="1.0" encoding="utf-8"?>
    <OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="TaskPaneApp">
    
    <!-- See https://github.com/OfficeDev/Office-Add-in-Commands-Samples for documentation-->
    
    <!-- BeginBasicSettings: Add-in metadata, used for all versions of Office unless override provided -->
    
    <!--IMPORTANT! Id must be unique for your add-in. If you copy this manifest ensure that you change this id to your own GUID. -->
    <Id>e504fb41-a92a-4526-b101-542f357b7acb</Id>
    <Version>1.0.0.0</Version>
    <ProviderName>Contoso</ProviderName>
    <DefaultLocale>en-US</DefaultLocale>
    <!-- The display name of your add-in. Used on the store and various placed of the Office UI such as the add-ins dialog -->
    <DisplayName DefaultValue="Add-in Commands Sample" />
    <Description DefaultValue="Sample that illustrates add-in commands basic control types and actions" />
    <!--Icon for your add-in. Used on installation screens and the add-ins dialog -->
    <IconUrl DefaultValue="https://contoso.com/assets/icon-32.png" />
    <HighResolutionIconUrl DefaultValue="https://contoso.com/assets/hi-res-icon.png" />
    <SupportUrl DefaultValue="[Insert the URL of a page that provides support information for the app]" />
    <!--BeginTaskpaneMode integration. Office 2013 and any client that doesn't understand commands will use this section.
      This section will also be used if there are no VersionOverrides -->
    <Hosts>
      <Host Name="Document"/>
    </Hosts>
    <DefaultSettings>
      <SourceLocation DefaultValue="https://commandsimple.azurewebsites.net/Taskpane.html" />
    </DefaultSettings>
    <!--EndTaskpaneMode integration -->
    
    <Permissions>ReadWriteDocument</Permissions>
    
    <!--BeginAddinCommandsMode integration-->
    <VersionOverrides xmlns="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="VersionOverridesV1_0">
      <Hosts>
        <!--Each host can have a different set of commands. Cool huh!? -->
        <!-- Workbook=Excel Document=Word Presentation=PowerPoint -->
        <!-- Make sure the hosts you override match the hosts declared in the top section of the manifest -->
        <Host xsi:type="Document">
          <!-- Form factor. Currently only DesktopFormFactor is supported. We will add TabletFormFactor and PhoneFormFactor in the future-->
          <DesktopFormFactor>
            <!--Function file is an html page that includes the javascript where functions for ExecuteAction will be called.
            Think of the FunctionFile as the "code behind" ExecuteFunction-->
            <FunctionFile resid="Contoso.FunctionFile.Url" />
    
            <!--PrimaryCommandSurface==Main Office app ribbon-->
            <ExtensionPoint xsi:type="PrimaryCommandSurface">
              <!--Use OfficeTab to extend an existing Tab. Use CustomTab to create a new tab -->
              <!-- Documentation includes all the IDs currently tested to work -->
              <CustomTab id="Contoso.Tab1">
                <!--Group ID-->
                <Group id="Contoso.Tab1.Group1">
                  <!--Label for your group. resid must point to a ShortString resource -->
                  <Label resid="Contoso.Tab1.GroupLabel" />
                  <Icon>
                  <!-- Sample Todo: Each size needs its own icon resource or it will look distorted when resized -->
                    <!--Icons. Required sizes: 16, 32, 80; optional: 20, 24, 40, 48, 64. You should provide as many sizes as possible for a great user experience. -->
                    <!--Use PNG icons and remember that all URLs on the resources section must use HTTPS -->
                    <bt:Image size="16" resid="Contoso.TaskpaneButton.Icon16" />
                    <bt:Image size="32" resid="Contoso.TaskpaneButton.Icon32" />
                    <bt:Image size="80" resid="Contoso.TaskpaneButton.Icon80" />
                  </Icon>
    
                  <!--Control. It can be of type "Button" or "Menu" -->
                  <Control xsi:type="Button" id="Contoso.FunctionButton">
                    <!--Label for your button. resid must point to a ShortString resource -->
                    <Label resid="Contoso.FunctionButton.Label" />
                    <Supertip>
                      <!--ToolTip title. resid must point to a ShortString resource -->
                      <Title resid="Contoso.FunctionButton.Label" />
                      <!--ToolTip description. resid must point to a LongString resource -->
                      <Description resid="Contoso.FunctionButton.Tooltip" />
                    </Supertip>
                    <Icon>
                      <bt:Image size="16" resid="Contoso.FunctionButton.Icon16" />
                      <bt:Image size="32" resid="Contoso.FunctionButton.Icon32" />
                      <bt:Image size="80" resid="Contoso.FunctionButton.Icon80" />
                    </Icon>
                    <!--This is what happens when the command is triggered (E.g. click on the Ribbon). Supported actions are ExecuteFunction or ShowTaskpane-->
                    <!--Look at the FunctionFile.html page for reference on how to implement the function -->
                    <Action xsi:type="ExecuteFunction">
                      <!--Name of the function to call. This function needs to exist in the global DOM namespace of the function file-->
                      <FunctionName>writeText</FunctionName>
                    </Action>
                  </Control>
    
                  <Control xsi:type="Button" id="Contoso.TaskpaneButton">
                    <Label resid="Contoso.TaskpaneButton.Label" />
                    <Supertip>
                      <Title resid="Contoso.TaskpaneButton.Label" />
                      <Description resid="Contoso.TaskpaneButton.Tooltip" />
                    </Supertip>
                    <Icon>
                      <bt:Image size="16" resid="Contoso.TaskpaneButton.Icon16" />
                      <bt:Image size="32" resid="Contoso.TaskpaneButton.Icon32" />
                      <bt:Image size="80" resid="Contoso.TaskpaneButton.Icon80" />
                    </Icon>
                    <Action xsi:type="ShowTaskpane">
                      <TaskpaneId>Button2Id1</TaskpaneId>
                      <!--Provide a url resource id for the location that will be displayed on the task pane -->
                      <SourceLocation resid="Contoso.Taskpane1.Url" />
                    </Action>
                  </Control>
                  <!-- Menu example -->
                  <Control xsi:type="Menu" id="Contoso.Menu">
                    <Label resid="Contoso.Dropdown.Label" />
                    <Supertip>
                      <Title resid="Contoso.Dropdown.Label" />
                      <Description resid="Contoso.Dropdown.Tooltip" />
                    </Supertip>
                    <Icon>
                      <bt:Image size="16" resid="Contoso.TaskpaneButton.Icon16" />
                      <bt:Image size="32" resid="Contoso.TaskpaneButton.Icon32" />
                      <bt:Image size="80" resid="Contoso.TaskpaneButton.Icon80" />
                    </Icon>
                    <Items>
                      <Item id="Contoso.Menu.Item1">
                        <Label resid="Contoso.Item1.Label"/>
                        <Supertip>
                          <Title resid="Contoso.Item1.Label" />
                          <Description resid="Contoso.Item1.Tooltip" />
                        </Supertip>
                        <Icon>
                          <bt:Image size="16" resid="Contoso.TaskpaneButton.Icon16" />
                          <bt:Image size="32" resid="Contoso.TaskpaneButton.Icon32" />
                          <bt:Image size="80" resid="Contoso.TaskpaneButton.Icon80" />
                        </Icon>
                        <Action xsi:type="ShowTaskpane">
                          <TaskpaneId>MyTaskPaneID1</TaskpaneId>
                          <SourceLocation resid="Contoso.Taskpane1.Url" />
                        </Action>
                      </Item>
    
                      <Item id="Contoso.Menu.Item2">
                        <Label resid="Contoso.Item2.Label"/>
                        <Supertip>
                          <Title resid="Contoso.Item2.Label" />
                          <Description resid="Contoso.Item2.Tooltip" />
                        </Supertip>
                        <Icon>
                          <bt:Image size="16" resid="Contoso.TaskpaneButton.Icon16" />
                          <bt:Image size="32" resid="Contoso.TaskpaneButton.Icon32" />
                          <bt:Image size="80" resid="Contoso.TaskpaneButton.Icon80" />
                        </Icon>
                        <Action xsi:type="ShowTaskpane">
                          <TaskpaneId>MyTaskPaneID2</TaskpaneId>
                          <SourceLocation resid="Contoso.Taskpane2.Url" />
                        </Action>
                      </Item>
    
                    </Items>
                  </Control>
    
                </Group>
    
                <!-- Label of your tab -->
                <!-- If validating with XSD it needs to be at the end -->
                <Label resid="Contoso.Tab1.TabLabel" />
              </CustomTab>
            </ExtensionPoint>
          </DesktopFormFactor>
        </Host>
      </Hosts>
      <Resources>
        <bt:Images>
          <bt:Image id="Contoso.TaskpaneButton.Icon16" DefaultValue="https://myCDN/Images/Button16x16.png" />
          <bt:Image id="Contoso.TaskpaneButton.Icon32" DefaultValue="https://myCDN/Images/Button32x32.png" />
          <bt:Image id="Contoso.TaskpaneButton.Icon80" DefaultValue="https://myCDN/Images/Button80x80.png" />
          <bt:Image id="Contoso.FunctionButton.Icon" DefaultValue="https://myCDN/Images/ButtonFunction.png" />
        </bt:Images>
        <bt:Urls>
          <bt:Url id="Contoso.FunctionFile.Url" DefaultValue="https://commandsimple.azurewebsites.net/FunctionFile.html" />
          <bt:Url id="Contoso.Taskpane1.Url" DefaultValue="https://commandsimple.azurewebsites.net/Taskpane.html" />
          <bt:Url id="Contoso.Taskpane2.Url" DefaultValue="https://commandsimple.azurewebsites.net/Taskpane2.html" />
        </bt:Urls>
        <bt:ShortStrings>
          <bt:String id="Contoso.FunctionButton.Label" DefaultValue="Execute Function" />
          <bt:String id="Contoso.TaskpaneButton.Label" DefaultValue="Show Taskpane" />
          <bt:String id="Contoso.Dropdown.Label" DefaultValue="Dropdown" />
          <bt:String id="Contoso.Item1.Label" DefaultValue="Show Taskpane 1" />
          <bt:String id="Contoso.Item2.Label" DefaultValue="Show Taskpane 2" />
          <bt:String id="Contoso.Tab1.GroupLabel" DefaultValue="Test Group" />
           <bt:String id="Contoso.Tab1.TabLabel" DefaultValue="Test Tab" />
        </bt:ShortStrings>
        <bt:LongStrings>
          <bt:String id="Contoso.FunctionButton.Tooltip" DefaultValue="Click to Execute Function" />
          <bt:String id="Contoso.TaskpaneButton.Tooltip" DefaultValue="Click to Show a Taskpane" />
          <bt:String id="Contoso.Dropdown.Tooltip" DefaultValue="Click to Show Options on this Menu" />
          <bt:String id="Contoso.Item1.Tooltip" DefaultValue="Click to Show Taskpane1" />
          <bt:String id="Contoso.Item2.Tooltip" DefaultValue="Click to Show Taskpane2" />
        </bt:LongStrings>
      </Resources>
    </VersionOverrides>
    </OfficeApp>
    

    See also this article and the samples it links to. And check out Validate and Troubleshoot your Manifest too.