Ribbon Customization

Hi,

I have got chance to research on SharePoint Ribbon. I found few basics about the ribbon and implemented some of basic customization demos. For a beginner I think below demos are very helpful. I will first start explaining some basics of ribbon control.

The Out-of-Box ribbon is rendered by a single Xml file resides in 14 hive at location ...\14\template\global\xml\cmdui.xml. Now in order to customize this we have to override the functionality of cmdui.xml file or extend it the way we want. There are the several ways VS 2010 development tool provides us to create/deploy a xml file but I think creating a module is quite simple and professional way to implement.

Ribbon Components:




  1. Tab: Tabs are the root of the Server ribbon. They contain one or more groups, and contain similar functions. For example, in Figure 2, the Page tab that is currently selected contains functions that pertain to working with the current page.

  2. Group:Every tab in the ribbon contains a series of one or more groups. Groups are used to associate controls with similar functionality. Each group is associated with a template that defines the layout of the group and how the group should appear based on the scale of the ribbon. The scale of the ribbon refers to situations where there are too many controls to show in the ribbon, for example, when the browser is not in a full-screen maximized state and is in a windowed state.

  3. Control:The ribbon would not be complete if users did not have anything to select or click. Controls are the items that live inside the ribbon that users can interact with. Controls reside within groups. These include things such as buttons, toggle buttons, check boxes, text boxes and many other controls.

  4. Contextual tab group:Contextual tab groups are used to provide functions that are not global to the current context, such as the page. They appear only when certain circumstances have been met and contain one or more tabs.


A ribbon can have mutiple tabs, each tab mutiple groups and each group multiple controls. These controls can be a Button, CheckBox, Dropdown etc. The complete list is here: Button, CheckBox, ComboBox, DropDown, FlyoutAnchor, GalleryButton, Label, MRUSplitButton, Spinner, SplitButton, TextBox, ToggleButton.

Any ribbon customization should be mounted within xml in feature declaration. The special xml tag exists for this purpose. Here is the example how it usually looks like:

<CustomAction
Id="[Your_custom_action_ID]"
RegistrationType="[Scope of the custom action eg. List]"
RegistrationId="[Id of the list]"
Location="CommandUI.Ribbon">
<CommandUIExtension>
<CommandUIDefinitions>
<CommandUIDefinition>

</CommandUIDefinition>
</CommandUIDefinitions>

<CommandUIHandlers>
</CommandUIHandlers>
</CommandUIExtension>
</CustomAction>

The CustomAction xml tag should have its Id in corresponding attribute – unique text value. The value for Location attribute should always be set to "CommandUI.Ribbon", independently on what kind of ribbon customization it is created for. The CommandUIDefinitions tag should contain CommandUIDefinition child tags declaring all controls or containers which should be created (i.e. buttons, groups, tabs, etc.).

The CommandUIHandlers tag can contain commands declarations for registered controls, so some JavaScript code can be executed. It is not necessary to register all commands in custom action – it can be done on server (webpart/page code-behind). The way how to do it will be described in next.

I. Adding custom button to existing group

Here is the example of declaring button control to be added to the ribbon which should be added to Shared Document doc library xml node

<CustomAction Id="CustomRibbonButton"
RegistrationType="List"
RegistrationId="101"
Location="CommandUI.Ribbon">
<CommandUIExtension>
<CommandUIDefinitions>
<CommandUIDefinition
Location="Ribbon.Documents.New.Controls._children">
<Button
Id="Ribbon.Documents.New.Controls.CustomButton"
Alt="Custom Ribbon Button"
Sequence="10"
Image32by32="/_layouts/images/DWSHOME.GIF"
Command="Custom_RibbonButton"
LabelText="Custom Ribbon Button"
TemplateAlias="o2"/>
</CommandUIDefinition>
</CommandUIDefinitions>
<CommandUIHandlers>
<CommandUIHandler
Command="Custom_RibbonButton"
CommandAction="javascript:window.open('http://mohitvash.wordpress.com/');" />
</CommandUIHandlers>
</CommandUIExtension>
</CustomAction>

Details of value of CommandUIDefinition Location: [Existing_Group_ID].Controls._children. You can find group’s ID in its declaration xml or using IE Dev Toolbar (the Group node is rendered as <li id="[TabID]">…</li> html tag)

II. Adding Custom group to existing tab:

Here is example how to add a custom group to the shared document library:

