Creating a dropdown menu in a SharePoint Online ribbon with JavaScript

Code Samples, SharePoint, SharePoint Apps

This article will explain how you can add a new Dropdown to the SharePoint Ribbon using JavaScript only. This script was developed and tested by adding the “.js” file containing all the bellow code to a content editor webpart in SharePoint Online.

Customizing the SharePoint Ribbon can be simple when working with simple buttons, but things get complicated when working with dropdowns. One example showing how to add a simple button to the Ribbon can be found  here but I couldn’t find any concluding examples showing how to add a dropdown to the ribbon with JavaScript.

Some useful information about the dropdown control in SharePoint Ribbon was found here.

After browsing trough all the articles I could find about adding a dropdown to the Ribbon, most of which were using an XML file, I came up with the next solution:

  1. Add all the necessary JavaScript references:

<script type="text/javascript" src="/_layouts/15/sp.init.debug.js"></script>
<script type="text/javascript" src="/_layouts/15/cui.debug.js"></script>
<script type="text/javascript" src="/_layouts/15/sp.ribbon.debug.js"></script>
<script type="text/javascript" src="/_layouts/15/sp.core.debug.js"></script>

  1. Register the ribbon_inited event handler, and register the PageComponent. Also wait for sp.ribbon.h5o be loaded:

ExecuteOrDelayUntilScriptLoaded(function () {
SelectRibbonTab("Ribbon.Read", true);
var pageManager = SP.Ribbon.PageManager.get_instance();
var ribbon = pageManager.get_ribbon();

if (ribbon == null || typeof (ribbon) == 'undefined') {
pageManager.add_ribbonInited(ribbon_init);
}
else {
ribbon_init();
}
}, 'sp.ribbon.js');

var ribbon_init = function () {
SelectRibbonTab('Ribbon.Browse', true);
CustomPageComponent.initializePageComponent();
var ribbon = (SP.Ribbon.PageManager.get_instance()).get_ribbon();
createSampleTab(ribbon);
applyCSSForDropdown();
};

  1. Create the necessary ribbon elements(tab, group, layout, section):

function createSampleTab(ribbon) {
var tabId = "Sample.Tab.Id";
var tabText = "Sample";
var tabDescription = "Samle tab";
var tabCommand = "Sample.Tab.Command";
var tab = new CUI.Tab(ribbon, tabId, tabText, tabDescription, tabCommand, false, '', null, null);
ribbon.addChild(tab);
creatSampleGroup(ribbon, tab);
SelectRibbonTab(tabId, true);
}
function creatSampleGroup(ribbon, tab) {
var groupId = "Sample.Group.Id";
var groupText = "Sample";
var groupDescription = "Sample Group";
var groupCommand = "Sample.Group.Command";
var group = new CUI.Group(ribbon, groupId, groupText, groupDescription, groupCommand, null);
tab.addChild(group);
var layout = new CUI.Layout(ribbon, 'Sample.Layout', 'The Layout');
group.addChild(layout);
var section = new CUI.Section(ribbon, 'Sample.Group.Section', 2, 'Top'); //2==OneRow
layout.addChild(section);
var row1 = section.getRow(1);
row1.addChild(addDropdownControlComponent(ribbon));
group.selectLayout('The Layout');
}

Screenshot with the created ribbon Tab and Group:

 

  1. Create the Dropdown Component:

function addDropdownControlComponent(ribbon) {
var dropDownId = "Sample.Dropdown.Id";
var dropDownLabelText = "Dropdown:";
var dropDownDescription = "Select a Value";
var dropDownCommand = "Dropdown.Command";
var dropDownQueryCommand = "Dropdown.QueryCommand";
var dropDownPopulateQueryCommand = "Dropdown.PopulateQueryCommand";
var controlProperties = new CUI.ControlProperties();
controlProperties.Id = dropDownId;
controlProperties.TemplateAlias = 'c5';
controlProperties.ToolTipTitle = dropDownLabelText;
controlProperties.ToolTipDescription = dropDownDescription;
controlProperties.LabelText = dropDownLabelText;
controlProperties.PopulateDynamically = "true";
controlProperties.PopulateOnlyOnce = "false";
controlProperties.Command = dropDownCommand;
controlProperties.QueryCommand = dropDownQueryCommand;
controlProperties.PopulateQueryCommand = dropDownPopulateQueryCommand;
var menu = new CUI.Menu(ribbon, 'Dropdown.Menu', 'menu name', '', 100);
var dll = new CUI.Controls.DropDown(ribbon, 'Dropdown', controlProperties, menu);
return dll.createComponentForDisplayMode('Medium');
}

This is how the dropdown will look on the ribbon:

  1. Create the PageComponent and implementing handlers for the commands:

