Monday, June 27, 2011

Ribbon customization - Part 9

We have seen in previous posts (Part 1 to Part 8)about adding tabs, groups and controls. Now we are going to add tab again. You might ask, okay so what is new to this? Because we have already done this. Well this is a new type of tab and called contextual tab. Tab comes alive only when specific actions being performed.

To give you an example, when you select any picture in MS Word, then picture tab comes alive. Normally that tab is not visible until you select any picture in the word file. Taking example in SharePoint, if you edit the page, then only several new tabs becomes available. When you select list item, then only view item and edit item buttons become enable.

So we are also going to add contextual tab which becomes visible when a specific web part is selected. The advantage of creating contextual tab as a web part is because we get a flexibility to add tab on a specific page. If your requirement is not to have that tab in the entire site level and at a specific level, then we can have tab created as a web part and then let our web part performs a task of registering the XML to the page and render the tab when web part is selected.

Now when we develop a contextual tab and take web part as an approach, we need to register the page component and add it to the page manager so that page manager allows us to render a tab. Page component is ECMA script that interacts with the ribbon. It allows us to write commands of ribbon and actions that takes place when that command triggers in the page component.

To understand more about page component, I would recommend reading this article from MSDN. I have taken this link only for the reference for building this sample for you.

Coming back to our example, let’s add blank SharePoint project by opening visual studio 2010.

While creating project, select deploy as a farm solution option. Add the Microsoft.Web.CommandUI reference. It must be under 14/ISAPI directory.

We will define two strings, one for the Tab and Group and the other for custom group template.

Then we will use one string variable that will register our page component which is actually an ECMA script.

Then we will use one function which will register our tab and template that we have defined in XML.

Our class would be implementing IWebPartPageComponentProvider interface and hence we will implement one more method which is WebPartContextualInfo. This interface will tell SharePoint which tab to visible when this web part is selected.

Then we have to create page component which will register the script part.

Well this is bit complex at the initial phase, but when practiced, then it becomes easy. This is the script which helps us to do further customizations as well. For example, if you want to have a drop down as controls in the group tab and if you want to dynamically populate the drop down, then this is the file which you need to modify.

I have written down the entire project details below. Your project layout should look something like this



And below is the entire code for the web part and following is the script for the js file. I have taken this example from this page, so I recommend you go through that link to understand it in more details. I have given this example to make things clear that what all parts we need to change to suit it to our need.



namespace SharePoint2010Practice.UtilitiesTabWebPart

{
[ToolboxItemAttribute(false)]
public class UtilitiesTabWebPart : WebPart, IWebPartPageComponentProvider
{
private string contextualTab = @"
<ContextualGroup Color=""Yellow""
Command=""CustomContextualTab.EnableContextualGroup""
Id=""Ribbon.CustomContextualTabGroup""
Title=""SPKings Contextual Tab Group""
Sequence=""502""
ContextualGroupId=""CustomContextualTabGroup"">
<Tab
Id=""Ribbon.CustomTabExample""
Title=""Utilities""
Description=""Various utilities options available!""
Command=""CustomContextualTab.EnableCustomTab""
Sequence=""501"">
<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""
Command=""CustomContextualTab.EnableCustomGroup""
Sequence=""52""
Template=""Ribbon.Templates.CustomTemplateExample"">
<Controls
Id=""Ribbon.CustomTabExample.CustomGroupExample.Controls"">
<Button
Id=""SPKings.Ribbon.CustomTab.SearchGroup.SearchBingButton""
Command=""CustomContextualTab.SearchBing""
Sequence=""15""
Description=""Bing Search Engine""
Image16by16=""/_layouts/images/CustomImages/Bing-logo.jpg""
Image32by32=""/_layouts/images/CustomImages/bing.png""
LabelText=""Bing""
TemplateAlias=""cust1""/>
<Button
Id=""SPKings.Ribbon.CustomTab.SearchGroup.SearchGoogleButton""
Command=""CustomContextualTab.SearchGoogle""
Sequence=""17""
Image16by16=""/_layouts/images/CustomImages/google-logo.png""
Image32by32=""/_layouts/images/CustomImages/google_logo.jpg""
Description=""Google Search Engine""
LabelText=""Google""
TemplateAlias=""cust2""/>
</Controls>
</Group>
</Groups>
</Tab>
</ContextualGroup>";

private string contextualTabTemplate = @"
<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=""OneRow"">
<Row>
<ControlRef DisplayMode=""Large"" TemplateAlias=""cust2"" />
</Row>
</Section>
</Layout>
</GroupTemplate>";



public string DelayScript
{
get
{
string webPartPageComponentId = SPRibbon.GetWebPartPageComponentId(this);
return @"
<script type=""text/javascript"">
//<![CDATA[

function _addCustomPageComponent()
{
var _customPageComponent = new UtilitiesTabWebPart.CustomPageComponent('" + webPartPageComponentId + @"');
SP.Ribbon.PageManager.get_instance().addPageComponent(_customPageComponent);
}

function _registerCustomPageComponent()
{
SP.SOD.registerSod(""UtilitiesTabPageComponent.js"", ""\/_layouts\/UtilitiesTabPageComponent.js"");
SP.SOD.executeFunc(""UtilitiesTabPageComponent.js"", ""UtilitiesTabWebPart.CustomPageComponent"", _addCustomPageComponent);
}
SP.SOD.executeOrDelayUntilScriptLoaded(_registerCustomPageComponent, ""sp.ribbon.js"");
//]]>
</script>";
}
}

private void AddContextualTab()
{

// Get the current instance of the ribbon on the page.
Microsoft.Web.CommandUI.Ribbon ribbon = SPRibbon.GetCurrent(this.Page);

// Prepare an XmlDocument object used to load the ribbon extensions.
XmlDocument ribbonExtensions = new XmlDocument();

// Load the contextual tab XML and register the ribbon extension.
ribbonExtensions.LoadXml(this.contextualTab);
ribbon.RegisterDataExtension(ribbonExtensions.FirstChild, "Ribbon.ContextualTabs._children");

// Load the custom templates and register the ribbon extension.
ribbonExtensions.LoadXml(this.contextualTabTemplate);
ribbon.RegisterDataExtension(ribbonExtensions.FirstChild, "Ribbon.Templates._children");



}



protected override void CreateChildControls()
{

}


public WebPartContextualInfo WebPartContextualInfo
{
get {

WebPartContextualInfo info = new WebPartContextualInfo();
WebPartRibbonContextualGroup contextualGroup = new WebPartRibbonContextualGroup();
WebPartRibbonTab ribbonTab = new WebPartRibbonTab();

// Create the contextual group object and initialize its values.
contextualGroup.Id = "Ribbon.CustomContextualTabGroup";
contextualGroup.Command = "CustomContextualTab.EnableContextualGroup";
contextualGroup.VisibilityContext = "CustomContextualTab.CustomVisibilityContext";

// Create the tab object and initialize its values.
ribbonTab.Id = "Ribbon.CustomTabExample";
ribbonTab.VisibilityContext = "CustomContextualTab.CustomVisibilityContext";

// Add the contextual group and tab to the WebPartContextualInfo.
info.ContextualGroups.Add(contextualGroup);
info.Tabs.Add(ribbonTab);
info.PageComponentId = SPRibbon.GetWebPartPageComponentId(this);

return info;

}
}

protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);

this.AddContextualTab();

ClientScriptManager clientScript = this.Page.ClientScript;
clientScript.RegisterClientScriptBlock(this.GetType(), "UtilitiesTabWebPart", this.DelayScript);

}


}
}




