Monday, December 8, 2008

Use ICallbackEventHandler interface for asynchronous calls to the server

A simple way to perform asynchronous calls to the server from the client is by using the ICallbackEventHandler interface in .NET 2.0.

1.) Create a class and specify ICallbackEventHandler interface:
public partial class TestClass : System.Web.UI.UserControl, ICallbackEventHandler

2.) Implement ICallbackEventHandler.RaiseCallbackEvent and ICallbackEventHandler.GetCallbackResult()
private string results;
void ICallbackEventHandler.RaiseCallbackEvent(string argument)
{
string[] list;
int i=0;
string id= argument.ToLower();
DataView dv = RetrieveData(argument);
list = new string[dv.Table.Rows.Count];

foreach (DataRow row in dv.Table.Rows)
{
list[i] = row[1].ToString() + "," + row[2].ToString();
i++;
}
results = String.Join("-", list);

return;
}

string ICallbackEventHandler.GetCallbackResult()
{
return results;
}


3.) Create async call-back function for use on client side.
private string GetDataRefreshScript()
{
StringBuilder sb = new StringBuilder("function RefreshResults(data){");
sb.AppendLine(Page.ClientScript.GetCallbackEventReference(this, "data", "UpdateData","null", "UpdateData_Error", true));
sb.AppendLine("}");
sb.AppendLine(GetUpdateDataScript());

return sb.ToString();
}


4.) Create client script to handle data retreived from server through async call.
private string GetUpdateDataScript()
{
StringBuilder sb = new StringBuilder("function UpdateData(response, context) {");
sb.AppendLine("var id = document.getElementById(\"" + ResultsGrid.ClientID + "\");");
sb.AppendLine("if(id != null){");
sb.AppendLine("var rows = new Array();");
sb.AppendLine("rows = response.split(\"-\");");
sb.AppendLine("for(j=0; j sb.AppendLine("var tmpRow = rows[j];");
sb.AppendLine("addResultGridRow(id, tmpRow);\r\n}}}");

//Error
sb.AppendLine("function UpdateData_Error(response, context) {");
sb.AppendLine("var err = document.getElementById(\"" + errorMessage.ClientID +"\");");
sb.AppendLine("if(err != null){");
sb.AppendLine("err.innerHTML = 'Error processing data.';");
sb.AppendLine("err.style.visibility = 'visible';\r\n}}");

return sb.ToString();
}


5.) The last thing that needs done is triggering the async call from client
btn.Attributes.Add("onmousedown", "RefreshResults('" + data + "')");

Communicate data between two browser windows

To communicate data between two browser windows "window.opener" can be of assistance. window.opener returns a reference to the window that opened the current window. So this mock function below should be inserted into the opened window.
Make note that "__datatarget" and "__datawindow" are two variables that were defined in the parent window.

function SetData(data)
{
  if ((window.opener != null)
  && (!window.opener.closed)
  && (window.opener.__datatarget != null))
  {
    var changed = (window.opener.__datatarget.value != data);
    window.opener.__dataetarget.value = employee;
    window.opener.__datawindow.value = null;
    if (changed)
      window.opener.__datatarget.fireEvent("onchange");
  }
window.close();
}