jQuery-Ui Tabs and Asp.net MVC
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.
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 !

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.
Thanks ! It was created with rc2, but should work with the new 1.0 as well !
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.
> 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.
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?
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
.
Thank you for the follow-up I will take a look for an appropriate jQuery menu plugin.
Cheers!
Maybe this is a good one. Looks pretty nice:
http://pupunzi.wordpress.com/2009/01/18/mbmenu/
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!
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 !
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!
Ok that looks good too. Glad to be of service
.
A friend just sent me a link to this…and I thought hey that’s me!
Thanks for the post!
Nice example.
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”
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
.
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 ?
Yes you could do it like that. Or do it just like the example if that´s more convenient
.
What in your opinion is the best real world approach ?
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.
Oh sounds complicated. Has this bug been fixed yet ? Otherwise you’d need to work around it !
Solution is to load the accordians first:
$(document).ready(function(){
$(“#accordion1″).accordion();
$(“#accordion2″).accordion();
$(‘#tabs’).tabs();
});
So with this example, how would you point to an ascx file in a different view folder or is that possible?
You’d probably have to put the ascx in the shared folder ?
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
crimony!… url is like this:
var url=’/’ + index;
well, I see why you did screen shots now
var url='/' + index;