In my previous article of Ajax enabled grid using ICallbackEventHandler I outline the creation of a grid with the following operations
In this article we will discuss editing the grid with the principal goal of doubleclicking on a grid cell to enable editing of that cell then edit the content of the cell and finally update server side data without refreshing the page. The key advantages of this grid are as follows
The basic UI will contain one Gridview and one update button. We will bind data to grid on page load.
<div id="Gridview"> <asp:GridView EnableViewState="false" runat="server" id="_grid" OnRowDataBound="_grid_RowDataBound"></asp:GridView><span id ="ServerMsg"></span></div> <br /> <input type=button value="Update" onclick="javascript: JSUpdateTable ();" /> <script language="javascript">function UpdateGrid(args) { <%= ClientScript.GetCallbackEventReference(this,"args", "ShowResult", null) %>; } </script>
We have activated RowDataBound event of the grid.
public DataTable _sampleData { get { DataTable dt = (DataTable) Session["DataTable"]; if(dt == null) { dt = new DataTable(); dt.Columns.Add(new DataColumn("Contact Name",typeof(string))); dt.Columns.Add(new DataColumn("Company Name", typeof(string))); dt.Columns.Add(new DataColumn("City", typeof(string))); dt.Columns.Add(new DataColumn("Country", typeof(string)));
dt.Rows.Add(new object[] { "Maria Anders" ,"Alfreds Futterkiste","Berlin","Germany"}); dt.Rows.Add(new object[] { "Ana Trujillo" ,"Emparedados y helados ","México D.F.","Mexico"}); dt.Rows.Add(new object[] { "Antonio Moreno", "Antonio Moreno Taquería", "México D.F.","Mexico" });Session["DataTable"] = dt; } return dt; } set { Session["DataTable"] = value; } }
We can write a function which will return a datatable, and the get property will simply return that table. We have used a session variable instead of viewstate to store the table; this is because we need to update data on the server side, if we use viewstate we would need to do post back of the page.
To bind this table to the grid we can simply set the datasource of the grid to the datatabe : _grid.DataSource = _sampleData;And to set new data table we will add _sampleData = _tempTable;
Here _tempTable is the updated table after updating the grid on client side.
public void RaiseCallbackEvent(string eventArgument) { string[] args = eventArgument.Split('$'); if (args[0] == "updateTable") updateTable(args[1]); }
public string GetCallbackResult() { return result; }
The result is a global variable declared on the page.
We are following the same convention for RaiseCallbackEvent(string eventArgument) which we have used in my last article ( Ajax enabled grid using ICallbackEventHandler )
We can view a grid and and datatable as a two dimentional arrays with any cell being referenced by a row,column combination (i.e. row[i][j]).
As we have discussed earlier; we will look at the grid as a two dimentional array. Thus we will maintain unique id for each cell so that cell id will give the position of that cell in the datatable. Here, understand that grid data is an exact copy of the datatable so row[i][j] in datatable will match with row[i][j] of grid.
Define _rowNumber as global variable for same page.int _rowNumber = 0;
protected void _grid_RowDataBound(object sender, GridViewRowEventArgs e) { if (e.Row.RowType == DataControlRowType.DataRow) { for (int i = 0; i < e.Row.Cells.Count; i++) { e.Row.Cells[i].Attributes.Add("ondblclick", "javascript:MakeCellEditable(this);"); e.Row.Cells[i].Attributes.Add("id", _rowNumber + "_" + i); } _rowNumber += 1; }}
To make cell editable we have add: e.Row.Cells[i].Attributes.Add("ondblclick","javascript:MakeCellEditable(this);");
MakeCellEditable(this) will write this JavaScript function in next step.
To identify each cell as unique cell and to mach it with corrosponding datatable entry, we will give id to each cell in such a way that it will follow row[i][j] structure.i.e. e.Row.Cells[i].Attributes.Add("id", _rowNumber + "_" + i);
And we are increasing row number each time. Observe the way we have given id, we will get [i][j] position just by spliting the is on “_”.
function MakeCellEditable(obj){if(!window.document.getElementById(obj.id + "_input")) { obj.innerHTML = "<input id="+ obj.id + "_input" + " type=text value='" + obj.innerText + "'/>" }window.document.getElementById(obj.id + "_input").focus();}
This function will convert the cell into text box and set focus in that text box. Check the way we have assinged theid to the text box (i.e.[i]_[j]_input obj is the cell)