/* Initialize the page component members */
var CustomPageComponent = function () {
CustomPageComponent.initializeBase(this);
};
CustomPageComponent.initializePageComponent = function () {
var ribbonPageManager = SP.Ribbon.PageManager.get_instance();
if (null !== ribbonPageManager) {
var rbnInstance = CustomPageComponent.get_instance();
ribbonPageManager.addPageComponent(rbnInstance);
}
};
CustomPageComponent.get_instance = function () {
if (CustomPageComponent.instance == null) {
CustomPageComponent.instance = new CustomPageComponent();
}
return CustomPageComponent.instance;
};
CustomPageComponent.prototype = {
/* Create an array of handled commands with handler methods */
init: function () {
this._handledCommands = new Object();
this._handledCommands['Sample.Tab.Command'] = { enable: function () { return true; }, handle: function (commandId, props, seq) { /*code*/ } };
this._handledCommands['Sample.Group.Command'] = { enable: function () { return true; }, handle: function (commandId, props, seq) { /*code*/ } };
this._handledCommands['Dropdown.Command'] = { enable: function () { return true; }, handle: function (commandId, props, seq) { } };
this._handledCommands['Dropdown.QueryCommand'] = { enable: function () { return true; }, handle: function (commandId, props, seq) { handleDropDownFilterQuery(commandId, props, seq); } };
this._handledCommands['Dropdown.PopulateQueryCommand'] = { enable: function () { return true; }, handle: function (commandId, props, seq) { PopulateViewOptions(commandId, props, seq); } };
this._handledCommands['Dropdown.Button.Command.one'] = { enable: function () { return true; }, handle: function (commandId, props, seq) { alert("Button one pressed"); } };
this._handledCommands['Dropdown.Button.Command.two'] = { enable: function () { return true; }, handle: function (commandId, props, seq) { alert("Button two pressed"); } };
this._handledCommands['Dropdown.Button.Command.three'] = { enable: function () { return true; }, handle: function (commandId, props, seq) { alert("Button three pressed"); } };
this._commands = ['Sample.Tab.Command',
'Sample.Group.Command',
'Dropdown.Command',
'Dropdown.QueryCommand',
'Dropdown.PopulateQueryCommand',
'Dropdown.Button.Command.one',
'Dropdown.Button.Command.two',
'Dropdown.Button.Command.three'
];},
getFocusedCommands: function () { return []; },
getGlobalCommands: function () { return this._commands; },
canHandleCommand: function (commandId) {
var handlerFn = this._handledCommands[commandId].enable;
if (typeof (handlerFn) == 'function') {
return handlerFn();
}
return true;
},
handleCommand: function (commandId, properties, sequence) {
return this._handledCommands[commandId].handle(commandId, properties, sequence);
},
isFocusable: function () { return false; },
yieldFocus: function () { return false; },
receiveFocus: function () { return true; },
handleGroup: function () { }
};

  1. Defining the necessary functions to build the menu inside the dropdown and add values to it:

/*Setting the default value: before any value from the dropdown is selected*/
function handleDropDownFilterQuery(commandId, properties, sequenceNumber) {
properties.Value = "Default";
return true;
}
/*Building the menu with buttons for the dropdown using a XML string*/
function PopulateViewOptions(commandId, properties, sequenceNumber) {
properties.PopulationXML = getDropdownItemsXml();
return true;
}
/*Building the XML string with the menu, menu sectionand buttons*/
function getDropdownItemsXml() {
var sb = new Sys.StringBuilder();
sb.append('<Menu Id=\'Dropdown.Menu\'>');
sb.append('<MenuSection DisplayMode=\'Menu\' Id=\'Dropdown.Menu.Section\'>');
sb.append('<Controls Id=\'Dropdown.Menu.Section.Controls\'>');
var dropdownOptions = ["one","two","three"];
for (var i = 0; i < dropdownOptions.length; i++) {
sb.append('<Button');
sb.append(' Id=\'Dropdown.Button.');
sb.append(i);
sb.append('\'');
sb.append(' Command=\'');
sb.append('Dropdown.Button.Command.');
sb.append(dropdownOptions[i]); // each button in the dropdown will have a different command ( Dropdown.Button.Command.one for first button, etc)
sb.append('\'');
sb.append(' LabelText=\'');
sb.append(dropdownOptions[i]); //button label
sb.append('\'');
sb.append(' CommandType=\'');
sb.append("General");
/*General - for typical command, OptionSelection - A command that is generated when a user selects one option in an option group,
IgnoredByMenu - A command that is used for controls that should not close the menu when selected.*/
sb.append('\'');
sb.append(' CommandValueId=\'');
sb.append("1");
sb.append('\'');
sb.append('/>');
}
sb.append('</Controls>');
sb.append('</MenuSection>');
sb.append('</Menu>');
return sb.toString();
}
function applyCSSForDropdown() {
var span = document.getElementById("Dropdown-Medium");
span.setAttribute("style", "margin-top:25px; padding-left:70px");
span.firstElementChild.setAttribute("style", "width: 80px");
var label = span.getElementsByTagName("label")[0];
label.removeAttribute("class");
label.setAttribute("style", "position:absolute; right:120px");
}
CustomPageComponent.registerClass('CustomPageComponent', CUI.Page.PageComponent);
NotifyScriptLoadedAndExecuteWaitingJobs('CustomPageComponent.js');

The final result(with default value, and other values inside the dropdown) is shown below:

The dropdown menu added above also has a hidden label in which the “controlProperties.LabelText” is displayed. If you need the label you can just remove it’s class(which makes it hidden) and use CSS to position it according to your needs.

Clicking on the “two” option of the dropdown will produce the next alert:

 

In conclusion I hope this will help those of you who work with the SharePoint Ribbon. After reading this article, you will have learned how to add a dropdown to the SharePoint Online Ribbon with JavaScript only.

What do you think?

  • Hi,

    thanks for your awesome article. 1 question, how to handle enable/disable button by javascript?

    • Hello,
      You can disable the dropdown component by setting the Dropdown.Command enable function to return false: this._handledCommands[‘Dropdown.Command’] = { enable: function () { return false; }, handle: function (commandId, props, seq) { } };

Click here to cancel reply.