Creating SharePoint ribbon elements in JavaScript

Code Samples, SharePoint, SharePoint Apps

When developing SharePoint 2013 hosted Apps, you might want to add a ribbon to your App pages. But, you’re limited on using javascript as no server-side scripting is allowed. This article explains how to add a new button to the ribbon in a new tab. Some inspiration came from here and here, and below there’s a full working example.

Working with ribbon in a SharePoint App involves a few steps:

1). Add JavaScript references to several needed files. You can use SOD (Script on Demand) loading, as explained here, or you can include the files directly.
2). Register an event handler with the Page Manager that will  notify you when the ribbon has been initialized and is available. Register a Page Component to handle the new ribbon commands.
3). Create the ribbon elements (tabs, groups, buttons, etc).

Let’s get started.

1. Add JavaScript references

The files needed are all located under /_layouts/15/ :

<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>

2. Register the ribbon_inited event handler, and register the PageComponent

 

$(document).ready(function () {
(SP.Ribbon.PageManager.get_instance()).add_ribbonInited(ribbon_init);
SelectRibbonTab('Ribbon.Read', true);
SamplePageComponent.initializePageComponent();
});

3. Create the ribbon elements

function ribbon_init() {
var ribbon = (SP.Ribbon.PageManager.get_instance()).get_ribbon();
createTab(ribbon);
}

