The Ribbon Workbench for CRM 2011 makes it very easy to add menu items and sections, but occasionally you may need to dynamically change the menu items depending on run-time variables such as the selected record or security roles.
The following video shows adding a Flyout Anchor menu that is populated dynamically when opened.
The tutorial performs the following steps:
- Adding the DynamicMenu.js WebResource to the solution. This contains two functions, one that creates the dynamic menu and another that is called when a menu item is clicked.
- Adding of a Flyout Anchor button to the Contact Homepage Ribbon
- Creating a command that is used to dynamically populate the menu items. The command has an action that calls the populateDynamicMenu function in the DynamicMenu.js WebResource. A CommandProperties CrmParameter is passed to the function which is used to set the PopulationXML property with the Menu Xml. This Menu Xml has the same format as the Ribbon Xml Menu items, so you could use the Ribbon Workbench to create a set of menu items and then copy the generated Xml to use as a template.
- The command is then set as the PopulateQueryCommand for the new Flyout Anchor Button.
- The MenuXml returned by the PopulateQueryCommand contains references to a command that is run when the menu item is clicked, so this command is then created passing the CommandProperties again as a parameter. This time, the CommandProperties are used to determine which item was clicked by looking at the value of the ‘SourceControlId’ property.
The DynamicMenu.js Webresource is:
function populateDynamicMenu(commandProperties)
{
// Dynamically return the menu to show - this can be built at run time
commandProperties["PopulationXML"]='<Menu Id="demo.CustomReportMenu"><MenuSection Id="demo.CustomReportSection" Sequence="10"><Controls Id="demo.CustomReportControls"><Button Id="demo.CustomReportMenu.Button1" Command="demo.contact.ItemClicked.Command" Sequence="30" LabelText="Custom Report" /></Controls></MenuSection></Menu>';
}
function itemClicked(commandProperties)
{
// Determine which button was clicked in the menu
alert(commandProperties.SourceControlId+ ' clicked');
}
The generated Ribbon Xml is:
<RibbonDiffXml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<CustomActions>
<CustomAction Id="demo.contact.Button1.Button.CustomAction"
Location="Mscrm.HomepageGrid.contact.MainTab.Management.Controls._children" Sequence="29">
<CommandUIDefinition>
<FlyoutAnchor Command="Mscrm.Enabled" Id="demo.contact.Button1.Button"
Image16by16="$webresource:new_Image16.png" Image32by32="$webresource:new_Image32.png"
LabelText="$LocLabels:demo.contact.Button1.Button.LabelText" PopulateDynamically="true"
PopulateQueryCommand="demo.contact.PopulateMenu.Command" Sequence="29" TemplateAlias="o3">
<Menu Id="demo.contact.Button1.Button.Menu">
<MenuSection Id="demo.contact.Section2.Section" Sequence="10" DisplayMode="Menu16">
<Controls Id="demo.contact.Section2.Section.Controls" />
</MenuSection>
</Menu>
</FlyoutAnchor>
</CommandUIDefinition>
</CustomAction>
</CustomActions>
<Templates>
<RibbonTemplates Id="Mscrm.Templates" />
</Templates>
<CommandDefinitions>
<CommandDefinition Id="demo.contact.PopulateMenu.Command">
<EnableRules />
<DisplayRules />
<Actions>
<JavaScriptFunction FunctionName="populateDynamicMenu" Library="$webresource:demo_DynamicMenu.js">
<CrmParameter Value="CommandProperties" />
</JavaScriptFunction>
</Actions>
</CommandDefinition>
<CommandDefinition Id="demo.contact.ItemClicked.Command">
<EnableRules />
<DisplayRules />
<Actions>
<JavaScriptFunction FunctionName="itemClicked" Library="$webresource:demo_DynamicMenu.js">
<CrmParameter Value="CommandProperties" />
</JavaScriptFunction>
</Actions>
</CommandDefinition>
</CommandDefinitions>
<RuleDefinitions>
<TabDisplayRules />
<DisplayRules />
<EnableRules />
</RuleDefinitions>
<LocLabels>
<LocLabel Id="demo.contact.Button1.Button.LabelText">
<Titles>
<Title description="Dynamic Menu" languagecode="1033" />
</Titles>
</LocLabel>
</LocLabels>
</RibbonDiffXml>