WP Tabify: Transform a SharePoint Web Part Zone into Tabs

I do quite a bit of design and implementation on the SharePoint platform. Today, I created a very handy little script that I think might be something worth sharing. I don’t often post anything so specific on my blog, but I found this to be extremely useful, and I hope you do too.

What is it?

This all started with a great idea from the mind of Matthew Koon. If you’re not familiar with SharePoint, one thing you can do in the platform is place web parts on a page, which are akin to sidebar widgets in WordPress or other CMS platforms. Web parts have a lot of nifty drag-and-drop functionality, but the appearance of them is pretty much limited to what you can do with a bit of CSS and maybe some background images. The script that I created transforms a particular “web part zone,” which contains individual web parts, into a jQuery UI tab control. For each web part in the zone, you see an interactive “tab” instead of a boring static box. The contents of each tab is the contents of the web part, itself.

What does it do?

When you’re editing a page, you’ll see this:

When you publish the page, you’ll see this:

1. Attach Required Scripts

You’ll need both jQuery 1.4.2 and jQuery UI 1.8.5 (or later).

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/jquery-ui.min.js"></script>

2. Attach the Script

Paste this into an attached JavaScript file:

(function($){
  $.fn.wpTabify = function(){
    if($('.ms-WPAddButton').size() == 0){
      return this.each(function(i){
        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' + i + j + '">' + $(this).find('h3.ms-WPTitle').text() + '</a></li>');
          var thisPanel = $('<div id="ui-tab-panel' + i + j + '" class="wpt-ui-tabs-panel"/>');
          var panelContents = $(this).detach();
          $(thisPanel).append($(panelContents).find('.ms-WPBody').html());
          $(panels).append(thisPanel);
        });
        if($(tabList).find('li').size() > 0){
          $(this).prepend(panels);
          $(this).prepend(tabList);
          $(this).tabs();
        }
      });
    }
    else{
      return false;
    }
  };
})(jQuery);

3. Wrap Your Web Part Zone

In your custom page layout, place a <div/> tag around a web part zone, and give it a class name or ID of your choosing.

<div class="my-web-part-tabs">
  <WebPartPages:WebPartZone id="zone1" runat="server" title="Tabs Zone"><ZoneTemplate></ZoneTemplate></WebPartPages:WebPartZone>
</div>

4. Run the Script

Now that you’ve attached the script, run it using a jQuery selector that matches the <div> you created in step three (above). This code also goes in an attached JavaScript file.

$(document).ready(function(){
  $('.my-web-part-tabs').wpTabify();
});

5. Add Some Style (Optional)

You may choose to add a bit of style to your newly tabified web parts (this is not specific to this plug-in, these are just some generic jQuery tabs styles):

.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;
}

Compatibility

This has been tested in SharePoint 2007 and SharePoint 2010. Make sure to set your web part chrome to anything other than None, as my script relies on the web part title to display the tab title. Please let me know if you have any issues, as I will continue to update the script as needed. Good luck, and happy tabbing!

