jQuery Tabs and Lazy Loading

Posted by: Malcolm Sheridan , on 9/24/2009, in Category jQuery and ASP.NET
Views: 81800
Abstract: The following article demonstrates how to use jQuery’s Ajax functionality to load data from LINQ to SQL into jQuery’s tabs control.
jQuery Tabs and Lazy Loading
 
Tabs are a great way to break up data if you have large amounts of data to display. The people from jQuery have made their own tabs control. I thought it would be cool to write an article that uses jQuery’s tab control to lazy load data from LINQ to SQL into the tabs. Well here it is. In this article I will connect to the Northwind database using LINQ to SQL, and display customer and product information in separate tabs. I’ll also show you one way of lazy loading these tabs so the data is retrieved only once, not each time a tab is selected.
Update: This article, with some modifications (jTemplates), is now a part of the eBook 51 Tips, Tricks and Recipes using jQuery and ASP.NET Controls
Before we get started, this example uses the latest version of jQuery which is 1.3.2. That can be downloaded from here. You’ll also need the jQuery UI Core Tabs Widget and the Tabs CSS files which can be downloaded from here. You’ll also need a copy of the Northwind database. If you don’t have a copy of the Northwind database, you can go here to download it.
Open Visual Studio 2008 and create a new Web Application. I’ve separated my project by adding two folders, one called CSS to store the cascading style sheets and the other called Scripts to store the JavaScript files. To begin with add a new LINQ to SQL file to your project and call it Northwind. Add the customer and products tables to the design surface:
Customer_Product
Now we need to add two methods to the default page to retrieve the data from the database. These need to be decorated with the WebMethod attribute so they can be consumed by jQuery’s Ajax function:
C#
[WebMethod]
public static List<Customer> GetCustomers()
{           
using (var dc = new NorthwindDataContext())
      {
            var query = from p in dc.Customers
                        select p;
return query.ToList();
}
}
 
[WebMethod]
public static List<Product> GetProducts()
{
using (var dc = new NorthwindDataContext())
      {
            var query = from p in dc.Products
                            select p;
            return query.ToList();
}
}
VB.NET
 <WebMethod> _
Public Shared Function GetCustomers() As List(Of Customer)
Using dc = New NorthwindDataContext()
             Dim query = From p In dc.Customers _
                          Select p
Return query.ToList()
End Using
End Function
 
<WebMethod> _
Public Shared Function GetProducts() As List(Of Product)
Using dc = New NorthwindDataContext()
             Dim query = From p In dc.Products _
                          Select p
                  Return query.ToList()
End Using
End Function
That’s all the server code we’ll need. Turning our attention back to the default page, open the HTML designer and add the following JavaScript and CSS file references to the <head> HTML tag:
<link type="text/css" href="CSS/jquery-ui-1.7.2.custom.css" rel="stylesheet" />
<script type="text/javascript" src="Scripts/jquery-1.3.2.js"></script>
<script type="text/javascript" src="Scripts/jquery-ui-1.7.2.custom.min.js"></script>
First of all you need to add the following HTML. This will act as a placeholder for the data retrieved from the database.
<div id="tabs">
 <ul>
    <li>
      <a href="#tabs-0">Customers</a>
    </li>
    <li>
      <a href="#tabs-1">Products</a>
    </li>
 </ul>
 <div id="tabs-0">
    <input type="hidden" id="tab0Selected" />
 </div>
 <div id="tabs-1">
    <input type="hidden" id="tab1Selected" />
 </div>
</div>
Now that’s done we can start adding the JavaScript. The following code will ensure when the page loads, no tabs are displayed:
$('#tabs').tabs({ selected: -1 });
The tab control has a number of events, but the two events I am binding to in this article are the select and show events.   The select event is triggered when clicking a tab and the show event is triggered when a tab is shown. The show event is critical for the lazy loading to work. When this event is fired, I am updating a hidden field in the selected tab. Before rushing off to the server to retrieve the data, I first check to see if the hidden control has a value. If it does, no server code will be executed. Add the following code for the show event:
$('#tabs').bind('tabsshow', function(event, ui) {
var tabSelected = "#tab" + ui.index + "Selected";
      $(tabSelected).html("isClicked");
});
The next step is to add code to the select event. The code for this event is below:
$('#tabs').bind('tabsselect', function(event, ui) {
var callMethod;
      var tabSelected = "#tab" + ui.index + "Selected";
      if ($(tabSelected).text() == "") {                   
            switch (ui.index) {
                  case 0:
                        callMethod = "Default.aspx/GetCustomers";
                        break;
case 1:
                        callMethod = "Default.aspx/GetProducts";
                        break;
}
 
            $.ajax({
                  type: "POST",
                  url: callMethod,
                  data: "{}",
                  contentType: "application/json; charset=utf-8",
                  dataType: "json",
                  async: true,
                  success: function(msg) {
                        switch (ui.index) {
                              case 0:
                                    var customers = msg.d;
                                    for (var i = 0; i < customers.length; i++) {
                                        $("#tabs-0").append(customers[i].CustomerID + ", " +
                                                customers[i].CompanyName + ", " +
                                                customers[i].ContactName + ", " +
                                                customers[i].Address + ", " +
                                                customers[i].City + ", " +
                                                customers[i].Country + "<br />");
                                    }
                                    break;
                                case 1:
                                    var products = msg.d;
                                    for (var i = 0; i < products.length; i++) {
                                        $("#tabs-1").append(products[i].ProductID + ", " +
                                                products[i].ProductName + ", " +
                                                products[i].QuantityPerUnit + ", " +
                                                products[i].UnitPrice + ", " +
                                                products[i].UnitsInStock + ", " +
                                                products[i].Discontinued + "<br />");
                                    }
                                    break;
}
}
});
}
});
In the code above, the first step is to get the selected tab and locate the hidden field inside the tab. If the hidden field contains text, I know the data has been loaded for this tab previously, so don’t load it again:
var tabSelected = "#tab" + ui.index + "Selected";
      if ($(tabSelected).text() == "") {
}
The next step is to set which server side method is to be executed. This is determined by the tab selected:
switch (ui.index) {
case 0:
            callMethod = "Default.aspx/GetCustomers";
            break;
case 1:
            callMethod = "Default.aspx/GetProducts";
            break;
}
 
