Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I'm trying to add a Custom tab with a group and some buttons to a single client via conditional javascript, as far as i can tell this is all found in the CUI namespace, however documentation is hard to find.

i've found a partial example here however this example ends up only adding a tab and a group.

one thing i noticed is that there is no group template, so maybe adding that might help me. Also , the button doesn't get added to the section row, perhaps there are some more properties that need to be set somewhere, i'm not sure what else might be missing.

share|improve this question
1  
How did you go? Did you end up getting it working? –  Russell Jan 9 at 7:25
    
Hey, sorry for the very delayed response, I did figure this out, i posted an answer below if you are still curious. –  Gilgamesh Aug 26 at 12:26

2 Answers 2

This might help, it's a Similar scenario - Add User Custom Actions Using JavaScript

share|improve this answer
    
That adds a custom action to a context menu, not the ribbon, although does explain CA in JS. –  Russell Jan 9 at 7:24
up vote 0 down vote accepted

I realize that this response is very delayed but I figured out how to do this after a lot of reverse engineering and maybe this will save someone else some time.

To better understand and improve on this example, it will be helpful to:

  1. Have an understanding of how a ribbon is created and how commands are registered
  2. Take a look at the sp.ribbon.js file and explore various properties at run time.
  3. Understand that any variable that start with $ might not be the same in other environments. My example works in the dozen or some environments where this code is used, however i have observed other ribbon control variables that start with $ change across 2010 environments. From 2010 to 2013 these variables all change as well.

For my example we will be adding a Group, Sections, Row and Button to the initial Tab of the ribbon on the EditForm.aspx page.

To run this, you can open the edit for page, select the correct frame, Load JQuery and then execute this JavaScript.

//This example requires JQuery to run because of $.extend()
Type.registerNamespace('Foo.Ribbon');

//This class is used to help enable controls we create after the ribbon has been built.
Foo.Ribbon.CustomChild = function () {
    this.customChildren = [];
};

//Note: this method will need modifying to support controls like menus
//this will enable the control all all custom child controls it contains
Foo.Ribbon.EnableControl = function (control) {
    if (control) {
        control.set_enabled(true);
        if (control.set_enabledInternal) {
        control.set_enabledInternal(true);
        }
        if (control.customChildren) {
            var length = control.customChildren.length;
            if (length < 1) {
               control.set_enabled(false);
            } else {
                var element = null;
                var tempChildren = [];
                for (var i = 0; i < length; i++) {
                    element = control.customChildren[i];
                    Foo.Ribbon.EnableControl(element);
                }
            }
        }
    }
};


//First we need to make sure the ribbon is initialized
_ribbonStartInit(_ribbon.initialTabId, false, null);
//Get the instance of the ribbon
var ribbon = (SP.Ribbon.PageManager.get_instance()).get_ribbon();
//Get the initial tab the ribbon loaded, this is the tab we will use.
var tab  = ribbon.getChild("Ribbon.DocLibListForm.Edit");
//Get the page manage
var pageManager = SP.Ribbon.PageManager.get_instance();

//Create a new group for our controls to go into
var group = new CUI.Group(ribbon, 'Foo.Group', 'Foo Group', 'Foo Controls',         'Foo.Group.Command', null);
//Create a new layout and add it to the group.
var layout = new CUI.Layout(ribbon, 'Foo.Layout', 'Foo.Layout');
group.addChild(layout);
group.selectLayout(layout.get_title(), layout);

//Create a section
var  section = new CUI.Section(ribbon, 'Foo.Section.Small', 4, 'Top');
$.extend(section, new Foo.Ribbon.CustomChild());
//Add a section to the layout
layout.addChild(section);

//Get the row we want to add a button to
var row1 = section.getRow(1);
//Define control properties for the button we are about to create
var controlProperties = new CUI.ControlProperties();
//Include desired properties.
//This property is the ID for the command we are giving the button
controlProperties.Command = 'Foo.Button.Command';
controlProperties.TemplateAlias = 'o1';
controlProperties.ToolTipTitle = "Click Me";
controlProperties.Image16by16 = "images/SomeImage.png";
//Create a new Button
var fooButton = new CUI.Controls.Button(ribbon, 'Foo.Button', controlProperties);
//Create a control component for the button
var controlComponent = new CUI.ControlComponent(ribbon, 'Foo.MenuItem.Button', 'Medium', fooButton);
//Link the control component back to the button, this looks weird but is necessary.
//The use of the variable $2J_1 is very bad this changes between SharePoint versions
fooButton.$2J_1 = fooButton.get_id();
fooButton.get_components().push(controlComponent);
//Make sure the button is part of our custom class, this is important for making sure     the button stays enabled
section.customChildren.push(fooButton);
//Add the control component(and button) to the row
row1.addChild(controlComponent);
//Add the group to our tab once we have created and attached all the controls
tab.addChild(group);
//This is sort of hacky, but a custom command needs to be created to enable all the     custom controls When RefreshCommandUI() is called
var cmd = new Object();
cmd.handleCommand = function (commandId, properties, sequenceNumber) {
        var length = section.customChildren.length;
        if (length > 0) {
            var element = null;
            for (var i = 0; i < length; i++) {
                element = section.customChildren[i];
                if (element) {
                    Foo.Ribbon.EnableControl(element);
                }
            }
        }
};
//Get the dispatcher
var dispatcher = pageManager.get_commandDispatcher();   
//Register our refresh command with the dispatched
dispatcher.registerCommandHandler(Commands.CommandIds.ApplicationStateChanged, cmd);

//Create a click command for our button
var buttonCmd = new Object();
//This specifies that the button has a command and can be clicked
buttonCmd.canHandleCommand = function (commandId) {
    return true;
}
//The command that is executed when the button is clicked
buttonCmd.handleCommand = function (commandId, properties, sequenceNumber) {
    alert("Button Clicked");
}
//'Foo.Button.Command' is the CommandID and must match the controlProperties.Command
dispatcher.registerCommandHandler('Foo.Button.Command', buttonCmd);
//Refresh the UI so our control(s) are enabled
RefreshCommandUI();

Expanding on this example it's possible to create any control it might take a little bit of digging into the API but it's certainly possible.

I also want to leave a disclaimer that just because you can modify the ribbon from the browser with JavaScript doesn't mean you should. If you think this is the solution to a problem there's a very good chance that there's a better solution using more traditional methods to interact with the ribbon.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.