Archive

Posts Tagged ‘ribbon’

SharePoint 2010: Fixing the MSDN Contextual Tab Web Part Walkthrough

July 31st, 2010 Buta 2 comments

I haven’t had much opportunity to work with SharePoint 2010 in the past few months. However, I did get to try out the MSDN walkthrough for creating a custom web part with contextual ribbon tab recently. You can find the article here: http://msdn.microsoft.com/en-us/library/ff407578.aspx

In a nutshell, what’s supposed to happen is when you click on the web part, there will be a custom tab that appears in the Ribbon. It all works great for the first instance of the custom web part you place onto a page, but if you try adding a second instance of the web part, your page blows up!

You’ll get the following error:
Item has already been added. Key in dictionary: ‘Ribbon.CustomContextualTabGroup’ Key being added: ‘Ribbon.CustomContextualTabGroup’

:-/ … looks like there wasn’t much QA done for the walkthrough. Anyways, to make a short story shorter… I posted a question on the TechNet forums and Dallas Tester from MS did get back to me with a bunch of suggestions.

Here are the changes you can make to allow for multiple instances of the custom web part to appear on the page without everything blowing up.

Make the following modifications to the ContextualTabWebPart class.

Add the global ‘_added’ bool and OnInit event handler:

static bool _added = false;

protected override void OnInit(EventArgs e)
{
 base.OnInit(e);
 _added = false;
}

Since we no longer have to get the unique component ID in the delay script, I changed DelayScript into a private string:

private string delayScript = @"
 function _addCustomPageComponent()
 {
  for (var i = 0; i < g_customWebPartIds.length; i++)
  {
    SP.Ribbon.PageManager.get_instance().addPageComponent(new ContextualTabWebPart.CustomPageComponent(g_customWebPartIds[i]));
  }
 }

 function _registerCustomPageComponent()
 {
  SP.SOD.registerSod(""CustomContextualTabPageComponent.js"", ""/_layouts/CustomContextualTabPageComponent.js"");
  var isDefined = ""undefined"";
  try
  {
   isDefined = typeof(ContextualTabWebPart.CustomPageComponent);
  }
  catch(e)
  {
  }
  EnsureScript(""CustomContextualTabPageComponent.js"",isDefined, _addCustomPageComponent);
 }
 SP.SOD.executeOrDelayUntilScriptLoaded(_registerCustomPageComponent, ""sp.ribbon.js"");";

Modify the OnPreRender event handler:

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

 ClientScriptManager csm = this.Page.ClientScript;
 string componentId = SPRibbon.GetWebPartPageComponentId(this); // the unique component id 

 // if this is the first instance of the custom web part,
 //we need to add the contextual tab to the ribbon
 if (!_added)
 {
  this.AddContextualTab();
  _added = true;
 }

 // we need to create an array which will store the IDs of all instances of our custom web part
 csm.RegisterClientScriptBlock(
  this.GetType(), "DeclareCustomWebPartArray", "var g_customWebPartIds = new Array();", true);

 // add this webpart's ID to our array
 csm.RegisterClientScriptBlock(
  this.GetType(), "AddCustomWebPartId" + componentId, "g_customWebPartIds.push('" + componentId + "');", true);

 csm.RegisterClientScriptBlock(this.GetType(), "ContextualTabWebPart", this.delayScript, true);
}

If you want to verify that the correct web part is trigger the Ribbon commands, you can modify the ‘handleCommand‘ method in ‘CustomContextualTabPageComponent.js

handleCommand: function ContextualTabWebPart_CustomPageComponent$handleCommand(commandId, properties, sequence) {
 if (commandId === 'CustomContextualTab.HelloWorldCommand') {
  alert(this._webPartPageComponentId + ' says: Hello, world!');
 }
 if (commandId === 'CustomContextualTab.GoodbyeWorldCommand') {
  alert(this._webPartPageComponentId + ' says: Good-bye, world!');
 }
}

Here’s a ZIP file of the entire solution in case you’re too lazy to make the modifications yourself. :-)

Yaroslav on Customizing the SharePoint 2010 Ribbon

December 29th, 2009 Buta Comments

My buddy Yaroslav’s been blogging away about customizing the SharePoint 2010 ribbon, like the mad scientist that he is, over the past few weeks…

Here’s what he’s got so far:

Go check it out!

Categories: Development, SharePoint

SPC09: SharePoint 2010 Ribbon and Form Dialogs

October 20th, 2009 Buta Comments
SharePoint 2010 Ribbon

SharePoint 2010 Ribbon

A busy first day at the SharePoint Conference so I’ll start off with a quickie.

As most of you know already, SharePoint 2010 will use the ribbon interface for editing. I personally like the ribbon from an UI perspective compared with the old editing UI for SharePoint 2007. Some might argue that it’s a bit cluttered and the context sensitive editing may be confusing to new users. I think it’s something that users can grasp in short fashion especially if they use Office 2007 or 2010 as well.

Something that’s new to me in 2010 are the AJAX form dialogs. Pretty much any new item creation is now done in a modal dialog now instead of taking the user to a different form page in 2007. This is great as it keeps everything in context for the user.

An added benefit of the ribbon and form dialogs is that in most cases we no longer have to design for or make design decisions regarding these edit mode elements anymore. They are pretty much separate from the rest of the page from a design perspective.

UPDATE:
I’ll be putting up another post regarding the dialog creation API which is exposed as a JavaScript library in a later post.

The ribbon is extensible as well, you’re able to create new button elements, replace existing elements with customized functionality or remove an element all together.