Adding a Tabbed View to A Web Part Page Using jQueryUI

Sometimes I work on something and blindly stumble into a neat trick. The other day I was trying to figure out how to reliably add a tabbed view to a SharePoint Web Part Page. I was working in SharePoint Designer, so I had total freedom to try whatever I wanted.

The idea was to show a set of tabs, each of which could contain at least a Content Editor Web Part (CEWP) initially. We wanted it to look something like this:

Tabs Mock UpAside: Wireframes drive me a little batty because they turn into the goal rather than just a useful development tool. Mock ups like this using something like Balsamiq make far more sense to me. The Comic Sans makes it very clear to everyone that this is the basic idea, and we’re not talking about pixel placement.

My first thought was of course to use Christophe Humbert’s most excellent Easy Tabs, but for some reason that wasn’t working in the page. Since we’re already using jQueryUI for some other things – this is a highly customized environment – I figured that it would be a good alternative and would probably give me more control of the display.

If you look at the jQueryUI documentation, you’ll see that there is some specific markup required to get the .tabs() widget to function:

<div id="tabs">
   <ul>
      <li><a href="#tabs-1">Nunc tincidunt</a></li>
      <li><a href="#tabs-2">Proin dolor</a></li>
      <li><a href="#tabs-3">Aenean lacinia</a></li>
   </ul>
   <div id="tabs-1">
      <p>Tab 1 content</p>
   </div>
   <div id="tabs-2">
      <p>Tab 2 content</p>
   </div>
   <div id="tabs-3">
      <p>Tab 3 content</p>
   </div>
</div>

Once you have that basic markup in place, you can make this simple call to activate the tabs:

$("#tabs").tabs();

There are multiple options, of course, but that gets you the basics.

I tried a number of things, but the main difficulty I had was that Web Part Zones cannot contain markup; they can only contain Web Parts. SharePoint Designer strips out any markup that you add manually inside a Web Part Zone.

Somehow I thought of trying to wrap the Web Part Zone with the markup I needed to make the tabs work instead. Even better, each tab could have its own Web Part Zone so that we could edit existing Web Parts and add new Web Parts to the tabs at will. That markup ended up like this:

<div id="team-tabs">
  <ul>
    <li><a href="#tabs-how-we-help">How we can help</a></li>
    <li><a href="#tabs-case-studies">Case studies</a></li>
    <li><a href="#tabs-projects">Current projects</a></li>
    <li><a href="#tabs-applications">Applications we support</a></li>
  </ul>
  <div id="tabs-how-we-help">
    <WebPartPages:WebPartZone runat="server" Title="loc:HowWeHelp" ID="HowWeHelp" FrameType="TitleBarOnly"><ZoneTemplate>
    </ZoneTemplate></WebPartPages:WebPartZone>
  </div>
  <div id="tabs-case-studies">
    <WebPartPages:WebPartZone runat="server" Title="loc:CaseStudies" ID="CaseStudies" FrameType="TitleBarOnly"><ZoneTemplate>
    </ZoneTemplate></WebPartPages:WebPartZone>
  </div>
  <div id="tabs-projects">
    <WebPartPages:WebPartZone runat="server" Title="loc:Projects" ID="Projects" FrameType="TitleBarOnly"><ZoneTemplate>
    </ZoneTemplate></WebPartPages:WebPartZone>
  </div>
  <div id="tabs-applications">
    <WebPartPages:WebPartZone runat="server" Title="loc:Applications" ID="Applications" FrameType="TitleBarOnly"><ZoneTemplate>
    </ZoneTemplate></WebPartPages:WebPartZone>
  </div>
</div>

This markup gives us this nice UI. I’ve blurred out the specific content in the CEWP, but you should get the idea.jQueryUI Tabs Example

The really nifty thing about all of this is that editing the content of each Web Part Zone seems to work just fine in the context of each tab. In other words, not only do we get the user experience (UX) goodness from the tabs for the end user, we also get it for the few people who will be editing the tab content.

Editing Web Part Zone Content

Similar Posts