The next step uses jQuery’s Ajax function to execute the WebMethod. Once the method has finished executing the success function is called. The data is passed back in the msg.d property. The JSON returned can be viewed through Firebug if you’re using Firefox:
 
Firebug
The final step is to render the data in the browser. Visual Studio’s Intellisense won’t be able to find the properties returned, but you can type them in manually:
success: function(msg) {
switch (ui.index) {
            case 0:
                  var customers = msg.d;
                  for (var i = 0; i < customers.length; i++) {
                        $("#tabs-0").append(customers[i].CustomerID + ", " +
                        customers[i].CompanyName + ", " +
                        customers[i].ContactName + ", " +
                        customers[i].Address + ", " +
                        customers[i].City + ", " +
                        customers[i].Country + "<br />");
}
                  break;
case 1:
                  var products = msg.d;
                  for (var i = 0; i < products.length; i++) {
                        $("#tabs-1").append(products[i].ProductID + ", " +
                        products[i].ProductName + ", " +
                        products[i].QuantityPerUnit + ", " +
                        products[i].UnitPrice + ", " +
                        products[i].UnitsInStock + ", " +
                        products[i].Discontinued + "<br />");
}
                  break;
}
}

If you run the application now you’ll be able to select a tab, and the corresponding data will be returned from the database. You’ll also notice the code is executed once. This is a good way to add feature rich functionality to your page without drowning it in tonnes of server code.

The entire source code of this article can be downloaded over here

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Malcolm Sheridan is a Microsoft awarded MVP in ASP.NET, a Telerik Insider and a regular presenter at conferences and user groups throughout Australia and New Zealand. Being an ASP.NET guy, his focus is on web technologies and has been for the past 10 years. He loves working with ASP.NET MVC these days and also loves getting his hands dirty with jQuery and JavaScript. He also writes technical articles on ASP.NET for SitePoint and other various websites. Follow him on twitter @malcolmsheridan


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by Andi on Thursday, September 24, 2009 4:21 AM
Hi ! Nice article, but please note that the source code is not working 100%.
You should replace $(tabSelected).text() with $(tabSelected).attr("value") and $(tabSelected).html("isClicked"); with $(tabSelected).attr("value","isClicked");
At least this is how I got it working !
Comment posted by Malcolm Sheridan on Thursday, September 24, 2009 6:39 AM
@Andi
Thanks for the feedback.  This is a strange one because I just downloaded the code from the website and I didn't need to change anything.

Glad you enjoyed the article.
Comment posted by Rodel on Friday, September 25, 2009 12:48 AM
Nice article. Clear and simple.  I just downloaded the code as well and it worked just fine.
Comment posted by Jeff Morten on Saturday, September 26, 2009 3:11 AM
Nice demo
Comment posted by Malcolm Sheridan on Sunday, September 27, 2009 8:13 PM
@Rodel,@Jeff
I'm glad you enjoyed the article.
Comment posted by linxon on Saturday, October 17, 2009 2:43 PM
Great article, thanks!
Comment posted by Matt Juroch on Thursday, October 29, 2009 10:54 PM
Amazing article!
Comment posted by Eugene on Friday, October 30, 2009 2:34 AM
jQuery UI Tabs ALREADY supports loading tab content via Ajax in an unobtrusive manner.
Comment posted by Harman on Friday, October 30, 2009 1:12 PM
Thanks for the article and code. I enjoyed reading it.
Comment posted by Malcolm Sheridan on Saturday, November 7, 2009 4:26 AM
@Eugene
Yes that is true.  The difference is this article was about lazy loading the data.
Comment posted by Aman on Friday, August 20, 2010 12:52 PM
hi your tutorial is really helpful. I have also 15+ eyes Caching Jquery tabs please see here:-

http://jquery13.blogspot.com/2010/08/15-eyes-catching-jquery-tabs.html

Thanks
Aman
Comment posted by Anil on Monday, December 19, 2011 12:19 AM
Hi ! Nice article.It's working fine in Firefox browser, but while clicking on every tab giving an Error in Internet Explorer 7 says that "htmlfile: Unexpected call to method or property access.". After ignoring this error giving the result as normally.
Comment posted by Anil on Monday, December 19, 2011 2:41 AM
Hi ! Nice article.It's working fine in Firefox browser, but while clicking on every tab giving an Error in Internet Explorer 7 says that "htmlfile: Unexpected call to method or property access.". After ignoring this error giving the result as normally.
Comment posted by abc on Saturday, November 8, 2014 12:31 AM
jskd

Categories

JOIN OUR COMMUNITY

POPULAR ARTICLES

FREE .NET MAGAZINES

Free DNC .NET Magazine

Tags

JQUERY COOKBOOK

jQuery CookBook