jQuery-Ui Tabs and Asp.net MVC

2009 March 17
by ericdotnet

Clay made a comment on my previous post and asked how I would use asp.net mvc with jQuery-UI’s tabs. I have slapped together an example project that shows how you could implement the tabs in an asp.net mvc web site. I created an ajax and a regular tab example.

Tab Example jQueryUi

Tab Example jQueryUi

Basically I use a partial view for each tab. This partial view is then also used for the ajax response.

<div id="tabs">
<ul>
	<li><a href="#tabs-1">Text 1</a></li>
	<li><a href="#tabs-2">Text 2</a></li>
	<li><a href="#tabs-3">Text 3</a></li>
</ul>
<div id="tabs-1">
            < % Html.RenderPartial("_tab1", Model);  %></div>
<div id="tabs-2">
	        < % Html.RenderPartial("_tab2", Model);  %></div>
<div id="tabs-3">
	        < % Html.RenderPartial("_tab3", Model);  %></div>
</div>

There is no database access in the example project, I sort of simulated a database by using a service model that provides the viewmodel that holds the texts that are displayed in the three tabs.

Regarding the ajax controller method, it would of course be better to not get the entire viewmodel in a real world situation and then pass that on to the view, but since this is a brief demo I thought I could get away with this in this example ;) .


        public ActionResult getAjaxTab(int id)
        {
            string viewName = string.Empty;

            TabExample.Services.tabTextService serv = new TabExample.Services.tabTextService();
            tabViewModel myModel = serv.getTabViewModel();

            switch (id)
            {
                case 1:
                    viewName = "_tab1";
                    break;
                case 2:
                    viewName = "_tab2";
                    break;
                case 3:
                    viewName = "_tab3";
                    break;
                default:
                    viewName = "_error";
                    break;
            }

            System.Threading.Thread.Sleep(1000);   

            return PartialView(viewName, myModel);
        }

