Introduction
Before explaining the article, I would like to thank all readers who read my article and voted for it. Your appreciation for my article gives me strength to write more good articles. Hope in future I will get your valuable comments and suggestions. Now I won't waste your time and come back to the topic. I have written this article on ‘Ajax Enabled Gridview Using JavaScript in ASP.NET’. In this article, I will show you how to make a Gridview using a simple HTML table, JavaScript and XML HTTP for Ajax call without using any ASP.NET control.
Using Code
Using this JavaScript Gridview, you can do normal operations like gridview as displaying data in tabular format, viewing records from page to page, sorting data at runtime without any postback. Besides this, you can delete records and set page size.
We will cover this article in the following sections:
- Requesting for data from data source.
- Binding Gridview with data or creating HTML table to show data in tabular format.
- Creating pager.
- Setting pager size at runtime.
- Deleting records from grid.
Now let's get started with step 1.
1. Requesting for Data from Data Source
I have used a default.aspx page to show a grid on that page. When the page is loaded, a JavaScript function fnFillGrid()
is called on the onload
event of the body
tag.
function fnFillGrid()
{
GetResponse('HandleRequest.ashx?RequestType=ShowCart' ,GetCartResponse)
}
Function fnFillGrid()
itself calls a GetResponse()
function that has two parameters, a URL and a function to carry the response. An asynchronous call is made to get the send request and get response from the server.
function GetResponse(url, Response)
{
if(navigator.appName == "Microsoft Internet Explorer")
{
var xhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
else
{
var xhttp = new XMLHttpRequest();
}
xhttp.open("GET", url, true);
xhttp.onreadystatechange =
function()
{
if (xhttp.readyState == 4 && xhttp.responseText)
{
validateResponse(xhttp);
Response(xhttp.responseXML);
}
}
xhttp.send(null);
}
In the URL parameter, you will see a generic handler file, named handlerequest.ashx. The request goes to the server for this file with a querystring RequestType
, which determines what type of request to process at the server.
From web server, the response comes in XML format.
Here I will show you how the server processes the request and sends a response in XML format.
When a request for handlerequest.ashx goes to the web server, a function is called ProcessRequest()
. In the ProcessRequest
function, I have declared an XmlTextWriter
XML object. And using this XML object, an XML file in the memory is created and sent as response.
XmlTextWriter xml = new XmlTextWriter(context.Response.Output);
xml.WriteStartElement("Root");
To make an XML file, three functions of XmlTextWritter
are used:
WriteStartElement(NodeName)
WriteElementstring()
WriteEndElement()
The WriteStartElement
function is used to make the begin of root
element of the XML file and WriteElementString()
is used to make child elements of the Root
element. And finally WriteendElement()
is used to close the tag of the Root
element.
The structure of the XML file will be in the following format:
<Root>
<Product>…….</Product>
<ProductId>…….</ProductId>
…………………………………………….
……………………………..………………
</Root>
Now a dataset is used to read data from an XML file cart.xml which is stored at App_Data folder of the application folder.
After reading data from the data source, the records are inserted as child of the Root
element in between the <Root>
tag and then it is sent as response.
DataSet DS = new DataSet();
DS.ReadXml(HttpContext.Current.ApplicationInstance.Server.MapPath
("~/App_Data/Cart.xml"));
double TotalMRP=0;
double TotalDiscount=0;
double GrantTotal=0;
if(DS.Tables.Count>0)
foreach (DataRow dr in DS.Tables[0].Rows)
{
double PriceTotal =Convert.ToDouble(dr["MRP"].ToString()) -
Convert.ToDouble(dr["Discount"].ToString());
PriceTotal *= Convert.ToDouble(dr["Qty"].ToString());
TotalMRP += Convert.ToDouble(dr["MRP"].ToString());
GrantTotal += PriceTotal;
TotalDiscount += Convert.ToDouble(dr["Discount"].ToString());
xml.WriteStartElement("Product");
xml.WriteElementString("ProductId", dr["ProductId"].ToString());
xml.WriteElementString("ProductName", dr["ProductName"].ToString());
xml.WriteElementString("Category", dr["Category"].ToString());
xml.WriteElementString("MRP", dr["MRP"].ToString());
xml.WriteElementString("Discount", dr["Discount"].ToString());
xml.WriteElementString("Qty", dr["Qty"].ToString());
xml.WriteElementString("PriceTotal", PriceTotal.ToString());
xml.WriteElementString("TotalMRP", TotalMRP.ToString());
xml.WriteElementString("TotalDiscount", TotalDiscount.ToString());
xml.WriteElementString("GrantTotal", GrantTotal.ToString());
xml.WriteEndElement();
}
Now the response goes to the browser.
In step 2, I will show you how this response data is binded with the Grid.
2. Binding Gridview with Data
As we know, the response is sent in XML format so the data is retrieved tag wise and stored in respective arrays. These arrays are processed later to form grid data.
var ProductNameList = XML.getElementsByTagName('ProductName');
var ProductIdList = XML.getElementsByTagName('ProductId');
var MRPList = XML.getElementsByTagName('MRP');
var DiscountList = XML.getElementsByTagName('Discount');
var CategoryList = XML.getElementsByTagName('Category');
var QtyList = XML.getElementsByTagName('Qty');
var PriceTotalList= XML.getElementsByTagName('PriceTotal');
var TotalMRPList= XML.getElementsByTagName('TotalMRP');
var TotalDiscountList= XML.getElementsByTagName('TotalDiscount');
var GrantTotalList= XML.getElementsByTagName('GrantTotal');
Now the items of the Grid are created here:
strTable = strTable + '<tr class="gvHeader" >';
strTable = strTable + ' <td style=width:8% align=center>';
strTable = strTable + ' Delete' ;
strTable = strTable + ' </td>';
strTable = strTable + ' <td style=width:30% class=gvHeader align=center>';
strTable = strTable + ' Product Name';
strTable = strTable + ' </td>';
strTable = strTable + ' <td style=width:24% class=gvHeader align=center>';
strTable = strTable + ' Category';
strTable = strTable + ' </td>';
strTable = strTable + ' <td style=width:10% class=gvHeader align=center>';
strTable = strTable + ' MRP';
strTable = strTable + ' </td>';
strTable = strTable + ' <td style=width:10% class=gvHeader align=center>';
strTable = strTable + ' Discount';
strTable = strTable + ' </td>';
strTable = strTable + ' <td style=width:8% class=gvHeader align=center>';
strTable = strTable + ' Quantity';
strTable = strTable + ' </td>';
strTable = strTable + ' <td style=width:10% class=gvHeader align=center >';
strTable = strTable + ' Total';
strTable = strTable + ' </td>';
strTable = strTable + '</tr>';
After creating the table, it is assigned to a div gvCart
as innerHTML
.
Now we have a JavaScript Gridview.
3. Creating Pager
To create a pager, I have used a default page size of 3
. Number of pages are determined by dividing length of the array of ProductIdList
by page size. With every page, we have an onclick
event that is fired when the user clicks on the page number.
To make a page number link, we have this code.
for(var pageCount=1 ; pageCount<=Math.ceil(ProductIdList.length/PageSize);pageCount++)
{
Pagelink= Pagelink + '<a href=javascript:void(0)
onclick=javacsript:PageIndexChanging('+ (pageCount-1) + ');
id=a_'+ pageCount+'> ' + (pageCount) + '</a>'
}
When the user changes the page, a function PageIndexChanging
is called and there we change the page content.
Here I have not sent any request for the page data. I have just made the page row hidden or unhidden, i.e. when the user changes page number from 1 to 2, all the rows that come in page 2 are made unhidden and all rows of the rest of the pages are made hidden.
The following code does this:
var arrProduct;
arrProduct = document.getElementsByName('chkSelect');
for (var i=0; i< arrProduct.length ; i++)
{
if(i >=(PageNo*PageSize) && i < (PageNo+1)*PageSize)
document.getElementById('trSelect'+i).style.display=''
else
document.getElementById('trSelect'+i).style.display='none'
}
In the if
condition, you will see that I have made unhidden all rows that come in the selected page and rest of the rows are made hidden.
Now on to step 4.
4. Setting Pager Size at Runtime
A dropdown is taken to change the page size of the grid at run time. The default size of the page is set to 3
.
var PageSize=3;
if(document.getElementById('ddlPageSize'))
PageSize = document.getElementById('ddlPageSize').value;
The first time when the grid is bound, we don't actually have the pager dropdown created. So the default size is 3
. But when we change the page size, we have pager dropdown and from there, we can get the value of the page size. Here we can set the page size of the grid from the dropdownlist.
Now on to the final step 5.
5. Deleting Records from Grid
To delete records from the grid, we need a checkbox to select and a button to delete the record. For this, I have created a button btnDelete
and a function DeleteItem()
which is fired when the user clicks on the delete button.
var arrProduct;
arrProduct = document.getElementsByName('chkSelect');
var ProdIds='';
for (var i=0 ; i<arrProduct.length ; i++)
{
if(arrProduct[i].checked)
{
ProdIds = ProdIds + arrProduct[i].id.substring(7,arrProduct[i].id.length) + ',';
}
}
if(ProdIds !='')
{
if(confirm('Are you sure want to delete selected item(s)?'))
{
ProdIds=ProdIds.substring(0,ProdIds.length-1)
GetResponse('HandleRequest.ashx?RequestType=DeleteCart&ProdIds='+
ProdIds,GetCartResponse);
}
}
else
{
alert('Please select item(s) to delete.');
}
In this JavaScript function, I have found all the checkboxes which are checked and then they are sent to the server as request to delete the items and a new response is received from the server to fill the gird with the rest of the records. The checkbox value is preserved during page change.
History
- 15th February, 2009: Initial post