This post is going to show you how to use JSON and JavaScript to create a light weight GridView in JavaScript. It's not in its best shape because I've just learned JavaScript and had to come up with some solution to replace GridView with something and this is what I came up with, no doubt it can be further tweaked to make it more apt. So here we go.
Things we'll cover
1. converting data in JSON
2. using JavaScript to create GridView
3. applying paging and sorting to it.
1. converting data in JSON
In order to achieve our first goal we'll use the code from which I took from Naveed Akhtar's post, you can read the entire article here; for now I am posting the code here for you now.
It uses a DataTable object to create JSON; here it is.
public void GetJSONString(DataTable Dt)
{
string[] StrDc = new string[Dt.Columns.Count];
string HeadStr = string.Empty;
for (int i = 0; i < Dt.Columns.Count; i++)
{
StrDc[i] = Dt.Columns[i].Caption;
HeadStr += "\"" + StrDc[i] + "\" : \"" + StrDc[i] + i.ToString() + "¾" + "\",";
}
HeadStr = HeadStr.Substring(0, HeadStr.Length - 1);
StringBuilder Sb = new StringBuilder();
Sb.Append("{\"" + Dt.TableName + "\" : [");
for (int i = 0; i < Dt.Rows.Count; i++)
{
string TempStr = HeadStr;
Sb.Append("{");
for (int j = 0; j < Dt.Columns.Count; j++)
{
TempStr = TempStr.Replace(Dt.Columns[j] + j.ToString() + "¾", Dt.Rows[i][j].ToString());
}
Sb.Append(TempStr + "},");
}
Sb = new StringBuilder(Sb.ToString().Substring(0, Sb.ToString().Length - 1));
Sb.Append("]}");
}
2. using JavaScript to create GridView
Here I wanted to get the key of key value pair in JSON created but couldn't retrieve it and also couldn't find any solutions to take them out. Here you have to specify the name of the column explicitly (that's why I said it's not the perfect solution for now, if you have any suggestion that can help us, you are most welcome).
This is how your html page should look like
<body onload="LoadGrid()">
<center>
<table id="tid" style="border:dotted 1px gray; width:50%;">
</table>
<div id="Paging" style="margin:0px 0px 0px 0px; padding:0px 0px 0px 0px; clear:both; text-align:center; width:100%;">
</div>
<input type="hidden" id="hfprice" />
<input type="hidden" id="hfname" />
<input type="hidden" id="hfstar" />
</center>
</body>
First let me tell you how this HTML works. It has a method loadGrid() in body which loads the GridView for you initially. We have used three hidden fields here to keep track of the order in which data is sorted: price, name or rating (stars like 4 star, 5 star hotels).
var data=[{"id":"1","nm":"hotel a","sr":3,"max":4375},{...}]
var ResultArray = new Array();
function LoadGrid()
{if(data.length==0)
{return;}
else
{LoadPaging();}}
function LoadPaging()
{
var pageSize=Math.ceil(data.length/25);
if(pageSize>1)
{
var divPager=document.getElementById("Paging");
for(var i=0;i<pageSize;i++)
{
var pageid=document.createElement("a");pageid.appendChild(document.createTextNode(i+1));
pageid.setAttribute("onclick","BindPage("+(i+1)+")");
pageid.setAttribute("href","JavaScript:none;");
pageid.style.margin="0 0 0 10px";
divPager.appendChild(pageid);
}
}
BindPage(1);
}
In the given data 'max' represents the price, 'sr' for star and 'nm' for name, here in the above code we'll get the data into a new array "ResultArray" as and when required from the "data" variable which has the JSON.
loadGrid()
in this function we check if the data has some data in it or not, if it has some we'll call the next method loadpaging()
loadPaging()
we'll be creating a GridView with pagesize of 25, in the variable pagesize we'll calculate how many pages we'll be getting out of the data we've just received and if the value exceeds 1 it goes into the loop and adds anchor tag in the paging div created just below the table.
BindPage()
if the pagesize dosen't exceed 1 bindpage will bind the page for a single page data without paging being done on it.
function BindPage(val)
{
var i=0;
var k=0;
while(ResultArray.length!=0)
{
ResultArray.pop();
}
for(i=0;i<val*25;i++)
{
if(i>=(val-1)*25&&i<val*25)
{
if(data[i]!=undefined)
{
ResultArray[k]={"id":i+1,"ChildData":data[i]};
k++;
}
}
}
if(ResultArray.length!=0)
{
var tb = document.getElementById("tid");
while(tb.firstChild)
{
tb.removeChild(tb.firstChild)
}
if(ResultArray.length!=0)
{
var r1 = document.createElement("tr");
var h1 = document.createElement("th");
var a1 = document.createElement("a");
//a1.setAttribute("href","JavaScript:none;");
a1.setAttribute("onclick","SortByID()");
a1.appendChild(document.createTextNode("ID"));
h1.appendChild(a1);
var h2 = document.createElement("th");
var a2 = document.createElement("a");
a2.setAttribute("href","JavaScript:none;");
a2.setAttribute("onclick","SortByName()");
a2.appendChild(document.createTextNode("Name"));
h2.appendChild(a2);
var h3 = document.createElement("th");
var a3 = document.createElement("a");
a3.setAttribute("href","JavaScript:none;");
a3.setAttribute("onclick","SortByStar()");
a3.appendChild(document.createTextNode("Stars"));
h3.appendChild(a3);
var h4 = document.createElement("th");
var a4 = document.createElement("a");
a4.setAttribute("href","JavaScript:none{0};");
a4.setAttribute("onclick","SortByPrice()");
a4.appendChild(document.createTextNode("Price"));
h4.appendChild(a4);
r1.appendChild(h1);
r1.appendChild(h2);
r1.appendChild(h3);
r1.appendChild(h4);
tb.appendChild(r1);
}
for(var x=0;x<=ResultArray.length;x++)
{
if(ResultArray[x].id>(val-1)*25&&ResultArray[x].id<=val*25)
{
var r1 = document.createElement("tr");
var d1 = document.createElement("td");
d1.appendChild(document.createTextNode(ResultArray[x].ChildData.id));
var d2 = document.createElement("td");
d2.appendChild(document.createTextNode(ResultArray[x].ChildData.nm));
var d3 = document.createElement("td");
d3.appendChild(document.createTextNode(ResultArray[x].ChildData.sr));
var d4 = document.createElement("td");
d4.appendChild(document.createTextNode(ResultArray[x].ChildData.max));
r1.appendChild(d1);
r1.appendChild(d2);
r1.appendChild(d3);
r1.appendChild(d4);
tb.appendChild(r1);
}
else
{
break;
}
}
}
}
In the above code we'll clear the resultarray if it has somevalue left in it using resultarry.pop() in while loop then we look for the table with id equals "tid" and give its column header value which are of anchor type and assign attribute values to it, so that we can sort the column when we click on them. We have three methods SortByName(), SortByPrice() and SortByStar(). In the second for loop just below in we bind the data to the columns.
function SortByPrice()
{
var flag=0;
setStyle()
do
{
BubbleSortPrice();
SortArray();
flag=1;
}
while(flag!=1)
endStyle();
}
function SortByName()
{
var flag=0;
setStyle()
do
{
BubbleSortName();
SortArray();
flag=1;
}
while(flag!=1)
endStyle();
}
function SortByStar()
{
var flag=0;
setStyle()
do
{
BubbleSortStar();
SortArray();
flag=1;
}
while(flag!=1)
endStyle();
}
Here we have three different methods that will be called when the sorting needs to be done, it has two methods setStyle() and endStyle() which pops up a css modal window showing "please wait text" while the processing is done.
function BubbleSortPrice()
{
var val = document.getElementById("hfprice");
if (val.value == "asc" || val.value == "")
{
val.value = "dsc"; var temp;
for (var i = 0; i < ResultArray.length; i++)
{
for (var j = i + 1; j < ResultArray.length; j++)
{
if (parseInt(ResultArray[i].ChildData.max) > parseInt(ResultArray[j].ChildData.max))
{
temp = ResultArray[i]; ResultArray[i] = ResultArray[j]; ResultArray[j] = temp;
}
}
}
}
else
{
val.value = "asc"; var temp; for (var i = 0; i < ResultArray.length; i++)
{
for (var j = i + 1; j < ResultArray.length; j++)
{
if (parseInt(ResultArray[i].ChildData.max) < parseInt(ResultArray[j].ChildData.max))
{
temp = ResultArray[i]; ResultArray[i] = ResultArray[j]; ResultArray[j] = temp;
}
}
}
}
}
I've used bubble sort here to sort the data which can actually takes more time than other sorting algorithms but to keep it simple I've used bubble sort here, but you can use any algorithm to replace this one and better performance. For those who don't know how it works, you don't have to worry because it is one of the simplest ones we could have used, for extra intro on bubble sort you always have Google by your side. :P
So what special this method has is it looks for the value in the respective hiddenfield it has; the value could be "asc" or "dsc" depending on the last value it had when sorting was done and this is how you can create a GridView in JavaScript.