I am using this js function to update the tabs.


        function getContentTab(index) {
            var url='< %= Url.Content("~/Home/getAjaxTab") %>/' + index;
            var targetDiv = "#tabs-" + index;
            var ajaxLoading = "<img id='ajax-loader' src='<%= Url.Content("~/Content") %/>/ajax-loader.gif' align='left' height='28' width='28'>";

            $(targetDiv).html("
" + ajaxLoading + " Loading...
"); 

            $.get(url,null, function(result) {
                $(targetDiv).html(result);
            });
        }

There is a select event on the tabs that you can hook into as well, I just find it easier to just use the onclick event of the tab div’s.

Hope this is some help to anybody out there, it was fun to create this small project. If anyone has any suggestions, or questions let me know in the comments !

Download TabExample Project Link

27 Responses leave one →
  1. 2009 March 19

    Nice one though, downloading sample project right now. I actually wanted to use JQuery Ui tabs in ASP.NET MVC in my current project. Now i don’t have to dig into the problems. I can watch an learn from your code.

  2. 2009 March 19

    Thanks ! It was created with rc2, but should work with the new 1.0 as well !

  3. 2009 March 26
    KBase permalink

    Tab Text Example- not getting data from server, only load first time.
    Ajax Tab Example – getting data from the server

    You are comparing performance for each one. but it is fake

    If you claim Tab Text Example takes data from server every time then drop me a message.

    • 2009 March 26

      > Tab Text Example- not getting data from server, only load first time.

      The data in this example is indeed loaded when you load the controller / page holding the tabs.

      > Ajax Tab Example – getting data from the server

      Indeed, it does an ajax request to get the content for the tab you click on.

      > You are comparing performance for each one. but it is fake

      I am not comparing anything, just showing two different ways to do things.

  4. 2009 April 17

    Nice job on your implementation. I want to simply use the tabs to navigate to the controllers to pull each view from a MasterPage, so essentially only use the tabs as navigators without using the inner div tags but haven’t found a nice way to do this. I thought either through jQuery or Json I could call the controllers. Any suggestions?

    • 2009 April 17

      You could either use the 2nd method (the ajax one), but that means that you depend on javascript to load your pages. So if someone comes along that doesn’t use javascript he can’t load the site.

      You might me better off using a jquery menu plugin. And there are a lot of those out there ;) .

    • 2009 April 17

      Thank you for the follow-up I will take a look for an appropriate jQuery menu plugin.

      Cheers!

  5. 2009 April 18

    Maybe this is a good one. Looks pretty nice:
    http://pupunzi.wordpress.com/2009/01/18/mbmenu/

  6. 2009 April 21
    Ricky permalink

    In the Ajax Tab Example, when the page loads it is set to use the first content tab:

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

    I wanted to see if the page would load the second tab by updating it to use:

    getContentTab (2);

    Why does the document load the first tab but not second? What could I do to accomplish this?

    Thanks again for sharing!

    • 2009 April 22

      You have to activate the 2nd tab then load the content. Something like this:

                  $("#tabs").tabs('option', 'selected', 1);
                  getContentTab (2);
      

      The 1 in the first line is because it’s a zero based index.

      Hope this helps !

    • 2009 April 22
      Ricky permalink

      I ended up using:

      var $tabs = $(‘#tabs’).tabs();
      var selected = $tabs.tabs(‘option’, ’selected’);
      var contentTab = $tabs.tabs(‘option’, ’selected’, 1);

      getContentTab(2);

      Thanks again for your help!

  7. 2009 April 22

    Ok that looks good too. Glad to be of service ;) .

  8. 2009 July 9
    Clay permalink

    A friend just sent me a link to this…and I thought hey that’s me!
    Thanks for the post!
    Nice example.

  9. 2009 September 1
    colforbin permalink

    I am not sure exactly what you mean by this… I am new to MVC. Could you clarify and maybe lead me in the direction of what I should actually do for best results?

    Thanks!

    “Regarding the ajax controller method, it would of course be better to not get the entire viewmodel in a real world situation and then pass that on to the view, but since this is a brief demo I thought I could get away with this in this example”

    • 2009 September 2

      What you usually do is make a partial view strongly typed and render it like this Html.RenderPartial(Viewdata.Item); Instead of passing down the whole viewdata to the partial !

      Hope this helps :) .

    • 2009 September 2
      colforbin permalink

      So I would need to create a class for each tab partial view so you are passing a strongly typed into the RenderPartial()…. Then you just have to change the Inherits property for the partial view to use the newly created class….

      Is that correct ?

  10. 2009 September 2

    Yes you could do it like that. Or do it just like the example if that´s more convenient :) .

    • 2009 September 2
      colforbin permalink

      What in your opinion is the best real world approach ?

  11. 2009 October 8
    Paul Wallace permalink

    Thanks for the example code, very helpful. I’ve run into a problem using accordions within tabs, the initially inactive accordions do not render there content correctly when their tab is selected. Reading around I see the reason for this is that the inactive tabs have display:none initially so the height of the divs within the accordion do not get calculated correctly. None of the suggested solutions work for me.
    Wondering if you have had to overcome this and have a work around?
    See code below for example of the problem:

    $(document).ready(function(){
    $(‘#tabs’).tabs();
    $(“#accordion1″).accordion();
    $(“#accordion2″).accordion();
    });

    Tab 1
    Tab 2

    Section 1

    Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer
    ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit
    amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut
    odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.

    Section 2

    Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet
    purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor
    velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In
    suscipit faucibus urna.

    Section 3

    Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis.
    Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero
    ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis
    lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.

    List item one
    List item two
    List item three

    Section 4

    Cras dictum. Pellentesque habitant morbi tristique senectus et netus
    et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in
    faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia
    mauris vel est.

    Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus.
    Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
    inceptos himenaeos.

    Section 1

    Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer
    ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit
    amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut
    odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.

    Section 2

    Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet
    purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor
    velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In
    suscipit faucibus urna.

    Section 3

    Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis.
    Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero
    ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis
    lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.

    List item one
    List item two
    List item three

    Section 4

    Cras dictum. Pellentesque habitant morbi tristique senectus et netus
    et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in
    faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia
    mauris vel est.

    Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus.
    Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
    inceptos himenaeos.

    • 2009 October 30

      Oh sounds complicated. Has this bug been fixed yet ? Otherwise you’d need to work around it !

    • 2009 October 30
      Paul Wallace permalink

      Solution is to load the accordians first:

      $(document).ready(function(){
      $(“#accordion1″).accordion();
      $(“#accordion2″).accordion();
      $(‘#tabs’).tabs();
      });

  12. 2009 October 30
    Frank Footer permalink

    So with this example, how would you point to an ascx file in a different view folder or is that possible?

  13. 2009 October 30

    You’d probably have to put the ascx in the shared folder ?

  14. 2009 October 30
    Frank Footer permalink

    Well, this is how I did it… looks like each controller would need getAjaxTab(int id) or would need to inherit from a parent that has that method in it…

    So basically, adding a “view” argument to the getContentTab javascript function…

    $(document).ready(function() {
    $(“#tabs”).tabs();
    getContentTab (‘gumby’,1);
    });

    function getContentTab(view,index) {
    if (view == “” || view == null){
    view = “Home”;
    }
    var url=’/’ + index;
    var targetDiv = “#tabs-” + index;
    var ajaxLoading = “<img id='ajax-loader' src='/ajax-loader.gif’ align=’left’ height=’28′ width=’28′>”;

    $(targetDiv).html(“” + ajaxLoading + ” Loading…”);

    $.get(url,null, function(result) {
    $(targetDiv).html(result);
    });
    }

    function call:
    Text 1

  15. 2009 October 30
    Frank Footer permalink

    crimony!… url is like this:

    var url=’/’ + index;

  16. 2009 October 30
    Frank Footer permalink

    well, I see why you did screen shots now :-)

    var url='/' + index;

Trackbacks & Pingbacks

  1. This Week in jQuery UI vol. 2 « jQuery UI Blog

Leave a Reply

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS