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:
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 ?
Yes you could do it like that. Or do it just like the example if that´s more convenien
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;
Hi
I’ve inserted all you javascripts and Style to my project, and did set all your adjustment exactly but the style of tabs does not work for me.
Really cool demonstration… Thanks for sharing this.
So, your solution was exactly what I was looking for, thanks! There is one thing I’m still trying to figure out; however.
I’m using the AJAX example you’ve posted so when I click on a tab I call a controller action and generate a partial view in a div on the page. I’d like to allow my users to use the browser back/forward buttons and bookmark pages. Have you any ideas on how to implement this solution while preserving back/forward behavior of the browser?
I’ve taken a look at Ben Alman’s jQuery BBQ (http://benalman.com/code/projects/jquery-bbq/examples/fragment-jquery-ui-tabs/#some_tabs=0); but it doesn’t assume you are using AJAX.
Thanks in advance for any help!
Hi,
I have a different problem. I have an accordion control and each div (not the header but the content) has a Tab control and i am trying to load the accordion using the Ajax.
First time, when add some content to the accordion, the tab control in that content loads fine. but, for everyother subsequent addition of content to the accordion, the tab controls dont load or should i say that they dont have a tab css set and hence they dont act like tabs. its just the content sitting out there.
is it ok to have multiple jquery tab controls in one single page?
is there anyway i can get some help…
thanks a lot in advance,
Pavan
I havent tried nesting various of those controls yet. Maybe you can ask over at stackoverflow.com ? I am sure some smart people will have an answer :).
Hi Eric,
I’ve been trying to implement your code into an MVC 2 application. I’m getting the error:
The server block is not well formed on the following line. Note that my gif is in an Images folder off Content.
var ajaxLoading = “<img id='ajax-loader' src='/ajax-loader.gif’ align=’left’ height=’28’ width=’28’>”;
I have tried to rewrite this line, but without success. Do you (or someone else) know how to rewrite the line so tht .Net does not complain?
Thanks!
Arnold
I’m using jQuery-1.4.2
Hi Again,
I t looks like the line got cropped when I copied when I pasted it in. Here it is again in bits:
var ajaxLoading = “<img id='ajax-loader'
src='
/ajax-loader.gif’ align=’left’ height=’28’ width=’28’>”;
Thanks,
Arnold
I’ll try one more time. This time I pasted into Notepad, first.
var ajaxLoading = “<img id='ajax-loader'
src='
/ajax-loader.gif’ align=’left’ height=’28’ width=’28’>”;
Fingers crossed.
If we don’t see the entire line, just know that it’s the one beginning with:
var ajaxLoading
Arnold
The way I do that these days is using CSS. So you append a class with display: none if you do not want to show the gif, and remove it if you want to. Or make a span of the give and do hide and show(). Very easy with jQuery !
Hope this helps !
Hi Eric,
Thanks for the tip! I’m new at jQuery and ASP.NET MVC, so I’m picking up whatever I can. I got your example working! Well..almost…It all works except for the fact that the jQuery tabs do not appear. My tabs page is a duplicate of yours. I summon the page in the browser url, something like:
http://localhost:60768/Media/TabAjaxExample/1
Debugging, I see that execution proceeds into the Media Contoller/TabAjaxExample Action. The correct view is populated with the correct model data.
However, the page displays the correct data without tabs. It’s as though the tabs are not recognized as such. I’ve poured through the code comparing your implementation with mine, but I don’t see the critical difference. Do you have an idea what might be happening?
Thanks, Arnold
It could be that you forgot to hook up the tabs in javascript. Dont forget this
$(document).ready(function() {
$(“#tabs”).tabs();
});
Hi Eric,
I see what is happening, now, but I don’t know why.
The tabs page (TabAjaxExample.aspx) uses Site.Master, so I would expect its display to be accompanied by the master page code, with header and logo, etc.
However, what I see in View Source is the partial view created in _tab1.ascx. That partial view should have been injected into the tab div.
Thanks for any insight,
Arnold
Eric,
I definitely got the tabs hooked up:
$(document).ready(function() {
$(“#tabs”).tabs();
getContentTab (1);
});
And it does return the tab number to the controller, through the function getContentTab().
-Arnold
Eric,
I’m so new to this.
I found out my problem. Now everything works perfectly!
Thanks for your patience and the great example!
Arnold
Great that you got it right :).
Hi Eric,
I have yet another question.
If I were to place a Submit button on a partial view loaded into a tab via the Ajax method you describe above, what would the code to post back changed data look like? I don’t suppose I could get away with something like this?
var url=’/’ + index;
Thanks,
Arnold
Sorry, forgot about the gator tags which shall be hereafter referred to as gtl; and gtr;
I meant something like this:
var url=’gtl;= Url.Content(“~/Home/MyPostBack”) gtr;/’ + index;
Thanks,
Arnold
Erm… How can I get this to run in VS 2010? Im trying to convert it but it fails
This blogpost was written over a year ago using mvc 1.0, so you’ll have to be a bit creative and try and get it to work. The underlying techniques should still be the same.
Useful information..thx Thank You for having us
excellent information, thank you thanks for the inspiration!
Good one. Used it as starting point and got myself a jQuery UI book.
Working it into an Asp.Net MVC 2 Sample you can view/download here: http://jquery.krokonoster.com/
Hi,
I want to do a Jquery POST and get a chart using renderControl (which will return HTML attributes) I have successfully done this on WEbforms, However the same with MVC give a empty image. The handler doesn’t perform the same in MVC2 3.5. I went near to 50 sites now.
No solutions could resolve this.
I can’t use base64encoding as IE6, 7 don’t support it.
I have few data parameteres to be sent to server and in response get the Chart image along with some table data all this to be done using JQUERY. No postbacks to be used.
Hi PLZ use this comment for reply,
I want to do a Jquery POST and get a chart using renderControl (which will return HTML attributes) I have successfully done this on WEbforms, However the same with MVC give a empty image. The handler doesn’t perform the same in MVC2 3.5. I went near to 50 sites now.
No solutions could resolve this.
I can’t use base64encoding as IE6, 7 don’t support it.
I have few data parameteres to be sent to server and in response get the Chart image along with some table data all this to be done using JQUERY. No postbacks to be used.
Hi,
Is there a way in the “Tab Text Example” to dynamically determine which tab is selected? For example, I would like tab2 to be the one selected when I click on the Tab Text Example link.
Thanks,
Ken
Maybe this helps. Question has been asked on Stackoverflow.com.
Great article… I applied this article using TabStrip ASP MVC component from Telerik and the result was very good. Telerik have the “Load on Demand of Content”:
http://demos.telerik.com/aspnet-mvc/tabstrip/ajaxloading
But It was not working the way that I wanted and your article gave me what I needed to load on demand my content and showing the little image “Loading”.
Thanksss