41 comments

  1. David Wallach says:

    I’m not getting this to work. I’m using Data View Web Parts. The tabs do not align horizontally and I don’t see the contents of the Web Parts.

    Thank in advance for any help

    • Kyle says:

      Hi, David. Are you using SharePoint 2007 or 2010? I may have to test and update the script for the 2007 platform, as it remains untested.

  2. Joe says:

    I am not getting this to work. Using MOSS 2007. I have added the JS calls to jquery 1.4.2 and jquery ui. I added in the css, the js to a js file being called already and the snipped of js after the web part zone and divs. I then added in 2 CEWP and they show up just normal. Thanks for any help you can give me.

  3. Joe says:

    I should have added that I am getting a JS error on the page and not sure what is causing it. Thanks, Joe

  4. Kyle says:

    Updated the script to work in both SharePoint 2010 as well as 2007. Added a new selector to the script (td[id^="MSOZoneCell_"] > table) that selects web parts on the 2007 platform. Please let me know if you have any issues!

  5. Brett says:

    Wow, love this look but the programming is way over my head as I’m not understanding it all.

    Guess I’m more of a step by step with pictures kind of guy…LOL

  6. Christophe says:

    Kyle,

    I found your article today, cross-posted on EndUserSharePoint.com
    This technique has actually been around for a while. I published the first “Easy Tabs” in May 2009. You can grab the current version (5) at this address:
    http://sp2010.pathtosharepoint.com/SharePoint-User-Toolkit/Pages/Easy-Tabs-v5.aspx
    Note that my version doesn’t require jQuery/jQuery UI.

  7. Gill says:

    Hi kyle ,
    thanks for this post is really helpful. I have just started playing with Sharepoint 2010. This was good technique hope to have lot more .

  8. Neel says:

    Kyle, Help me out, I am not able to tabify, can you let me know ? I am trying to tabify the web part in a page layout.. below i s what i have added to it

    $(document).ready(function(){
    $(‘.my-web-part-tabs’).wpTabify();
    });

    I have the css for the webpart lay out
    #container{ margin:0 auto;}
    #main{display:block; padding:10px 0;}
    #column_left{width:600px; margin-right:3px; float:left;}
    #column_right{width:280px; margin-right:3px; float:left;}
    #column_right_adsense{width:280px; float:left;}
    div.spacer{clear:both;}

    then i have the below code for web parts

    <WebPartPages:WebPartZone runat="server" AllowPersonalization="false" ID="ContentLeftZone" FrameType="TitleBarOnly"
    Title="” Orientation=”Vertical”>

    <WebPartPages:WebPartZone runat="server" AllowPersonalization="false" ID="WebpartCenterZone" FrameType="TitleBarOnly"
    Title="” Orientation=”Vertical”>

    <WebPartPages:WebPartZone runat="server" AllowPersonalization="false" ID="WebpartRightZone" FrameType="TitleBarOnly"
    Title="” Orientation=”Vertical”>

    Another question..
    I am trying to create a pagelayout with 3 columns , each with a web part, for some reason, when i type into CEQP, then the webpart expands horizontally below the others, is there a way to stop the overflow. I have fixed columns, css is above

    thank you
    Neel

  9. Kyle says:

    Hi, Neel. You need to surround your web part zone (where you want the tabs to appear) in a DIV tag. You can add a CSS class to the DIV tag (for example, class="neel-tabs"), and then use that class when you’re running my script.

    $(‘.neel-tabs‘).wpTabify();

  10. Neel says:

    Kyle,
    Thank you.. figured it out, I have 3 columns, when i added your script, it is pushing down the 2 columns.. is there a way to adjust the width (fixed when we add the tabs)
    thank you
    Neel

  11. Shaz says:

    Hi, this works very well with content editor web parts but any list web part I add doesn’t appear at all – has anyone successfully been able to view list web parts?

    • Rod says:

      I have it working with a list webpart by wrapping that in a page viewer webpart that displays the list. It works wonderfully except for in IE. It is limiting the height in IE and putting in a scroll bar. Any ideas on how to fix that in IE. This is SharePoint after all. email me rod at bergren .net

  12. Great Idea! We had this problem at my shop a couple days ago and ended up building a web part for it, but this is a great solution, and really leverages OOB SharePoint well. Thanks!

  13. Going to look into this, great idea and thanks for the share and all the work you put into this. Going to talk to my designer now about my WP site.

  14. Mallikarjun says:

    Hi Kyle
    I am u r fan, u r postings are amazing.
    I am a starter in sharepoint we are working in sharepoint 2010. please post one article about how to create the custome master page in sharepoint2010

  15. Sowmya Deenadayal says:

    Hi Kyle,

    great post!
    Now that i have the muti tabs in my webpart zone, i have few content editor webparts as tabs in my webpart zone. In each of the content editor webpart, i have few links which points to another page on the portal, there, in the another page, i have “Go back” button.
    I am expecting to get this “Go back” button point back to the exact tab in the zone, when it goes back to that page..
    Any thoughts?

    Thanks,
    Sowmya

  16. Mahesh says:

    Hi Kyle,

    This work very well. But it’s not working anonymous user account. Can you please help me for same …

  17. Hemant says:

    Hi Kyle,

    Great post. I implemented the same in my 2010 site. But I am having one issue. Following line doesnt append anything to the “thisPanel”
    $(thisPanel).append($(panelContents).find(‘.ms-WPBody’).html());
    So i update the line to
    $(thisPanel).append($(panelContents));

    It is working fine but now i am having another problem. When i select any record, ribbon doesnt show.

    Thank in advance for any help.

  18. padma says:

    Hi,

    I need to convert the webparts in home.aspx page into tabs, for that i am trying to add webpart zone into sharepoint 2010 home.aspx and it is not happening. Any idea?

  19. Matt says:

    Hello, I can’t seem to display a calendar web part in the tabbed zone. Other things, like Summary Links web parts, work. What might be the problem?

    Thanks!

    • Kyle says:

      Matt, this doesn’t work on some web parts, like data views, list views, and calendars. It’s due to the way that Microsoft chose to output the HTML for those web parts – they don’t have all the same classes and div elements that normal web parts have, so unfortunately there’s no reliable way to grab them and add them as a tabbed web part.

  20. Marissa says:

    We’re looking to use multiple colors for our tabs…any suggestions?

  21. […] jQuery UI tabs maries sharepoint webparts Like this:LikeBe the first to like this post. Uncategorized ← Previous Post […]

  22. JO says:

    Hi,
    Does this script work for custom web parts as well?
    As “Easy web part” doesnot add custom web parts as tabs

    • Kyle says:

      Hi, JO. Yes, this should work for custom web parts, depending on how they were built. This script relies on a CSS class called s4-wpTopTable. Most SharePoint 2010 web parts have it, some don’t, so it entirely depends on how you’ve set up your web part.

  23. CT says:

    Hi,

    I got a strange behavior in Firefox (working in IE and Chrome) although the tab is displayed nicely. The content in the tab is not responding when clicking on asp:TabPanel. Here are the snippet code

    [code]

    <asp:Label ID="lblBreakPt" runat="server" Visible="false" Text="”>

    [/code]

  24. John says:

    Will it work for SharePoint 2010 Calendars? I am planning to put around 5 calendars.

  25. Cindy Osbon says:

    Hi Kyle, I took your virtual Styling/Branding class last week and well on my way to implementing the things I learned. Related to that – for the Tabs – is it possible to have the initial view not display any of the tab contents – in other word when the page loads the user would just see the tabs then when a tab is selected it would display the web part it is connected to? If that is possible what code would need to be adjusted?

    Thanks
    C

  26. UXJester says:

    Hey Kyle,
    Love the plugin. I implemented it on a project I did last summer and I forgot to post an update. While your plugin works great for most content driven web parts, not all i.e. list and document library web parts, use the .ms-wpbody class. I updated this line .find(‘.ms-WPBody’).html()); to .find(‘.ms-wpContentDivSpace’).html());

    This update enables the tab roll up to display the content of web parts that don’t use the .ms-wpbody class. Let me know if you have run into this or if you see an issue with it.

    Thanks again for the awesome plugin.

  27. mikeha says:

    BEA utiful, love it. works wonderfully. Thank you for making my life easier!!!

  28. Karnith says:

    Updated js for SharePoint 2013

    (function ($) {
    $.fn.wpTabify = function () {
    if ($(‘.ms-WPAddButton’).size() == 0) {
    return this.each(function (i) {
    var tabList = $(‘<ul class="wpt-ui-tabs-nav"/>’);
    var panels = $(‘<div class="wpt-ui-tabs-wrapper"/>’);
    $(this).find(‘div[id^="MSOZoneCell_"]’).each(function (j) {
    $(tabList).append(‘<li><a href="#ui-tab-panel’ + i + j + ‘">’ + $(this).find(‘h2.ms-webpart-titleText’).text() + ‘</a></li>’);
    var thisPanel = $(‘<div id="ui-tab-panel’ + i + j + ‘" class="wpt-ui-tabs-panel"/>’);
    var panelContents = $(this).detach();
    $(thisPanel).append($(panelContents).find(‘.ms-WPBody’).html());
    $(panels).append(thisPanel);
    });
    if ($(tabList).find(‘li’).size() > 0) {
    $(this).prepend(panels);
    $(this).prepend(tabList);
    $(this).tabs();
    }
    });
    }
    else {
    return false;
    }
    };
    })(jQuery);
    jQuery(document).ready(function(){
    jQuery(‘.my-div-class’).wpTabify();
    });

  29. Larry Milask says:

    Hi Kyle;

    Have working through your branding class code for a test site. Found a few minor typo errors in your class handout and will another time. Was trying to style the tabs background color when selected and the style: “.ui-tabs-nav li.ui-tabs-selected a ” does not seem to work. Can you clarify?

    Thanks much;

    • Kyle says:

      Hi, Larry. I don’t think that’s a typo, it just depends on which version of jQuery UI you’re using. Depending on the version and age of your UI library, the “active” tab class could be .ui-tabs-active, .ui-state-active, or .ui-tabs-selected.

      • Larry says:

        Hi Kyle;

        Great; turned out to be .ui-tabs-active.
        Where is the best place to ask you about the jQuery cycyle solution you presented in class?

        Thanks much;

  30. Kumar says:

    Hi Kyle,

    Thanks for the post.It almost worked fine for me, but I have an issue here…whenever I select filtering or sorting of fields in one of the tabbed list, the control goes back to the first tab after postback rather than maintaining the selected tab. Do you have any fix for this issue??

    Kumar.

  31. kumar says:

    Hi Kyle,

    I have posted a reply on your post and waiting for your answer. Please let me know if you have a solution for the above issue!!

    Thanks.
    Kumar.

    • Kyle says:

      Hi, Kumar. Your problem is more related to jQuery than my script/plugin. You could write some JS caching into the script. I’ve done this before but it will not be part of my script here.

  32. Kumar says:

    Hi Kyle…Thanks for the reply!!…Could you please provide me the script if you have it??….. I have tried caching it in a hidden variable but it’s not working when page gets reloaded. I’m unable to retrieve the current selected tab after page reloads…