Table In-Place Editing Using ASP.NET 2.0 Client Callbacks
We are all familiar with In-Place editing feature which allows the user to edit the rows in the table without having to leave the place. The default in-place editing causes a postback which is very annoying if you have several rows in the table. It would be very nice to have in-place editing feature without the postback headache. In this post I will explain how to create in-place editing using a simple HTML Table and ASP.NET 2.0 Client Callbacks.
ASP.NET 2.0 Client Callbacks allows you to make server side calls from the client side without causing a postback. All you need to do is to implement the ICallbackEventHandler interface and after that your page will be able to make Asyncronous calls. Let's first see how to register the Callback methods.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
PopulateCategories();
}
// register the client callbacks scripts
string cbReference = ClientScript.GetCallbackEventReference(this, "arg", "RecieveServerData", "context");
string script = String.Empty;
if (!ClientScript.IsClientScriptBlockRegistered("CallServer"))
{
script = "function CallServer(arg,context) { " + cbReference + "}";
ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", script, true);
}
}
The Callback method is registered inside the Page_Load event. Next we need to implement the GetCallbackResult and RaiseCallbackEvent method.
public
string GetCallbackResult()
{
return returnValue;
}
public void RaiseCallbackEvent(string eventArgument)
{
string[] req = SplitCallback(eventArgument);
if (req[0].Equals("GET_ARTICLES"))
{
returnValue = TableManager.ConvertDataToHTMLTable(DataManager.GetArticles(Int32.Parse(req[1])));
}
else if (req[0].Equals("DELETE_ARTICLE"))
{
DataManager.DeleteArticle(Int32.Parse(req[1]));
}
else if (req[0].Equals("UPDATE_ARTICLE"))
{
DataManager.UpdateArticle(req[1]);
}
}
Ohh by the way the variable "returnValue" is a class level variable of type string.
One of the disadvantages of using the Client Callbacks is that you won't know which control caused the callback. Microsoft should have provided some implementation for this scenario. To overcome this scenario I sent the keyword along with the actual data. The keyword is used to distinguish the type of request. Check out the code below which is fired when the user selects an item from the dropdownlist.
// get the articles
var
GET_ARTICLES = "GET_ARTICLES:"; function
GetArticles()
{
var selectedValue = document.getElementById("ddlCategories").value;
CallServer(GET_ARTICLES+selectedValue,'');
}
As, you can see the GET_ARTICLES is the keyword the the value from the DropDownList is the actual data. Now, when the request reaches the server side I check the keyword and then take appropriate action.
if (req[0].Equals("GET_ARTICLES"))
{
returnValue = TableManager.ConvertDataToHTMLTable(DataManager.GetArticles(Int32.Parse(req[1])));
}
The method ConvertDataToHTMLTable is used to convert the table to HTML and add more columns. This columns include "Delete" and "Edit" columns.
private
static Table GetTable(
DataSet data)
{
int rowIndex = 0;
Table table = new Table();
table.CssClass = "TableStyle";
TableHeaderRow headerRow = new TableHeaderRow();
for (int columnIndex = 1; columnIndex < data.Tables[0].Columns.Count; columnIndex++)
{
TableCell tableCell = new TableCell();
tableCell.Text = data.Tables[0].Columns[columnIndex].ColumnName;
headerRow.Cells.Add(tableCell);
}
foreach (DataRow row in data.Tables[0].Rows)
{
TableRow tableRow = new TableRow();
tableRow.ID = "TableRow" + rowIndex;
object[] items = row.ItemArray;
for (int i = 1; i < items.Length; i++)
{
TableCell cell = new TableCell();
cell.Text = items[i].ToString();
tableRow.Cells.Add(cell);
}
TableCell deleteButtonCell = new TableCell();
HtmlAnchor anchorDelete = new HtmlAnchor();
anchorDelete.HRef = "#";
anchorDelete.InnerHtml = "Delete";
deleteButtonCell.Controls.Add(anchorDelete);
anchorDelete.Attributes.Add("onclick", "DeleteArticle("+items[0].ToString()+")");
TableCell editButtonCell = new TableCell();
editButtonCell.ID = "EditCell" + rowIndex;
HtmlAnchor editButton = new HtmlAnchor();
editButton.HRef = "#";
editButton.InnerHtml = "Edit";
editButton.Attributes.Add("onclick", "EditArticle('" + tableRow.ID + "',"+items[0].ToString()+")");
editButtonCell.Controls.Add(editButton);
tableRow.Cells.Add(deleteButtonCell);
tableRow.Cells.Add(editButtonCell);
table.Rows.Add(tableRow);
// increment the index
rowIndex++;
}
table.Rows.AddAt(0, headerRow);
return table;
}
There is a lot of JavaScipt code involved which I will discuss in my upcoming article "In-Place Editing Using Client Callbacks in ASP.NET 2.0". For now please check out the animation below:
