Labels

Friday, May 9, 2008

Determining the Control that Caused a PostBack

Hi,

Have you ever tried to know - On an ASP.NET postback, which control caused the postback. How does the Page class "know" which control at the client side was "clicked. Since HTTP is stateless and there is no "invisible connection" between the Client-Side HTML & Server-Side classes, how can a client-side event be handled on the server side?

The answer to this all jargon is – One Client side Hidden field named __EVENTTARGET and one JS fucntion named – __doPostBack()

If we read the ViewSource of an HTML page, you’ll find something like below.

<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />

<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"

<script type="text/javascript">

var theForm = document.forms['aspnetForm'];

if (!theForm)

{

theForm = document.aspnetForm;

}

function __doPostBack(eventTarget, eventArgument)

{

if (!theForm.onsubmit || (theForm.onsubmit() != false))

{

theForm.__EVENTTARGET.value = eventTarget;

theForm.__EVENTARGUMENT.value = eventArgument;

theForm.submit();

}

}

</script>

Whenever a client-side event, such as an "onclick" or "onchange" event occurs, the javascript __doPostBack() function records the name of the object that fired the event, as well as any additional event information, places it into the hidden form fields __EVENTTARGET and __EVENTARGUMENT, and then submits the form, initiating our PostBack.

Now to determine, which control made the postback at server side, below are the two approaches:

1st Approach:

· Access this hidden input from the code-behind as it is submitted with the form and can be found in the Params or Form collections.

· Once we have the name you can get a reference to the control via FindControl and use it as needed.

string ctrlname = page.Request.Params.Get("__EVENTTARGET");

if (ctrlname != null && ctrlname != string.Empty)

{

return this.Page.FindControl(ctrlname);

}

2nd Approach:

The above approach work only for CheckBoxes, DropDownLists, LinkButtons, etc, this does not work for Button controls.

Reason :

· If we take a look at how the server controls render as HTML, you'll see that the buttons do not call the __doPostBack Javascript function so the __EVENTTARGET is never set. Instead, the Buttons render as simple input type=“submit” tags.

· All the button does is cause the form to submit. That's it.

· Since the button (or input) is what causes the form to submit, it is added to the items in the Form collection, along with all the other values from the submitted form.

· It is important to note, that other input type=“submit” tags on the form are not added to the Form collection unless it was the one that caused the form to submit.

public static Control GetPostBackControl(Page page)

{

Control control = null;

string ctrlname = page.Request.Params.Get("__EVENTTARGET");

if (ctrlname != null && ctrlname != string.Empty)

{

control = page.FindControl(ctrlname); // 1st Approach

}

else

{

foreach (string ctl in page.Request.Form) // 2nd Approach

{

Control c = page.FindControl(ctl);

if (c is System.Web.UI.WebControls.Button)

{

control = c;

break;

}

}

}

return control;

}

This can be called on Page_Load as below:

Control c = PageUtility.GetPostBackControl(this.Page);

if (c != null)

{

//...

}

Hope this help.

Thanks & Regards,

Arun Manglick || Senior Tech Lead


No comments:

Post a Comment