Using jQuery Tabs and ASP.NET MVC Partial Views For AJAX Goodness

Posted on February 23rd, 2010 by Kevin

Note: This example was built using jQuery UI 1.7.2 (which packages jQuery 1.3.2).  If you use jQuery 1.4.1, this example will break.  jQuery UI 1.8 will fix.  Thanks to mvcuser.  http://dev.jqueryui.com/ticket/5065

In my current project, I’ve had the need to use a Tab control but the data inside of the tabs was way too hefty to load initially when page loaded for the first time.  Luckily, the jQuery Tab control provides this functionality for me already.  However, I needed to find a way to easily organize the tab content on the server.  ASP.NET MVC provides a great structure for this called Partial Views.

In this quick tutorial, I’ll give you a run down on how to set up a jQuery tab control and how to configure ASP.NET MVC Partial Views to work with the tab controls.

Configuring Your View

Since we’re working in ASP.NET MVC, we’re going to talk about our pages in the form of Views.  I’m working with the default “blue screen” ASP.NET MVC application.  After you’ve downloaded and linked the jQuery and jQuery UI scripts to your View (either in the view itself or in the master page), you’re going to add the following code:

    <script type="text/javascript"><!--mce:0--></script>
<div id="tabContainer">
<ul>
	<li><a href="/Home/GetHomeTab">Home</a></li>
	<li><a href="/Home/GetProductTab">Products</a></li>
	<li><a href="/Home/GetContactUsTab">Contact Us</a></li>
</ul>
</div>

This code replaces the existing content section in the Index view for the Home controller.  The most interesting part of this is the tabContainer div.  Inside of it, we’ve declared a unordered list, and several list items.  jQuery UI uses this determine how to format the tab control.

You’ll notice that inside of our list items (<li> tags) that we’re using links to various action links (and yes, I know I could use HTML helpers to build these links for me).  Now, we need to build the views that will be rendered inside the tabs.

Here is an example of building the GetHomeTab view.  Nothing special, but make sure that you select Create a partial view.  Partial views won’t have any of the HEAD, HTML, or BODY fluff inside of them.  These are perfect for our tabs.

image

Repeat for GetProductTab and GetContactUsTab.  Add a few lines of text to the views in so you know they’re working.  Here’s an example of what my GetHomeTab looks like:

&lt;%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %&gt;
<h1>Home</h1>
You're inside the Home tab, which was rendered via a partial view!

Before we can test, we need to update our Controller to return the views as requested.  Here’s the additions you’ll make to your Home controller:

public ActionResult GetHomeTab()
{
return PartialView();
}
public ActionResult GetProductTab()
{
return PartialView();
}
public ActionResult GetContactUsTab()
{
return PartialView();
}

You can attach models to these views and they’ll work fine.  Build and run the application.

image

And to prove that everything is working as AJAX call backs, we can look at FireBug:

image

Firebug will show that when I clicked on the Contact Us tab, it automatically made an AJAX call to our Home controller and retrieved the partial view.

That’s awesome Kevin, now Why?

Tabs can be bloaty.  They contain a ton of markup for rendering inside the tab, and all this needs to be maintained within a single file.  By loading our pages dynamically, we’re eliminating the strain on the server.  Imagine we have 10 tabs.  If the user only needs to access two of them, we’re wasting bandwidth by downloading all the additional markup.  Then the browser needs to render it and store it, waiting for the user to come along and do something.  In an AJAX environment, we only download tabs as needed.  Much less strain on the server.

Second, maintaining 11 small files is much easier than maintaining 1 large file.  If you need to make a change to the Contact Us tab, you don’t need to go searching through the main page to find it.  Instead, you locate the GetContactUsTab view and make your changes!

I hope you’ve learned something from this, and maybe implement it into your future projects.  I can tell you that it definitely makes a difference in my app where there are 10 tabs containing a lot of data.  Separating out all the pieces makes it much easier to maintain and update.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Tags: , , , ,

Categories: ASP.NET, jquery