95 Comments

  1. This is a cross-post from

    http://social.msdn.microsoft.com/Forums/en-US/sharepointcustomization/thread/9257f222-c61d-4ccb-ad43-c0a52906b3fe

    in reference to using this solution and having multiple web parts under one tab… It thought it was relevant here as the original JQuery tab method was yours Marc.

    “I had a problem with this when using Marc Anderson’s tab solution (see link to article at bottom). In this case, because the JQuery reference is coded directly in the page using SharePoint Designer, I could not have a reference to JQuery in my CEWP, which happened to be the second web part on the page. I simply removed the JQuery reference in the CEWP and everything worked fine. By the way, the 2nd web part, the CEWP, referenced a script to adjust the width of the column names from the primary list under this tab. A side effect was that the CEWP web part was showing on the page in non-edit view; I was able to fix this by chaning the chrome for the CEWP to “none”.

    Brant.
    http://sympmarc.com/2011/11/09/adding-a-tabbed-view-to-a-web-part-page-using-jqueryui/

    1. Brant:

      It sounds like the general issue is multiple references to the jQuery library. In any given page, there should be only one reference, whether it’s in that page in a CEWP, inline, in a page layout, or the master page. Bottom line: reference jQuery (and any other .js filees you are using) only one per page in the user’s browser.

      M.

  2. Marc,

    Thanks for this post, very useful!!

    Problem is, I can’t seem to get the tabs to work in our SP 2010 Enterprise environment…?

    I uploaded the library files, added the references in the section of my masterpage, added the code above to my page, wrapping my wp zones as shown in your example, then after the last closing div tag, added the call “$(“#tabs”).tabs();”.

    Went to preview my page and see an unordered list with the headings I put in the ‘s, then each wp zone separately beneath it…no tabs.

    What am I doing wrong?

    TK

    1. TK:

      It sounds like you may not have wrapped the call to .tabs() in a $(document).ready(). This would mean that the .tabs() call is happening before the page is fully loaded.

      M.

  3. Thanks for the fast response. Even when I wrap it in the doc ready, no good / same result.

    $(document).ready(function() {
    $(“#tabs”).tabs();
    });

    Other ideas? I’ve double-checked the referneced location for the library…

    1. My guess is that you’re getting an error of some sort. Using the IE Developer Tools or Firebug, you can figure out what’s going wrong. The most common things would be bad references to the files or unclosed parentheses or brackets.

      M.

      1. You are correct, in IE Dev Tool, seeing 2 errors:
        “SCRIPT5007: Unable to get value of the property ‘id’: object is null or undefined”
        and
        “SCRIPT438: Object doesn’t support property or method ‘tabs'”.

        I’m fairly new to jQuery/JavaScript, so I’m at a bit of a loss… :(

      2. Okay, Marc – figured that one out (was a problem with the naming of the divs…DOH!). Now I’m seeing the tabs, however all 3 of the zones that are supposed to be tabbed are showing. Clicking the different tabs does nothing…ideas?

        My library references are good, the function is correct…all code exactly matches your example.

        Grrr…thanks in advance for your thoughts.

        1. Thom:

          It sounds like there is still something wrong with the markup you’ve added into the page. If the .tabs() functions is generating the tabs but not hiding the content for all but one of them, then the containers aren’t structured or named correctly.

          M.

          1. Here is my exact code, if you could please advise what I’ve missed:

            <div id="tabs">
              <ul>
                <li><a href="#tabs-new-all">All</a></li>
                <li><a href="#tabs-new-hospitals">Hospitals</a></li>
                <li><a href="#tabs-new-clinics">Clinics</a></li>
              </ul>
            
              <div id="tabs-new-all">
            	<WebPartPages:WebPartZone id="newall" runat="server" title="loc:newall" FrameType="TitleBarOnly"><ZoneTemplate>
            	</ZoneTemplate></WebPartPages:WebPartZone>
              </div>
            
              <div id="tabs-new-hospitals">
            	<WebPartPages:WebPartZone id="newhospitals" runat="server" title="loc:newhospitals" FrameType="TitleBarOnly"><ZoneTemplate>
            	</ZoneTemplate></WebPartPages:WebPartZone>
              </div>
            
              <div id="tabs-new-clinics">				
            	<WebPartPages:WebPartZone id="newclinics" runat="server" title="loc:newclinics" FrameType="TitleBarOnly"><ZoneTemplate>
            	</ZoneTemplate></WebPartPages:WebPartZone>
              </div>
            </div> 
            
              1. Thanks for your help Marc! Downloading the most recent version of UI with all the accompanying files seemed to fix me up.

                Great support!

  4. Can you provide the complete code for you example. Especially the calls to the scripts. Like what version of jquery should be called? What stylesheet is being called? I personally am not a jquery programmer and it seems like some critical code is missing in your code samples. I used what you provided in your post and it does not work and I think it is because I am not adding the right script calls. I think this will solve a big problem for me in getting to use web part zones in a tab view so I would appreciate a response. Thanks!

    1. Jill,

      The only pieces missing from my post are the references I placed in the head section of my master page:


      Then the function in my ‘scripts.js’ file:

      $(document).ready(function() {
      $(“#tabs”).tabs();
      });

      1. Thanks, I found what I needed from another blog posting. And, yes, I was referring to whatever the script calls were in your masterpage. Need to know what those were in order to show the tabs on the page.

  5. Hi Marc,

    New to implement jQueryUI and I would truly appreciate step by step guidance on this. I have already downloaded the jQueryUI from their website and it’s in _Layouts/jQuery/jquery-ui-1.10.3 folder. Also, it’s the latest version of jQueryUI. I am using the same web-part-page from the EasyTab so I can I put the few webparts per zone.

    Thanks
    Amber Berg

    1. Amber:

      You need to edit the page in SharePoint Designer and add the markup that allows the tabs to work around each of your Web Part Zones, as you can see in the third code snippet. You will probably have a different number of Web Part Zones and they will have different names, but as you can see in the first example, jQueryUI’s .tab() function requires an outer div for all of the tabs, an unordered list with an item per tab at the top of that div, and then a div per tab panel.

      M.

      1. Hi Marc,

        Am Sorry to trouble you, but i am new to JQuery.
        Would you mind having a quick look at my code below , i am facing some issues in calling the function. please

        Div.ms-titleareaframe {
        height: 100%;
        }
        .ms-pagetitleareaframe table {
        background: none;
        }

        //

        body #s4-leftpanel {
        display:none;
        }
        .s4-ca {
        margin-left:0px;
        }

        0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF39006F5D28E972289640B3F508CCC400DEF4Page,

        if(typeof(MSOLayout_MakeInvisibleIfEmpty) == “function”) {MSOLayout_MakeInvisibleIfEmpty();}

        $(document).ready(function(){
        $(“#webTabs”).tabs();
        });

        How we can help
        Case studies
        Current projects
        Applications we support

        This is view area

  6. Hi Marc,

    Tabbed webparts are working fine , thank you very much for that , but on postbacks the first tab get selected by default , what should i do to solve that , any ideas ?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.