Which control raised the async postback event?
The PageRequestManager in the ASP.net AJAX 1.0 Beta
2 framework exposes a pageLoaded event which is raised when
the page is refreshed.
AFAIK, the pageLoaded
event does not contain any property that tells you which
element on the page raised an async postback (I am hoping
something like this is already built in!).
This
would be useful in places where you wanted to get or set the
properties of the control that raised the async postback
after the page loaded.
You could get the value by subscribing to the beginRequest event and call the get_postBackElement method as described here. The problem with this approach is that the value is stored in a global variable which will get overwritten if you have multiple async requests active at the same time. In addition, the order in which the responses arrive is not guaranteed. Finally, even if you stored this value in an instance of a JS object, you still have no easy way of knowing the context of the pageLoaded event.
The aproach described here is to return the ClientID of the
control that raised the async postback through the
RegisterDataItem
method of the ScriptManager class.
As shown
below, when a control raises an async postback, we find the
control that raised the event in code behind and get its
ClientID.
We then create a dummy control and set
its ID to a unique value
___asyncPostBackClientID.
The reason for the unique value will become clear in the
next step. The RegisterDataItem method is called by passing
in our dummy control and the data we want to send down - the
ClientID of the control that raised the async postback which
we obtained in the previous step.
protected void Page_Load(object sender, EventArgs e) {
WriteAsyncPostbackClientId();
}
private void WriteAsyncPostbackClientId() {
ScriptManager sm = ScriptManager1;
if (sm.IsInAsyncPostBack) {
Control asyncPostbackControl = Page.FindControl(sm.AsyncPostBackSourceElementID);
if (asyncPostbackControl != null) {
//Dummy label used for RegisterDataItem
Label label = new Label();
label.ID = "___asyncPostBackClientID";
sm.RegisterDataItem(label, asyncPostbackControl.ClientID);
}
}
}
On the client side, we have subscribed to the pageLoadedEvent and we check to see if there is any dataItem that belongs to our dummy control with ID ___asyncPostBackClientID. This value has been set to something unique to avoid conflict with other controls on the page. So by looking at the dataItem for our dummy control, we can get the ClientID of the control that initiated the request.
<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoaded);
function pageLoaded(sender, args) {
var asyncPostBackId = args.get_dataItems()["___asyncPostBackClientID"];
if (typeof(asyncPostBackId) === "string") {
alert("AsyncPostBackId : " + asyncPostBackId);
}
}
</script>
PS : It has been three weeks since I started using the
ASP.net AJAX framework and I am really impressed. I really
like the fact that the Ajax framework blends in with the
page lifecycle.
I had been using my custom
XMLHttpRequest wrapper with webservices until then :-(