26 Responses to 'Using jQuery Tabs and ASP.NET MVC Partial Views For AJAX Goodness'

  1. Cool idea – although i think sometimes it is better to have the content right there so that a high latency connection doesn’t affect tab switching.

    Although for interactive content tabs this is definitely a win…

    thanks for the toolbelt item :-)

  2. [...] Using jQuery Tabs and ASP.NET MVC Partial Views For AJAX Goodness … [...]

  3. “d all this needs to be maintained within a single file”
    False. You can keep separate parts in partials.

    “By loading our pages dynamically, we’re eliminating the strain on the server.”
    Not proven and not necessarily.
    In fact your example it will be much better to load all 3 tabs on that page within one request (Home page) instead of 3.

    Another very important thing about this particular example is that you really should separate Products and Contact Us pages. The reason is that a User can have JavaScript disabled (and it is still common), then they will see link to Products & Contact Us. Clicking it they will see nothing except the plain content of those parts only. No layout, nothing. Usual user just leaves the site.

    So the point is that it should not be overused. In fact the example for Home, Products, Contact Us might be the worst one IMO.
    Something like Product, Reviews, Recommendations would probably be a better sample.

    Cheers,
    Dmitriy.

    • Jon Hilton says:

      But in the controller you could check if the request was an AJAX request and return the view complete with master page if not.

      So if a user doesn’t have javascript, they would see a link, which (when clicked on) would give them a page complete with layout and style.

  4. mvcuser says:

    Doesn’t seem to be working with jQuery 1.4.1, are you using 1.3.2?

    Thx

  5. mvcuser says:

    Sorry for the multiple posts, turns out 1.8 is out but not in \stable\ condition

    http://blog.jqueryui.com/2009/08/jquery-ui-18a1/

  6. mvcuser says:

    Since MVC2 RC2 comes with jQuery 1.4.1, that’s how i came across the issue. Doesn’t work with IE8 or FF either.

    In IE8, i first get the following error (this might be a different issue):

    Message: HTML Parsing Error: Unable to modify the parent container element before the child element is closed (KB927917)
    Line: 0
    Char: 0
    Code: 0

    And the tab URL appends “#ui-tabs-[object Object]” which is incorrect, i’ll download the jQuery UI 1.8 release and let you know if it’s working.

  7. [...] ici Tags: jQuery, Partial, Tab, View Share this [...]

  8. [...] to VoteUsing jQuery Tabs and ASP.NET MVC Partial Views For AJAX Goodness … (2/23/2010)Tuesday, February 23, 2010 from KevinSince we're working in ASP.NET MVC, we're going to talk about [...]

  9. [...] Using jQuery Tabs and ASP.NET MVC Partial Views For AJAX Goodness » Kevin Griffin [...]

  10. be7 says:

    Any idea how to get an ajaxLoader animated GIF to display *inside* the tab? For example:

    $(function() {
    $(“#ajaxLoader”).ajaxStart(function() {
    $(this).show();
    }).ajaxStop(function() {
    $(this).hide();
    });
    });

    I can only get it to work if the ajaxLoader GIF is outside the tab content. Also, should this code be put in the partial view, or in the Index view?

  11. Chris says:

    This is a very cool feature. Wish it was in standard ASP.NET though. I’ve not used MVC in earnest yet, but this effectively is like an old ‘include’ from classic ASP.
    A much better way of implementing when using tabs.
    Nice article.

  12. Mike says:

    I really like this affect, great article.

    One question though. I know you’ve allowed for the history to work when you click the back button but when I click a few pages then click back until I get to the webpage that doesn’t have a #anchor in the URL (the initial page) then it just shows the animation spinning.

    Is this an issue? And if so, does anyone know how to correct it?
    ——————————————-
    Avermedia trots out AVerLife Cinema media playing set-top box

  13. Greg says:

    so, it seems to me that either the examples are incomplete and/or I am doing something wrong (quite probably the latter)… when I implement this as shown, (a) the LIs are not rendered as tabs and (b) when links are clicked the .ascx content is just loaded sequentially into the page,

    I have verified that my links to JQ 1.42 and UI 1.84 are correct, the scripts are being loaded and I re-downloaded UI just to be sure that ‘Tabs’ was included.

    jQTabs is called with this I assume:

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

    Any ideas?

    • Kevin says:

      Hey Greg,
      Shoot me an email at kevin at kevgriffin dot com along with an example snippet. I’ll take a look and see what’s causing the issue.

      Kevin

    • Kyle Russell says:

      Double check which jQuery files you are loading. The documentation says UI Core is required so I was loading only jquery.core.ui and jquery.ui.tabs. Once I realized UI Core meant all the core files it worked. Basically you may be missing jquery.ui.widget. It makes sense now but the jQuery website should be a bit more clear which libraries are required for certain functions.

    • DE says:

      I am also having significant issues. I have downloaded the JQ 1.42 and UI 1.85 (all components selected) and confirmed they are loaded and tabs are included.

      1) The LIs are rendered as a normal list, not tabs
      2) When clicking on the link it just goes to and only displays the .ascx file content, not on the same page.

  14. OogaBooga says:

    Great post. Can I nest another set of tabs inside the partial view that looks identical to the first set of tabs but with different content?

    Thanks in advance.

  15. LMD says:

    Thanks for this neat and clean solution. I was looking for a way to improve the response time on an app, with tabs, that’s getting too bulky. This is very straight forward and avoids doing a bunch of ajax calls and a whole lot of rework. Thanks!

    LMD

  16. Patrick says:

    Hey there, i came across this solution a while back and have managed to get it working with firefox and chrome etc. But in IE 8 the partial views do not get loaded whatsoever, it seems as tho the action methods arnt being hit. I can see in firebug that they are when using firefox tho.Please Help :)

  17. Oran says:

    Hey there,

    Thanks for your article. This is exactly what I’m looking for but for some reason it’s not working for me.

    I’m using ASP.NET MVC 3.

    In the Master page I have:
    <script src=”@Url.Content(“~/Scripts/jquery-1.4.4.js”)” type=”text/javascript”></script>
    <script src=”@Url.Content(“~/Scripts/jquery-ui.min.js”)” type=”text/javascript”></script>

    and in the View I have:

    @{
    ViewBag.Title = “Index”;
    }
    <div id=”maintenance”>
    <div id=”tabs”>
    <ul>
    <li><a id=”lnkUsers” href=”/Maintenance/Users”><span>Users</span></a></li>
    <li><a id=”lnkMisc” href=”/Maintenance/Misc”><span>Misc</span></a></li>
    </ul>
    </div>
    </div>
    <script type=”text/javascript” language=”javascript”>
    $(function () {
    $(“#tabs”).tabs();
    });
    </script>

    The problem is that I get empty tabs and when I hover over the tab links I see the link is http://localhost/WebApp/Maintenance#ui-tabs-1 instead of http://localhost/WebApp/Maintenance/Users

    Anyone else had this problem? Any ideas?

    Thanks