<CustomAction Id="Ribbon.Documents.CustomGroupInExsitingTab" RegistrationType="List" RegistrationId="101" Location="CommandUI.Ribbon" >
<CommandUIExtension>
<CommandUIDefinitions>
<CommandUIDefinition Location="Ribbon.Documents.Scaling._children">
<MaxSize Id="Ribbon.Documents.CustomGroup.MaxSize" GroupId="Ribbon.Documents.CustomGroup" Size="LargeLarge" Sequence="10" />
</CommandUIDefinition>
<CommandUIDefinition Location="Ribbon.Documents.Scaling._children">
<Scale Id="Ribbon.Documents.CustomGroup.LargeSmall" Sequence="230" GroupId="Ribbon.Documents.CustomGroup" Size="LargeSmall" />
</CommandUIDefinition>
<CommandUIDefinition Location="Ribbon.Documents.Groups._children">
<Group Id="Ribbon.Documents.CustomGroup" Sequence="10" Title="Custom Group" Template="Ribbon.Templates.Flexible2" Image32by32Popup="/_layouts/images/RibbonCustomization/images32x32.png"
Image32by32PopupTop="-128" Image32by32PopupLeft="-192">
<Controls Id="Ribbon.Documents.CustomGroup.Controls">
<Button
Id="Ribbon.Documents.CustomGroup.Notify"
Command="CustomGroup.Command.Notify"
Sequence="15" Image16by16="/_layouts/images/NoteBoard_16x16.png" Image32by32="/_layouts/images/NoteBoard_32x32.png"
Description="Notification hello message"
LabelText="Notify"
TemplateAlias="o1" />
</Controls>
</Group>
</CommandUIDefinition>
</CommandUIDefinitions>
<CommandUIHandlers>
<CommandUIHandler Command="CustomGroup.Command.Notify" CommandAction="javascript: SP.UI.Notify.addNotification('Hello from my custom group');  " />
</CommandUIHandlers>
</CommandUIExtension>
</CustomAction>


In this sample you should pay attention to the following:

  1. Three different CommandUIDefinition xml nodes should be created: for deploying MaxSize, Scale and Group nodes; MaxSize and Scale nodes should reference to the group which is currently being declared (using GroupId attribute); the Size attributes should be based on the group template. If no MaxSize and Scale declarations for new group is created, on incorrect values of Size attributes are specified, the group won’t be visible or no controls should be shown in it;

  2. The Location attributes of CommandUIDefinition xml elements should be constructed in the following way: [ExistingTabID].Scaling._children – for MaxSize and Scale nodes; [ExistingTabID].Groups._children – for Group node;

  3. All controls for this group can be declared directly in the Controls node inside the group declaration xml.


III. Adding custom tab to ribbon:

Here is the example of declaring custom ribbon tab:

<CustomAction Id="Ribbon.CustomTab" Location="CommandUI.Ribbon" RegistrationId="101" RegistrationType="List">
<CommandUIExtension>
<CommandUIDefinitions>
<CommandUIDefinition Location="Ribbon.Tabs._children">
<Tab Description="Custom Tab" Id="Ribbon.CustomTabExample" Sequence="1000" Title="Custom Tab">
<Scaling
Id="Ribbon.CustomTabExample.Scaling">
<MaxSize
Id="Ribbon.CustomTabExample.MaxSize"
GroupId="Ribbon.CustomTabExample.CustomGroupExample"
Size="OneLargeTwoMedium"/>
<Scale
Id="Ribbon.CustomTabExample.Scaling.CustomTabScaling"
GroupId="Ribbon.CustomTabExample.CustomGroupExample"
Size="OneLargeTwoMedium" />
</Scaling>

<Groups Id="Ribbon.CustomTabExample.Groups">
<Group
Id="Ribbon.CustomTabExample.CustomGroupExample"
Description="This is a custom group!"
Title="Custom Group"
Sequence="52"
Template="Ribbon.Templates.CustomTemplateExample">
<Controls Id="Ribbon.CustomTabExample.CustomGroupExample.Controls">
<Button
Id="Ribbon.CustomTabExample.CustomGroupExample.HelloWorld"
Command="CustomTabExample.HelloWorldCommand"
Sequence="15"
Image32by32="/_layouts/images/DWSHOME.GIF"
Description="Says hello to the World!"
LabelText="Hello, World!"
Image16by16="/_layouts/images/next.png"
TemplateAlias="cust1"/>
<Button
Id="Ribbon.CustomTabExample.CustomGroupExample.GoodbyeWorld"
Command="CustomTabExample.GoodbyeWorldCommand"
Sequence="17"
Description="Says good-bye to the World!"
LabelText="Good-bye, World!"
Image32by32="/_layouts/images/DWSHOME.GIF"
Image16by16="/_layouts/images/next.png"
TemplateAlias="cust2"/>
<Button
Id="Ribbon.CustomTabExample.CustomGroupExample.LoveWorld"
Command="CustomTabExample.LoveWorldCommand"
Sequence="19"
Description="Says I love the World!"
LabelText="I love you, World!"
Image32by32="/_layouts/images/DWSHOME.GIF"
Image16by16="/_layouts/images/next.png"
TemplateAlias="cust3"/>
</Controls>
</Group>
</Groups>
</Tab>
</CommandUIDefinition>
<CommandUIDefinition Location="Ribbon.Templates._children">
<GroupTemplate Id="Ribbon.Templates.CustomTemplateExample">
<Layout
Title="OneLargeTwoMedium"
LayoutTitle="OneLargeTwoMedium">
<Section Alignment="Top" Type="OneRow">
<Row>
<ControlRef DisplayMode="Large" TemplateAlias="cust1" />
</Row>
</Section>
<Section Alignment="Top" Type="TwoRow">
<Row>
<ControlRef DisplayMode="Medium" TemplateAlias="cust2" />
</Row>
<Row>
<ControlRef DisplayMode="Medium" TemplateAlias="cust3" />
</Row>
</Section>
</Layout>
</GroupTemplate>
</CommandUIDefinition>
</CommandUIDefinitions>

