Download source code - 87.4 KB
This article shows how the jQuery DataTables plug-in can be integrated into an ASP.NET MVC application. It contains step by step examples that show how the DataTables plug-in interacts with server-side components.
This article do not cover all possible integration scenarios of JQuery DataTables plugin in ASP.NET MVC application. For other integation scenarios, you might also take a look at the other articles in this serie:
As an example, if you apply JQuery DataTables plugin to this plain HTML table, you will get something like the table on the following figure:
The DataTables plug-in adds a "Show XXX entries" dropdown above the table enabling the user to choose whether he wants to see 10, 25, 50, or 100 records per page, and a search text box that enables the user to filter by keyword records that should be shown in the table. This plug-in also adds sorting functionality that enables the user to sort results by clicking on the column header. Below the table, there is pagination that enables the user to navigate through the pages and text that automatically displays which records are currently displayed. All these functionalities are added by default and all you need is a single line of code:
If you are interested in using the JQuery DataTables plugin in pure client-side mode, then you do not need to read this article. All you need to do is to generate a plain HTML table and apply plugin. You can use various configuration options in the plugin so if you are interested in this mode you might read the following article "Enhancing HTML tables using the jQuery DataTables plug-in" where I have explained various configuration options of DataTables plugin.
Theme of this article is using the JQuery DataTables plugin in the server-side processing mode.
Once the plug-in is applied on such of table, it will call the server side page (server_processing.php in the example above), post information about the required data, take the response from the server, and load the table data dinamically. The server response is formatted as a JSON object, parsed on the client side, and displayed in the table body. The following figure shows a trace of the calls sent to the server (captured using the Firebug add-in for Firefox).
In this case, each event (changing the number of items that should be displayed per page, entering a keyword in the search filter, sorting, pressing the pagination button, etc.) triggers the DataTables plug-in to send information about the current page, search filter, and sort column to the server page. As shown in the third request, the server page returns JSON as a result and DataTables uses that data array when displaying the current table page. In this mode, instead of taking the complete page at once, several smaller requests are sent whenever new information is required, and minimal amount of data is returned from the server. DataTables, in this example, calls the server_processing.php page and sends information about the user action. A dull example of the server-side configuration of the jQuery DataTables plug-in can be found here. A major problem with the server-side mode is the implementation of the server-side logic that accepts parameters from the client-side component, performs action, and returns the data as expected. This article explains how to configure jQuery DataTables and implement server-side logic with ASP.NET MVC controllers.
Loading data into the table
The first example of server-side processing implementation shown in this article is a response to the initial call. Immediately after initialization, DataTables sends the first call to the
In server-side processing mode, each time the user enters some text in the text box, DataTables sends a new AJAX request to the server-side expecting only those entries that match the filter. DataTables plugin sends the value entered in the filter text box in the
In multi-column filtering configuration, DataTables sends individual column filters to the server side in request parameters
Pagination
Another functionality that is added by the DataTables plug-in is the ability to perform paging on the displayed records. DataTables can add either Previous-Next buttons or standard paging numbers. also it enables you to change the number of the records that will be displayed per page using the drop-down. Drop-down and pagination links are shown on the following figure:
In server-side mode, each time the user clicks on a paging link, the DataTables plug-in sends information about the current page and the page size to a server-side URL that should process the request. The
Each time user clicks on the column, DataTables plugin sends information about the column and sort order direction (ascending or descending). To implement sorting,
This is directly implemented in the client-side mode; however, in the server-side processing mode you will need to implement logic that will order records by several columns it in the controlller.
When several columns are selected for sorting, for each column that should be sorted DataTables sends in the Ajax request pairs iSortCol_0, sSortDir_0, iSortCol_1, sSortDir_1, iSortCol_2, sSortDir_2, where each pair contains position of the column that should be ordered and sort direction. in the previous code samle i have used only iSortCol_0 and sSortDir_0, because I have assumed that only single column sorting is used.
Multi-column sorting code is similar to the code shown in the previous example but you will need to put several ordering functions for each column, and apply OrderBy().ThenBy().ThenBy() chain of functions. Due to the specific nature of this code and complexity I have not implemented it here. Note that if this is a requirement more easier solution would be to use dinamically generated SQL Query where you will concatenate these columns and sorting directions in the "ORDER BY" clause. Linq is great and clean code for presentation adn maintenence; howerer, in some situations where you need too much customization, you need to go to lower level functionalities.
A complete example with controller action where are merged all functionalities described in the article can be downloaded from the link above. This is a project created in Visual Web Developer 2010, and you will need to have installed ASP.NET MVC with Razor. If you are not using Razor, it is not a big problem - I recommend that you copy some files into your project (Controller, Model, JavaScript's) and modify them if needed.
This article is just a first part in the serie about using the JQuery DataTables plugin in ASP.NET applications. Other parts in this serie are:
Table of content
- Introduction
- Background
- Using the code
- Implementation of server-side service
- Summary
Introduction
The jQuery DataTables plug-in is an excellent client-side component that can be used to create rich-functional tables in the web browser. This plug-in adds lot of functionalities to the plain HTML tables that are placed in web pages such as filtering, paging, sorting, changing page length, etc.This article shows how the jQuery DataTables plug-in can be integrated into an ASP.NET MVC application. It contains step by step examples that show how the DataTables plug-in interacts with server-side components.
This article do not cover all possible integration scenarios of JQuery DataTables plugin in ASP.NET MVC application. For other integation scenarios, you might also take a look at the other articles in this serie:
- Part 2 - Implementation of CRUD functionalities (add, inline edit, delete) using DataTable in ASP.NET MVC where I have described how you can add data management (CRUD) functionalities such as adding, deleting and editing rows,
- Part 3 - Reloading content of data tables in ASP.NET MVC where I have shown how you can reload DataTable content using Ajax,
- Part 4 - Creating an expandable master-details table where I have shown how you can implement opening details row when regular row is selected,
- Part 5 - jQuery DataTables Advanced Filtering in ASP.NET MVC - in this article is shown how you can implement advanced filtering,
- Part 6 - Table Row Drag and Drop in ASP.NET MVC - in this article is descibed how you can use drag'n'drop row reordering.
Background
Currently there are several components that can help developers to create effective and functional-rich tables on the web pages. Some of them are server-side components such as standard ASP.NET GridView or other similar components that generate HTML code and attach events which postback a request to the server and where user actions are handled by the sever code and a new table is generated. The other group of components, such as jQuery DataTables, FlexGrid, or jqGrid are implemented as client-side code. These plugins take the plain HTML tables as the one shown on the following figure and add various enhancements.As an example, if you apply JQuery DataTables plugin to this plain HTML table, you will get something like the table on the following figure:
The DataTables plug-in adds a "Show XXX entries" dropdown above the table enabling the user to choose whether he wants to see 10, 25, 50, or 100 records per page, and a search text box that enables the user to filter by keyword records that should be shown in the table. This plug-in also adds sorting functionality that enables the user to sort results by clicking on the column header. Below the table, there is pagination that enables the user to navigate through the pages and text that automatically displays which records are currently displayed. All these functionalities are added by default and all you need is a single line of code:
Collapse | Copy Code
$('#myDataTable').dataTable();
Under assumption that the plain table shown on the first figure has an id "myDataTable", this code will enhance the table with DataTables plugin. Most of these functionalities can be used completely separate from the server-side code, i.e., the web server can generate a plain HTML table in standard format in any server-side technology such as ASP.NET Web Forms, ASP.NET MVC, PHP, Java etc. The client-side JavaScript components will use whatever gets generated and add client-side functionalities. In this client-side mode, DataTables takes all the table rows from the <tbody></tbody>
section and performs filtering, paging, and sorting directly on these elements as on in-memory objects. This is the fastest way to use DataTables but it requires that the server returns all the data in a single call, loads all these rows as in-memory JavaScript objects, and render them dynamically in DOM. This might cause performance issues with server calls and memory usage on the client. However, this minimizes the number of requests sent to the server because once the table is loaded, the server is not used at all. If you are interested in using the JQuery DataTables plugin in pure client-side mode, then you do not need to read this article. All you need to do is to generate a plain HTML table and apply plugin. You can use various configuration options in the plugin so if you are interested in this mode you might read the following article "Enhancing HTML tables using the jQuery DataTables plug-in" where I have explained various configuration options of DataTables plugin.
Theme of this article is using the JQuery DataTables plugin in the server-side processing mode.
DataTables Server-side processing mode
It is possible to implement client-server interaction by configuring DataTables to query the server via AJAX calls in order to fetch the required data. In this case, table that is generated on the client side is initially empty as the one shown in the following example:
Collapse | Copy Code
<table id="myDataTable" class="display">
<thead>
<tr>
<th>ID</th>
<th>Company name</th>
<th>Address</th>
<th>Town</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
As you might notice, this "table" do not have any rows in it. In order to apply the plugin to this "table" you will need to call something like a following code:
Collapse | Copy Code
$('#myDataTable').dataTable({
"bServerSide": true,
"sAjaxSource": "server_processing.php"
});
In this code is used the server-side processing mode by setting the bServerSide
parameter to true. In this mode, DataTables plugin will load table data from the remote URL using the Ajax request. The second parameter defines to what URL DataTables plugin should send Ajax request in order to load the data into the table. Once the plug-in is applied on such of table, it will call the server side page (server_processing.php in the example above), post information about the required data, take the response from the server, and load the table data dinamically. The server response is formatted as a JSON object, parsed on the client side, and displayed in the table body. The following figure shows a trace of the calls sent to the server (captured using the Firebug add-in for Firefox).
In this case, each event (changing the number of items that should be displayed per page, entering a keyword in the search filter, sorting, pressing the pagination button, etc.) triggers the DataTables plug-in to send information about the current page, search filter, and sort column to the server page. As shown in the third request, the server page returns JSON as a result and DataTables uses that data array when displaying the current table page. In this mode, instead of taking the complete page at once, several smaller requests are sent whenever new information is required, and minimal amount of data is returned from the server. DataTables, in this example, calls the server_processing.php page and sends information about the user action. A dull example of the server-side configuration of the jQuery DataTables plug-in can be found here. A major problem with the server-side mode is the implementation of the server-side logic that accepts parameters from the client-side component, performs action, and returns the data as expected. This article explains how to configure jQuery DataTables and implement server-side logic with ASP.NET MVC controllers.
Using the code
The first thing you need to do is to create a standard ASP.NET Model-View-Controller structure. There are three steps required for this setup:- Creating the model classes that represent the data structure that will be shown
- Creating the controller class that will react on the user events
- Creating the view that will render data and create the HTML code that is sent to the browser window
- jQuery library containing the standard classes used by the DataTables plug-in
- jQuery DataTables plug-in including optional DataTables CSS style-sheets used for applying the default styles on the page
Model
The Model comes to a simple class containing company data. The fields that we need are company ID, name, address, and town. The source code of the company model class is shown below:
Collapse | Copy Code
public class Company
{
public int ID { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Town { get; set; }
}
View
Since the data presentation is done on the client-side, the classic View page is fairly simple. It contains a simple HTML table "decorated" with the jQuery DataTables plug-in. For example:
Collapse | Copy Code
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>jQuery DataTables/ASP.NET MVC Integration</title>
<link href="~/Content/dataTables/demo_table.css"
rel="stylesheet" type="text/css" />
<script src="~/Scripts/jQuery-1.4.4.min.js"
type="text/javascript"></script>
<script src="~/Scripts/jQuery.dataTables.min.js"
type="text/javascript"></script>
<script src="~/Scripts/index.js"
type="text/javascript"></script>
</head>
<body>
<div id="container">
<div id="demo">
<h2>Index</h2>
<table id="myDataTable" class="display">
<thead>
<tr>
<th>ID</th>
<th>Company name</th>
<th>Address</th>
<th>Town</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</body>
</html>
The view engine used is Razor but any other view engine can be used instead, as the engine specific code is only setting the layout page on the top of the page. The page includes all the necessary JavaScript libraries and renders an empty table. Data that should be displayed is not bound on the server-side. Therefore, the table body is not needed as data is going to be pulled from the server. In client side mode, the <tbody></tbody>
section would contain rows that should be displayed on the page. However, in server-side mode, data is dynamically taken via AJAX calls. Since all processing and display is done on the client-side in the browser, the usage of the server-side template engine is irrelevant. However, in a real situation, if we should bind some dynamic data on the server-side, we could use any MVC template engine such as ASPX, Razor, Spark, or NHaml. The View includes the standard jQuery and DataTables libraries required to initialize a table, as well as the standard DataTables CSS file which can be replaced with any custom style-sheet. Code that initializes the DataTables plugin should be placed in the included index.js file as shown below:
Collapse | Copy Code
$(document).ready(function () {
$('#myDataTable').dataTable({
"bServerSide": true,
"sAjaxSource": "Home/AjaxHandler",
"bProcessing": true,
"aoColumns": [
{ "sName": "ID",
"bSearchable": false,
"bSortable": false,
"fnRender": function (oObj) {
return '<a href=\"Details/' +
oObj.aData[0] + '\">View</a>';
}
},
{ "sName": "COMPANY_NAME" },
{ "sName": "ADDRESS" },
{ "sName": "TOWN" }
]
});
});
The initialization code is placed in the standard jQuery document ready wrapper. It finds the table with the myDataTable
ID and the magic begins. By setting the bServerSide
parameter to true
, DataTables is initialized to work with the server-side page. Another parameter, sAjaxSource
, should point to an arbitrary URL of the page that will provide data to client-side table ("Home/AjaxHandler" in this example). The parameter bProcessing
tells DataTables to show the "Processing..." message while the data is being fetched from the server, while aoColumns
defines the properties of the table columns (e.g., whether they can be used for sorting or filtering, whether some custom function should be applied on each cell when it is rendered etc. - more information about DataTables properties can be found on the DataTables site) and it is not directly related to the client-server setup of DataTables.Controller
Since there is no server-side processing, the controller class is also fairly simple and it practically does nothing. The controller class used in the example is shown below:
Collapse | Copy Code
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
As shown in the snippet, the controller just waits for someone to call the "Home/Index" URL and forwards the request to the Index view. All data processing is done in the Home/AjaxHandler controller action.Implementation of server-side service
Once the table has been initialized, it is necessary to implement server-side logic that will provide data to DataTables. The server-side service will be called (by jQuery DataTables) each time data should be displayed. Since the DataTables configuration declared "Home/AjaxHandler" as URL that should be used for providing data to the DataTable, we need to implement an AjaxHandler action in the Home controller that will react to the Home/AjaxHandler calls. For example:
Collapse | Copy Code
public class HomeController : Controller
{
public ActionResult AjaxHandler(jQueryDataTableParamModel param)
{
return Json(new{
sEcho = param.sEcho,
iTotalRecords = 97,
iTotalDisplayRecords = 3,
aaData = new List<string[]>() {
new string[] {"1", "Microsoft", "Redmond", "USA"},
new string[] {"2", "Google", "Mountain View", "USA"},
new string[] {"3", "Gowi", "Pancevo", "Serbia"}
}
},
JsonRequestBehavior.AllowGet);
}
}
The Action method returns a dummy 3x4 array that simulates information expected by the DataTable plug-in, i.e., the JSON data containing the number of total records, the number of records that should be displayed, and a two dimensional matrix representing the table cells. For example:
Collapse | Copy Code
{ "sEcho":"1",
"iTotalRecords":97,
"iTotalDisplayRecords":3,
"aaData":[ ["1","Microsoft","Redmond","USA"],
["2","Google","Mountain View","USA"],
["3","Gowi","Pancevo","Serbia"]
]
}
Values that the server returns to the DataTables plug-in are:sEcho
- the integer value that is used by DataTables for synchronization purpose. On each call sent to the server-side page, the DataTables plug-in sends the sequence number in thesEcho
parameter. The same value has to be returned in response because DataTables uses this for synchronization and matching requests and responses.iTotalRecords
- the integer value that represents the total unfiltered number of records that exist on the server-side and that might be displayed if no filter is applied. This value is used only for display purposes; when then user types in some keyword in a search text box, DataTables shows a "Showing 1 to 10 of 23 entries (filtered from 51 total entries)" message. In this case, theiTotalRecords
value returned in response equals 51.iTotalDisplayedRecords
- The integer value that represents the number of records that match the current filter. If the user does not enter any value in the search text box, this value should be the same as theiTotalRecords
value. The DataTables plug-in uses this value to determine how many pages will be required to generate pagination - if this value is less or equal than the current page size, pagination buttons will be disabled. When the user types in some keyword in the search text box, DataTables shows "Showing 1 to 10 of 23 entries (filtered from 51 total entries)" message. In this case, theiTotalDisplayedRecords
value returned in the response equals 23.aaData
- the two-dimensional array that represents the cell values that will be shown in the table. When DataTables receives data, it will populate the table cells with values from theaaData
array. The number of columns in the two dimensional array must match the number of columns in the HTML table (even the hidden ones) and the number of rows should be equal to the number of items that can be shown on the current page (e.g., 10, 25, 50, or 100 - this value is selected in the "Show XXX entries" dropdown).
Request
object as in standard ASP.NET, but in this example, they are encapsulated in the JQueryDataTableParamModel
class given below.
Collapse | Copy Code
/// <summary>
/// Class that encapsulates most common parameters sent by DataTables plugin
/// </summary>
public class jQueryDataTableParamModel
{
/// <summary>
/// Request sequence number sent by DataTable,
/// same value must be returned in response
/// </summary>
public string sEcho{ get; set; }
/// <summary>
/// Text used for filtering
/// </summary>
public string sSearch{ get; set; }
/// <summary>
/// Number of records that should be shown in table
/// </summary>
public int iDisplayLength{ get; set; }
/// <summary>
/// First record that should be shown(used for paging)
/// </summary>
public int iDisplayStart{ get; set; }
/// <summary>
/// Number of columns in table
/// </summary>
public int iColumns{ get; set; }
/// <summary>
/// Number of columns that are used in sorting
/// </summary>
public int iSortingCols{ get; set; }
/// <summary>
/// Comma separated list of column names
/// </summary>
public string sColumns{ get; set; }
}
The DataTables plug-in may send some additional parameters, but for most purposes, the mentioned parameters should be enough.Loading data into the table
The first example of server-side processing implementation shown in this article is a response to the initial call. Immediately after initialization, DataTables sends the first call to the
sAjaxSource
URL and shows the JSON data returned by that page. The implementation of the method that returns the data needed for initial table population is shown below:
Collapse | Copy Code
public ActionResult AjaxHandler(jQueryDataTableParamModel param)
{
var allCompanies = DataRepository.GetCompanies();
var result = from c in allCompanies
select new[] { c.Name, c.Address, c.Town };
return Json(new { sEcho = param.sEcho,
iTotalRecords = allCompanies.Count(),
iTotalDisplayRecords = allCompanies.Count(),
aaData = result
},
JsonRequestBehavior.AllowGet);
}
The list of all companies is fetched from the repository; they are formatted as a two-dimensional matrix containing the cells that should be shown in the table, and sent as a JSON object. The parameters iTotalRecords
and iTotalDisplayRecords
are equal to the number of companies in the list as this is the number of records that should be shown and the number of total records in a data set. The only parameter used from the request object is sEcho
, and it is just returned back to DataTables. Although this server action is good enough to display initial data, it does not handle other data table operations such as filtering, ordering, and paging.Filtering records
DataTables plugin adds a text box in the table, so the user can filter the results displayed in the table by entering a keyword. Text box used for filtering is shown on the following figure:sSearch
HTTP request parameter. In order to handle the user request for filtering, AjaxHandler
must be slightly modified, as it is shown in the following listing:
Collapse | Copy Code
public ActionResult AjaxHandler(jQueryDataTableParamModel param)
{
var allCompanies = DataRepository.GetCompanies();
IEnumerable<Company> filteredCompanies;
if (!string.IsNullOrEmpty(param.sSearch))
{
filteredCompanies = DataRepository.GetCompanies()
.Where(c => c.Name.Contains(param.sSearch)
||
c.Address.Contains(param.sSearch)
||
c.Town.Contains(param.sSearch));
}
else
{
filteredCompanies = allCompanies;
}
var displayedCompanies = filteredCompanies;
var result = from c in displayedCompanies
select new[] { Convert.ToString(c.ID), c.Name, c.Address, c.Town };
return Json(new{ sEcho = param.sEcho,
iTotalRecords = allCompanies.Count(),
iTotalDisplayRecords = filteredCompanies.Count(),
aaData = result},
JsonRequestBehavior.AllowGet);
In the given example, we use a LINQ query to filter the list of companies by the param.sSearch
value. DataTables plugin sends the keyword entered in the text box in the sSearch parameter. The filtered companies are returned as JSON results. The number of all records and the records that should be displayed are returned as well.Multi-column filtering
DataTables can use multiple column based filters instead of a single filter that is applied on the whole table. Detailed instructions for setting a multi-column filter can be found on the DataTables site (multi-filtering example). When multi-column filtering is used, in the table footer are added separate text boxes for filtering each individual columns, as it is shown on the following figure:In multi-column filtering configuration, DataTables sends individual column filters to the server side in request parameters
sSearch_0
, sSearch_1
, etc. The number of request variables is equal to the iColumns
variable. Also, instead of the param.sSearch
value, you may use particular values for columns as shown in the example:
Collapse | Copy Code
//Used if particular columns are separately filtered
var nameFilter = Convert.ToString(Request["sSearch_1"]);
var addressFilter = Convert.ToString(Request["sSearch_2"]);
var townFilter = Convert.ToString(Request["sSearch_3"]);
DataTables initialization settings could specify whether a column is searchable or not (the ID column is not searchable in the previous example). DataTables also sends additional parameters to the server-side page so server side component can determine which fields are searchable at all. In the configuration used in this article, DataTables sends the individual column filters to server as request parameters (bSearchable_0
, bSearchable_1
, etc). The number of request variables is equal to the iColumns
variable.
Collapse | Copy Code
//Optionally check whether the columns are searchable at all
var isIDSearchable = Convert.ToBoolean(Request["bSearchable_0"]);
var isNameSearchable = Convert.ToBoolean(Request["bSearchable_1"]);
var isAddressSearchable = Convert.ToBoolean(Request["bSearchable_2"]);
var isTownSearchable = Convert.ToBoolean(Request["bSearchable_3"]);
The example configuration used in this article has the isIDSearchable
variable set to false
, while other variables are set to true
. Values that are sent to the server depend on the aoColumns
setting in the database initialization function. The problem with server-side filtering might be a big number of AJAX requests sent to the server. The DataTables plug-in sends a new AJAX request to the server each time the user changes a search keyword (e.g., types or deletes any character). This might be a problem since the server needs to process more requests although only some of them will really be used. Therefore, it would be good to implement some delay function where the request will be sent only after some delay (there is an example of the fnSetFilteringDelay
function on the DataTables site).Pagination
Another functionality that is added by the DataTables plug-in is the ability to perform paging on the displayed records. DataTables can add either Previous-Next buttons or standard paging numbers. also it enables you to change the number of the records that will be displayed per page using the drop-down. Drop-down and pagination links are shown on the following figure:
In server-side mode, each time the user clicks on a paging link, the DataTables plug-in sends information about the current page and the page size to a server-side URL that should process the request. The
AjaxHandler
method that processes paging should be modified to use information sent in the request as shown in the example:
Collapse | Copy Code
public ActionResult AjaxHandler(jQueryDataTableParamModel param)
{
var allCompanies = DataRepository.GetCompanies();
IEnumerable<Company> filteredCompanies = allCompanies;
var displayedCompanies = filteredCompanies
.Skip(param.iDisplayStart)
.Take(param.iDisplayLength);
var result = from c in displayedCompanies
select new[] { Convert.ToString(c.ID), c.Name,
c.Address, c.Town };
return Json(new{ sEcho = param.sEcho,
iTotalRecords = allCompanies.Count(),
iTotalDisplayRecords = filteredCompanies.Count(),
aaData = result},
JsonRequestBehavior.AllowGet);
}
This example is similar to the previous one, but here we use the param.iDisplayStart
and param.IDisplayLength
parameters. These are integer values representing the starting index of the record that should be shown and the number of results that should be returned.Sorting
The last functionality that will be explained in this article is sorting results by column. The DataTables plug-in adds event handlers in HTML columns so the user that can order results by any column. DataTables supports multi-column sorting too, enabling user to order results by several columns, pressing the SHIFT key while clicking on the columns. DataTables adds event handlers to the column heading cells with direction arrows as it is shown on the following figure:Each time user clicks on the column, DataTables plugin sends information about the column and sort order direction (ascending or descending). To implement sorting,
AjaxHandler
should be modified to use information about the column that should be used for ordering, as shown in the example:
Collapse | Copy Code
public ActionResult AjaxHandler(jQueryDataTableParamModel param)
{
var allCompanies = DataRepository.GetCompanies();
IEnumerable<Company> filteredCompanies = allCompanies;
var sortColumnIndex = Convert.ToInt32(Request["iSortCol_0"]);
Func<Company, string> orderingFunction = (c => sortColumnIndex == 1 ? c.Name :
sortColumnIndex == 2 ? c.Address :
c.Town);
var sortDirection = Request["sSortDir_0"]; // asc or desc
if (sortDirection == "asc")
filteredCompanies = filteredCompanies.OrderBy(orderingFunction);
else
filteredCompanies = filteredCompanies.OrderByDescending(orderingFunction);
var displayedCompanies = filteredCompanies;
var result = from c in displayedCompanies
select new[] { Convert.ToString(c.ID), c.Name, c.Address, c.Town };
return Json(new
{
sEcho = param.sEcho,
iTotalRecords = allCompanies.Count(),
iTotalDisplayRecords = filteredCompanies.Count(),
aaData = result
},
JsonRequestBehavior.AllowGet);
There is an assumption that the server-side knows which fields are sortable. However, if this information is not known or it can be dynamically configured, DataTables sends all the necessary information in each request. Columns that are sortable are sent in an array of request parameters called bSortable_0
, bSortable_1
, bSortable_2
, etc. The number of parameters is equal to the number of columns that can be used for sorting which is also sent in the iSortingCols
parameter. In this case, the name, address, and town might be sortable on the client side, so the following code determines whether they are actually sortable or not:
Collapse | Copy Code
var isNameSortable = Convert.ToBoolean(Request["bSortable_1"]);
var isAddressSortable = Convert.ToBoolean(Request["bSortable_2"]);
var isTownSortable = Convert.ToBoolean(Request["bSortable_3"]);
These variables can be added in the conditions of the ordering function, creating a configurable sort functionality.Multi-column sorting
DataTables plugin enables multicolumn sorting by defualt. If you hold SHIFT key and click on several heading column cells, table will be ordered by first column then by second etc. On the following figure is shown how rows in the table are sorted by the first three columns at the same time.This is directly implemented in the client-side mode; however, in the server-side processing mode you will need to implement logic that will order records by several columns it in the controlller.
When several columns are selected for sorting, for each column that should be sorted DataTables sends in the Ajax request pairs iSortCol_0, sSortDir_0, iSortCol_1, sSortDir_1, iSortCol_2, sSortDir_2, where each pair contains position of the column that should be ordered and sort direction. in the previous code samle i have used only iSortCol_0 and sSortDir_0, because I have assumed that only single column sorting is used.
Multi-column sorting code is similar to the code shown in the previous example but you will need to put several ordering functions for each column, and apply OrderBy().ThenBy().ThenBy() chain of functions. Due to the specific nature of this code and complexity I have not implemented it here. Note that if this is a requirement more easier solution would be to use dinamically generated SQL Query where you will concatenate these columns and sorting directions in the "ORDER BY" clause. Linq is great and clean code for presentation adn maintenence; howerer, in some situations where you need too much customization, you need to go to lower level functionalities.
Summary
This article represents a step-by-step guideline for integrating the jQuery DataTables plug-in into server-side code. It shows how the standard DataTables plug-in that, by default, works with client-side data can be configured to take all the necessary data from the server via AJAX calls. The server-side code used in this example is a pure LINQ query set performed on an in-memory collection of objects. However, in a real application, we should use some data access components such as Linq2Sql, Entity Framework, Stored Procedures, WCF services, or any other code that takes data and performs sorting, paging, and filtering. As these data access samples are out of the scope of this article, they are not used in the example.A complete example with controller action where are merged all functionalities described in the article can be downloaded from the link above. This is a project created in Visual Web Developer 2010, and you will need to have installed ASP.NET MVC with Razor. If you are not using Razor, it is not a big problem - I recommend that you copy some files into your project (Controller, Model, JavaScript's) and modify them if needed.
This article is just a first part in the serie about using the JQuery DataTables plugin in ASP.NET applications. Other parts in this serie are:
- Part 2 - Implementation of an editable DataTable in ASP.NET MVC where I have described how you can add data management (CRUD) functionalities such as adding, deleting and editing rows,
- Part 3 - Reloading content of data tables in ASP.NET MVC where I have shown how you can reload DataTable content using Ajax,
- Part 4 - Creating an expandable master-details table where I have shown how you can implement opening details row when regular row is selected,
- Part 5 - jQuery DataTables Advanced Filtering in ASP.NET MVC - in this article is shown how you can implement advanced filtering,
- Part 6 - Table Row Drag and Drop in ASP.NET MVC - in this article is descibed how you can use drag'n'drop row reordering.
- Enhancing HTML tables using the jQuery DataTables plug-in where I have explained various configuration options of DataTables plugin,
- JQuery Data Tables in Java Web Applications - article similar to this one showing implementation in Java.
0 comments:
Post a Comment