and js file script



Type.registerNamespace('UtilitiesTabWebPart');

var _webPartPageComponentId;
SharePoint2010Practice.UtilitiesTabWebPart.CustomPageComponent = function SharePoint2010Practice.UtilitiesTabWebPart_CustomPageComponent(webPartPcId) {
this._webPartPageComponentId = webPartPcId;
SharePoint2010Practice.UtilitiesTabWebPart.CustomPageComponent.initializeBase(this);
}
UtilitiesTabWebPart.CustomPageComponent.prototype = {

init: function UtilitiesTabWebPart_CustomPageComponent$init() { },

getFocusedCommands: function UtilitiesTabWebPart_CustomPageComponent$getFocusedCommands() {
return ['CustomContextualTab.EnableCustomTab', 'CustomContextualTab.EnableCustomGroup',
'CustomContextualTab.SearchBing',
'CustomContextualTab.SearchGoogle'];
},

getGlobalCommands: function UtilitiesTabWebPart_CustomPageComponent$getGlobalCommands() {
return [];
},

isFocusable: function UtilitiesTabWebPart_CustomPageComponent$isFocusable() {
return true;
},

canHandleCommand: function UtilitiesTabWebPart_CustomPageComponent$canHandleCommand(commandId) {
// Contextual Tab commands
if ((commandId === 'CustomContextualTab.EnableCustomTab') ||
(commandId === 'CustomContextualTab.EnableCustomGroup') ||
(commandId === 'CustomContextualTab.SearchBing') ||
(commandId === 'CustomContextualTab.SearchGoogle')) {
return true;
}
},

handleCommand: function UtilitiesTabWebPart_CustomPageComponent$handleCommand(commandId, properties, sequence) {

if (commandId === 'CustomContextualTab.SearchBing') {
alert('Bing');
}
if (commandId === 'CustomContextualTab.SearchGoogle') {
alert('Google');
}
},

getId: function UtilitiesTabWebPart_CustomPageComponent$getId() {
return this._webPartPageComponentId;
}
}


UtilitiesTabWebPart.CustomPageComponent.registerClass('UtilitiesTabWebPart.CustomPageComponent', CUI.Page.PageComponent);
SP.SOD.notifyScriptLoadedAndExecuteWaitingJobs("UtilitiesTabPageComponent.js");




At the end, build the project and deploy. Open web part gallery, add this web part. Open a page where you would like to see this tab, add this new web part and then select that web part and see how the new tab becomes visible.



More to come on ribbon series. Stay tuned.

2 comments:

Anonymous said...

very detailed explanation. very helpful. Thanks so much for your time.

Anonymous said...

very useful series.

Thanks




Share your SharePoint Experiences with us...
As good as the SharePointKings is, we want to make it even better. One of our most valuable sources of input for our Blog Posts comes from ever enthusiastic Visitors/Readers. We welcome every Visitor/Reader to contribute their experiences with SharePoint. It may be in the form of a code stub, snippet, any tips and trick or any crazy thing you have tried with SharePoint.
Send your Articles to sharepointkings@gmail.com with your Profile Summary. We will Post them. The idea is to act as a bridge between you Readers!!!

If anyone would like to have their advertisement posted on this blog, please send us the requirement details to sharepointkings@gmail.com