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.
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:
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:
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
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
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