function createTab(ribbon) {

var tab = new CUI.Tab(ribbon, 'Sample.Tab', Sample', 'Tab description', 'Sample.Tab.Command', false, '', null, null);
ribbon.addChild(tab);

var group = new CUI.Group(ribbon, 'Sample.Tab.Group', 'Sample Group', 'Group Description', 'Sample.Group.Command', null);
tab.addChild(group);

var layout = new CUI.Layout(ribbon, 'Sample.Layout', 'The Layout');
group.addChild(layout);

var section = new CUI.Section(ribbon, 'Sample.Section', 2, 'Top'); //2==OneRow
layout.addChild(section);
var controlProperties = new CUI.ControlProperties();
controlProperties.Command = 'Sample.Button.Command';
controlProperties.Id = 'Sample.ControlProperties';
controlProperties.TemplateAlias = 'o1';
controlProperties.ToolTipDescription = 'Use this button';
controlProperties.Image32by32 = '_layouts/15/images/placeholder32x32.png';
controlProperties.ToolTipTitle = 'A Button';
controlProperties.LabelText = 'Something';
var button = new CUI.Controls.Button(ribbon, 'Sample.Button', controlProperties);

var controlComponent = button.createComponentForDisplayMode('Large');
var row1 = section.getRow(1);

row1.addChild(controlComponent);
group.selectLayout('The Layout');

SelectRibbonTab('Sample.Tab', true);

}

Creating the page component involves deriving from the CUI.Page.PageComponent JS class and implementing handlers for the commands:

/* Initialize the page component members */
SamplePageComponent = function () {
SamplePageComponent.initializeBase(this);
}
SamplePageComponent.initializePageComponent = function () {
var ribbonPageManager = SP.Ribbon.PageManager.get_instance();
if (null !== ribbonPageManager) {
var rbnInstance = SamplePageComponent.get_instance();
ribbonPageManager.addPageComponent(rbnInstance);
}
}

SamplePageComponent.get_instance = function () {
if (SamplePageComponent.instance == null) {
SamplePageComponent.instance = new SamplePageComponent();
}
return SamplePageComponent.instance;
}

SamplePageComponent.prototype = {
/* Create an array of handled commands with handler methods */
init: function () {
var buttonEnabled = false;

this._handledCommands = new Object();
this._handledCommands['Sample.Tab.Command'] = { enable: function () { return true; }, handle: function (commandId, props, seq) { /* do action */ } };
this._handledCommands['Sample.Group.Command'] = { enable: function () { return true; }, handle: function (commandId, props, seq) { /* do action */ } };
this._handledCommands['Sample.Button.Command'] = { enable: function () { return buttonEnabled; }, handle: function (commandId, props, seq) { /* do action */ } };
this._commands = ['Sample.Tab.Command', 'Sample.Group.Command', 'Sample.Button.Command'];

$('#buttonEnable').click(function () {
buttonEnabled = !buttonEnabled;
var ribbon = SP.Ribbon.PageManager.get_instance().get_ribbon();
ribbon.setFocusOnRibbon();
ribbon.pollForStateAndUpdate();
SelectRibbonTab('Sample.Tab', true);
});
},

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 () { }

}
/* Register classes and initialize page component */
SamplePageComponent.registerClass('SamplePageComponent', CUI.Page.PageComponent);
NotifyScriptLoadedAndExecuteWaitingJobs('SamplePageComponent.js');

 

 

What do you think?

  • Do you have something for SharePoint 2010? Thanks!

  • For SharePoint 2010 should be essentially the same code. The paths for the scripts should of course not include /15, and possibly some parameters are not required.

    Did you try it?

  • I had to make some changes and was able to add the button. However, it appears as disabled. I am trying to add a global tab with buttons for the whole site.

    function ribbon_init() {
    var ribbon = (SP.Ribbon.PageManager.get_instance()).get_ribbon();

    alert(SP.Ribbon.PageManager.get_instance());
    createTab(ribbon);
    }

    function createTab(ribbon) {

    var tab = new CUI.Tab(ribbon, ‘Sample.Tab’, ‘Sample’, ‘Tab Description’, ‘Sample.Tab.Command’, false, ”, null,null);
    ribbon.addChild(tab);
    var group = new CUI.Group(ribbon, ‘Sample.Tab.Group’, ‘Sample Actions’, ‘Group Description’, ‘Sample.Group.Command’, null);
    tab.addChild(group);
    var layout = new CUI.Layout(ribbon, ‘Sample.Layout’, ‘The Layout’);
    group.addChild(layout);
    var section = new CUI.Section(ribbon, ‘Sample.Section’, 2, ‘Top’); //2==OneRow
    layout.addChild(section);

    var controlProperties = new CUI.ControlProperties();
    controlProperties.Command = ‘Sample.Button.Command’;
    controlProperties.Id = ‘Sample.ControlProperties’;
    controlProperties.TemplateAlias = ‘o1’;
    controlProperties.ToolTipDescription = ‘Use this button’;
    controlProperties.Image32by32 = ‘/_layouts/images/placeholder32x32.png’;
    controlProperties.ToolTipTitle = ‘A Button’;
    controlProperties.LabelText = ‘Something’;

    var button = new CUI.Controls.Button(ribbon, ‘Sample.Button’, controlProperties);

    var controlComponent = button.createComponentForDisplayMode(‘Large’);
    var row1 = section.getRow(1);

    row1.addChild(controlComponent);
    group.selectLayout(‘The Layout’);

    SelectRibbonTab(‘Sample.Tab’, true);
    }

    SP.SOD.executeOrDelayUntilScriptLoaded(function () {

    var pm = SP.Ribbon.PageManager.get_instance();

    pm.add_ribbonInited(function () {
    ribbon_init();
    /* Register classes and initialize page component */
    SamplePageComponent.registerClass(‘SamplePageComponent’, CUI.Page.PageComponent);
    SamplePageComponent.initializePageComponent();
    //NotifyScriptLoadedAndExecuteWaitingJobs(‘SamplePageComponent.js’);

    });

    }, ”
    sp.ribbon.js “);

    try
    {
    /* Initialize the page component members */
    SamplePageComponent = function () {
    SamplePageComponent.initializeBase(this);
    }
    SamplePageComponent.initializePageComponent = function () {
    var ribbonPageManager = SP.Ribbon.PageManager.get_instance();
    if (null !== ribbonPageManager) {
    var rbnInstance = SamplePageComponent.get_instance();
    ribbonPageManager.addPageComponent(rbnInstance);
    }
    }

    SamplePageComponent.get_instance = function () {
    if (SamplePageComponent.instance == null) {
    SamplePageComponent.instance = new SamplePageComponent();
    }
    return SamplePageComponent.instance;
    }

    SamplePageComponent.prototype = {
    /* Create an array of handled commands with handler methods */
    init: function () {
    var buttonEnabled = false;

    this._handledCommands = new Object();
    this._handledCommands[‘Sample.Tab.Command’] = { enable: function () { return true; }, handle: function (commandId, props, seq) { /* do action */ } };
    this._handledCommands[‘Sample.Group.Command’] = { enable: function () { return true; }, handle: function (commandId, props, seq) { /* do action */ } };
    this._handledCommands[‘Sample.Button.Command’] = { enable: function () { return buttonEnabled; }, handle: function (commandId, props, seq) { /* do action */ } };
    this._commands = [‘Sample.Tab.Command’, ‘Sample.Group.Command’, ‘Sample.Button.Command’];

    $(‘#buttonEnable’).click(function () {
    buttonEnabled = !buttonEnabled;
    var ribbon = SP.Ribbon.PageManager.get_instance().get_ribbon();
    ribbon.setFocusOnRibbon();
    ribbon.pollForStateAndUpdate();
    SelectRibbonTab(‘Sample.Tab’, true);
    });
    },

    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 () { }

    }
    }
    catch(error)
    {
    alert(error);
    }

  • Finally got it working!

    Changed
    this._handledCommands[‘Sample.Button.Command’] = { enable: function () { return buttonEnabled; },

    to

    this._handledCommands[‘Sample.Button.Command’] = { enable: function () { return true;

  • Hi i am trying to add button to existing Tabs in Ribbon but keep getting this error saying ‘Only children of type Tab can be added to a Ribbon’. Question is it possible to add button, group or section to existing Ribbon Tab with this method?

  • I was able to add button to existing tab but button still appears disabled. Were you ever able to make it enabled. Any ideas where to look.

  • Awesome, working great for me. For those who are finding the ribbon button disabled, add the following to your HTML code

    Enable

  • Thanks a lot worked like a charm in one shot.

  • Stephan Onisick

    Will this work in SharePoint 2013 on premise?

    thanks,
    Stephan