Introduction
In a previous article, I was exploring a way to push JSON data from an SQL DataTable
to a browser. There are of course, many other ways to generate tabular JSON data, including Entity Framework collections. When it comes to the display and client side processing of this data, however I didn't find plenty of available controls and the ones that I found were quite heavy.
So I decided to play around with JavaScript and try to come up with something that I hope may be of some use to someone.
Background
This first attempt at developing a small GridView
like control doesn't rely heavily on jQuery and is not a plugin. It is a simple JavaScript object that uses some jQuery functions here and there. I realize that this presents a limitation when it comes to nesting of multiple controls, so sometime in the future, I will probably play around with a jQuery plugin that implements the same functionality.
Using the Code
The server side code is the same as in the previous article: Simple Way of Using SQL DataTables to JSON in MVC and its purpose is to generate some JSON formatted data from a hardcoded sample DataTable
and to send it to the browser.
The server side control looks like this:
public JsonResult GetJsonPersons()
{
ViewModels.DataAccessLayer oDAL = new ViewModels.DataAccessLayer();
DataTable dtPersons = oDAL.GetTable();
List<Dictionary<string, object>> lstPersons = oDAL.GetTableRows(dtPersons);
return Json(lstPersons, JsonRequestBehavior.AllowGet);
}
The client side includes some JavaScript include objects:
- jquery-1.10.2.min.js - the jQuery Library
- gridview.js - the JavaScript object, described here
- bpopup.js - a small jQuery plugin for modal pop-ups developed by Bjoern Klinggaard, that is used by a callback function in case you want to use HyperLinks in a
GridView
column, more about that below.
The HTML body
includes only two div
elements that are the root elements used by the GridView
and the modal pop-up:
<body >
<div id="Grid1_"></div>
<div id="Grid1_PopUp"></div>
</body >
The GridView
object works by using a root element, passed to it, generates and adds the elements of an HTML table as childElement
s to it. It generates and populates a header row either with the field names of the JSON object, or it would use a configuration JSON object if one is provided. It populates the cell elements with the data from the JSON object and generates a navigation set of links, depending on the selected page number.
The initialization of a GridView
object is done with the following code:
function getPersons() {
try {
$.getJSON("/CPArticle1/GetJsonPersons", null, function (data) {
try {
var dtPersons = eval(data);
window.oGridView = new GridView("Grid1_"); .
oGridView.jsonConfig = Grid1_Layout;
oGridView.dataTable = dtPersons;
oGridView.displayPage();
}
catch (ex1) {
alert(ex1);
}
});
}
catch (ex) {
alert(ex);
}
}
window.oGridView = new GridView("Grid1_");
- initializes the GridView
object by passing the id
of the root div
element Grid1_
, that is placed in the HTML body.
oGridView.jsonConfig = Grid1_Layout;
- assigns a JSON configuration object, that will be described below. If you comment out this line, GridView
will parse and display all of the JSON data columns and will populate the header with the names of the data fields as they are in the JSON data object dtPersons
.
oGridView.dataTable = dtPersons;
- assigns the JSON data object to be displayed.
oGridView.displayPage();
- starts the display.
The optional grid layout JSON object allows customization of the GridView
columns:
var Grid1_Layout = [{
"DataField": "UserID",
"HeaderText": "User ID",
"Width": "100px",
"HyperLinkField": showPopUp
},
{
"DataField": "FirstName",
"HeaderText": "First Name",
"Width": "150px"
},
{
"DataField": "LastName",
"HeaderText": "Last Name",
"Width": "150px"
},
{
"DataField": "DateJoined",
"HeaderText": "Date Joined",
"Width": "150px"
}
]
"DataField": "UserID"
- specifies the data field name of column 1, as it is in the data object dtPersons
. The field name has to exist in the JSON data object. "HeaderText": "User ID"
- appears in the Header of the first column "Width": "100px"
- column with, please note that it is text with px
at the end and not a number. "HyperLinkField": showPopUp
- optional field. If you wish to link a GridView
column with a callback function, you can specify it here. GridView
will add a link to this column, the click
event of this link will be wired to the specified function (showPopUp
) and the function will receive as parameter the whole JSON data record from the clicked row.
In this example, the function will display a modal pop up with the row data, passed to it:
function showPopUp(dataRow) {
var oPopUp = new popUp("Grid1_PopUp");
oPopUp.jsonConfig = Grid1_Layout;
oPopUp.jsonData = dataRow;
oPopUp.Show();
}
It is important to notice the dataRow
parameter that you have to specify in the external callback function. It will receive the row data from the JSON data object.
The appearance of the GridView
object can be customized entirely through CSS classes:
.Grid1_Table {
border: 1px solid black; border-spacing: 0px;
}
.Grid1_HeaderRow {
border: 1px solid black;
font-weight: bold; font-size: 15px; color: #FFFFFF;
height: 35px; background-color: #777777;
}
.Grid1_HeaderCell {
border: 1px solid black; padding: 3px;
text-overflow: ellipsis; overflow: hidden;
white-space: nowrap; text-align: center;
}
.Grid1_Row {
height: 35px;
}
.Grid1_Row:nth-child(odd) {
background-color: #DDDDDD;
}
.Grid1_Cell {
border: 1px solid #777777; padding: 5px; text-align: center;
}
.Grid1_FooterRow {
height: 40px;
}
.Grid1_NavigationLink {
display: inline-block; text-decoration: none; text-align: center; width: 18px;
padding: 5px; font-size: 16px; color: #444444;
}
.Grid1_NavigationLink:hover {
background-color: #888888; color: #FFFFFF; border-radius: 4px;
}
.Grid1_NavigationCurrentPage {
display: inline-block;
width: 18px; padding: 5px;
font-size: 16px; text-decoration: none; text-align: center;
background-color: #444444; color: #FFFFFF; border-radius: 4px;
}
.Grid1_CellLink {
color: black;
padding: 5px;
}
.Grid1_CellLink:hover {
background-color: #888888; color: #FFFFFF; border-radius: 4px;
}
#Grid1_Error {
position: absolute; top: 10px; left: 50px; background-color: Red;
padding: 3px; color: white; display: none;
}
As you can see, the convention is to take the ID of the root element and to add some additional text to it. If you pass to the GridView
a root element with the ID "AnotherRootElement_
", the classes you specify have to look like this: .AnotherRootElement_HeaderRow
or .AnotherRootElement_NavigationLink
.
.Grid1_HeaderRow
or rootElementIDHeaderRow
is setting the properties of the table header row .Grid1_HeaderCell
- the properties of the header columns .Grid1_Row
and .Grid1_Row:nth-child(odd)
- allows you to specify the properties of the grid rows .Grid1_CellLink
- specifies the properties of a link column if you specified one in the JSON configuration object.
Points of Interest
The GridView
- like object described here is only 300 lines of code, and that with generous formatting. It is quite lightweight and was tested with real data tables with the size of several thousand rows and about a hundred columns. It performed lightning fast during the tests.
It was tested with the latest versions of Internet Explorer, Chrome and Firefox. Not sure how old browsers will handle it though. There will be another version with heavy usage of jQuery that will be made as plugin.