<CommandUIHandlers>
<CommandUIHandler
Command="CustomTabExample.HelloWorldCommand"
CommandAction="javascript:alert('Hello, world!');" />
<CommandUIHandler
Command="CustomTabExample.GoodbyeWorldCommand"
CommandAction="javascript:alert('Good-bye, world!');" />
<CommandUIHandler
Command="CustomTabExample.LoveWorldCommand"
CommandAction="javascript:alert('I love you, world!');" />
</CommandUIHandlers>
</CommandUIExtension>

</CustomAction>

VI. Handling action using JavaScript

There are two different ways that we define the custom action performed by the controls we placed under the custom tab/group/control.

1. Using "ScriptSrc": Custom action tag contains this attribute to refer the js file which can contain the javascript/Jquery code. The simple example how to define this attribue is as follows:

<CustomAction Id="Ribbon.Library.Share.Sample.Script"

Location="ScriptLink" ScriptSrc="/_layouts/SCRIPT/Ribbon.js"
/>

2. Using "ScriptBlock":Custom action tag contains this attribute to refer the code without defining any js file. The simple example how to define this attribue is as follows:

<CustomAction Id="Ribbon.Library.Share.Sample.Script"

Location="ScriptLink" ScriptBlock="function viewDialog() {
var options = {
url: 'http://mohitvash.wordpress1.com/',
width: 800,
height: 600
};
SP.UI.ModalDialog.showModalDialog(options);
}"
/>

Also we can define the javascrip to the server side for more details please refer to: http://msdn.microsoft.com/en-us/library/gg552606.aspx

Comments

  1. hi Mohitvash , i used the following code






































    but the group didn't show up..
    can you help me out

    ReplyDelete
  2. Hi Surendra,

    You must check for the attribute RegistrationId=”101″, As this defines where the new group will be displayed. The 101 value is for the document library list so make sure that you are adding it at the right please. You can refer the list of Id here http://sharepoint-snippets.com/list-template-id-for-sharepoint-lists/.

    Regards
    Mohit

    ReplyDelete
  3. Hi, I'm able to add a button on the ribbon, however I just can't add in textBox on the ribbon.

    Any tricks behind?

    ReplyDelete
  4. Hi Rico,

    To add text box you must use following code:

    TextBox Id="MyTextBox.RibbonControls.Tab.TextBox"
    Command="MyTextBox.RibbonControls.TextBoxCommand"
    QueryCommand="MyTextBox.RibbonControls.QueryTextBoxCommand"
    TemplateAlias="section2"
    Width="100"
    MaxLength="20"
    Sequence="10"
    ToolTipImage32by32="/_layouts/Images/MyTextBox.RibbonControls/MyTextBox.RibbonControls.png"
    ToolTipImage32by32Left="0"
    ToolTipImage32by32Top="-48"
    ToolTipImage32by32Class="TextBoxTTClass"
    ToolTipDescription="A box where you can enter text"
    ToolTipHelpKeyWord="RibbonControls"
    ToolTipShortcutKey="J"
    ToolTipTitle="This is a textbox"
    ShowAsLabel="false"
    ImeEnabled="true"
    />

    and at code behind in javascript you must add:

    handleCommand: function (commandId, properties, sequence) {
    switch (commandId) {
    case 'MyTextBox.RibbonControls.QueryTextBoxCommand':
    if(null == properties['Value']) properties['Value'] = 'Default value';
    return;
    }
    }
    handleCommand: function (commandId, properties, sequence) {
    switch (commandId) {
    case 'MyTextBox.RibbonControls.TextBoxCommand':
    properties['Value'] = properties['Value'].toUpperCase();
    return;
    }
    }

    Hope above code will helpful for you. Happy Sharepointing!!

    ReplyDelete
  5. Thank for your fast reply, any sample on how to integrate the javascript code behind?

    ReplyDelete

Post a Comment

Popular posts from this blog

Hide Ribbon on SharePoint 2013 using CSS

Get Comment Count in SharePoint

Configure external site as content sources in sharepoint search