Posted on:
Categories: SharePoint
Description:

The Problem

Something that has come up a lot in the past with clients implementing SharePoint 2010 in tabbed content - specifically, tabbed web part zones. But those of you who have researched this before will know that this functionality is simply not available in SharePoint 2010 Out-Of-The-Box. I thought I would take a minute and show how we typically implement tabs for our clients.

When I first starting looking at how to create tabs in SharePoint, I came across this blog post by Matthew Koon. It got me some of the way there, but I wanted a more generic method of creating web part tabs...which is when I found this blog post by Kyle Schaeffer. I took the javascript and html that he posted, made slight modifications, and then wrapped it up in an empty re-usable SharePoint Page Layout. Using this method, users can create a page using this page layout, add simply add web parts in edit mode just like they do for any other web part zone. Only when they hit save, we use the JQuery UI library to "tabify" the web parts into nice looking tabs that can be easily customized to fit the clients desired branding using CSS.

The Implementation

Start with a new or existing SharePoint 2010 project, and add a new Module called PageLayoutModule. Next, add a new Text File called TabbedPageLayout.txt, once once it's added to the project, rename the file to TabbedPageLayout.aspx, and move it into the PageLayoutModule.

Now since we've just created a blank page layout, we need to modify the PageLayoutModule's Elements.xml to reflect this. So open Elements.xml, and inside the Elements tag, replace the existing Module with the following (you can delete the Sample.txt file from the module if you'd like):

<Module Name="PageLayoutModule" Url="_catalogs/masterpage">
 <File Path="PageLayoutModule\TabbedPageLayout.aspx" Url="TabbedPageLayout.aspx" 
 Type="GhostableInLibrary" IgnoreIfAlreadyExists="TRUE" >
   <Property Name="Title" Value="Tabbed Page Layout" />
   <Property Name="MasterPageDescription" Value="Tabbed Page Layout"/>
 </File>
</Module>

Now since TabbedPageLayout.aspx is still a blank file, we need to insert the required SharePoint registrations/etc. So just paste the following:

<%@ Page Language="C#" 
 Inherits="Microsoft.SharePoint.Publishing.PublishingLayoutPage,
 Microsoft.SharePoint.Publishing,Version=14.0.0.0,
 Culture=neutral,PublicKeyToken=71e9bce111e9429c"
    meta:progid="SharePoint.WebPartPage.Document" 
 meta:webpartpageexpansion="full" %>
<%@ Register Tagprefix="SharePointWebControls" 
Namespace="Microsoft.SharePoint.WebControls" 
 Assembly="Microsoft.SharePoint, Version=14.0.0.0, 
 Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="WebPartPages" 
Namespace="Microsoft.SharePoint.WebPartPages" 
 Assembly="Microsoft.SharePoint, Version=14.0.0.0, 
 Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="PublishingWebControls" 
Namespace="Microsoft.SharePoint.Publishing.WebControls" 
 Assembly="Microsoft.SharePoint.Publishing, Version=14.0.0.0, 
 Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="PublishingNavigation" 
Namespace="Microsoft.SharePoint.Publishing.Navigation" 
 Assembly="Microsoft.SharePoint.Publishing, Version=14.0.0.0, 
 Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
 
<asp:Content ContentPlaceholderID="PlaceHolderAdditionalPageHead" 
 runat="server">
 
 <script 
 src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js">
 </script>
 <script 
 src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js">
 </script>
 
 <script type="text/javascript">
 
  //PASTE TAB SCRIPTS HERE
 
 </script>
 
</asp:Content>
<asp:Content ContentPlaceholderID="PlaceHolderPageTitle" 
runat="server">
 <SharePointWebControls:FieldValue id="PageTitle" FieldName="Title" 
 runat="server"/>
</asp:Content>
<asp:Content ContentPlaceholderID="PlaceHolderPageTitleInTitleArea" 
runat="server">
 <SharePointWebControls:FieldValue FieldName="Title" 
 runat="server"/>
</asp:Content>
<asp:Content ContentPlaceholderID="PlaceHolderMain" runat="server">
 <div class="my-web-part-tabs" style="display:none;">
  <WebPartPages:WebPartZone runat="server" 
  Title="Tabs Web Part Zone" ID="CenterColumn"  />
 </div>
</asp:Content>

And now we have an empty SharePoint 2010 Page Layout, with 1 web part zone. As you may have guessed by web part name, this is the web part zone that will be transformed into tabs. The next step is to add the supporting scripts that will transform the web part zone into tabs. You will notice that in the code you copied and pasted above, JQuery is already referenced and there is a blank script block. We will be adding our scripts within that script block. Note if your existing branding already references JQuery and/or JQuery UI, you don't have to reference them above.

(function ($) {
 $.fn.wpTabify = function () {
  var toReturn = false;
  if ($('.ms-WPAddButton').size() == 0) {
   toReturn = this.each(function (i) {
    var idName = $(this).attr('id');
    var tabList = $('<ul class="wpt-ui-tabs-nav"/>');
    var panels = $('<div class="wpt-ui-tabs-wrapper"/>');

    $(this).find('.s4-wpTopTable,td[id^="MSOZoneCell_"] > table').
    each(function (j) {
     $(tabList).append('<li><a href="#ui-tab-panel' + 
      idName + i + j + '"><span>' + 
      $(this).find('h3.ms-WPTitle').text() + 
      '</span></a></li>');
     var thisPanel = $('<div id="ui-tab-panel' + idName + 
      i + j + '" class="wpt-ui-tabs-panel"/>');
     var panelContents = $(this).detach();
     $(thisPanel).append($(panelContents).
      find('.ms-wpContentDivSpace')​);
     $(panels).append(thisPanel);
    });
    if ($(tabList).find('li').size() > 0) {
     $(this).prepend(panels);
     $(this).prepend(tabList);
     $(this).tabs();
    }
   });
  }

  $(this).show();
  return toReturn;
 };

})(jQuery);

function TabifyFnWrapper() {
 $('.my-web-part-tabs').wpTabify();
}
_spBodyOnLoadFunctionNames.push("TabifyFnWrapper");

Now deploy the solution, and create a new page on the site you deployed to. Make sure you change the page layout to our newly created page layout.

Now in edit mode, add some web parts which you would like to appear in each tab. For example, I added two list view web parts:

And then Save & Close. You should now see something similar to this:

First thing you will likely notice is that, in fact, this looks nothing like tabs. But all that is missing is some CSS to transform the web part titles into Tabs, and hide/show the tab contents as appropriate. Typically you will want to write your own styles to accomodate your clients desired branding, but as an example, we will use the styles that Kyle Schaeffer provided in the blog post I mentioned earlier (I've made some tweaks as I was having some issues; your mileage may vary):

.ui-tabs-nav {
 margin: 0;
 padding: 0;
}
 .ui-tabs-nav li {
 list-style: none;
 margin: 0 1px 0 0;
 padding: 0;
 float: left;
}
.ui-tabs-nav a {
 position: relative;
 top: 1px;
 display: block;
 padding: 10px 8px;
 border: solid #e1e0dc;
 border-width: 1px 1px 0 1px;
 background: #d6d6d6;
 color: #999;
 text-decoration: none;
 -webkit-border-top-left-radius: 5px;
 -webkit-border-top-right-radius: 5px;
 -moz-border-radius-topleft: 5px;
 -moz-border-radius-topright: 5px;
 border-top-left-radius: 5px;
 border-top-right-radius: 5px;
}
.ui-tabs-nav li.ui-tabs-selected a {
 color: #c70d37;
 background: #fff;
}
.ui-tabs-panel {
 clear: both;
 padding: 20px;
 background: #fff;
 border: 1px solid #e1e0dc;
}
.ui-tabs-hide {
 display: none;
}

Now re-deploy and take a look at your page...it now looks like tabs! (fyi - sometimes I find that I have to manually upload the updated page layout) And that's all that is involved with creating SharePoint 2010 Page Layouts with Tabbed Web Parts from scratch. Feel free to leave comments on this page if you have any issues/questions/comments. Cheers!