Monday, October 10, 2005

IPostBackDataHandler - to track client-side changes

How to track the client-side changes in your custom control's Childen?

ASP.NET server control
If you have asp:textbox, it tracks itself to see if it has been changed on the client side and if so, it raises the OnDataChanged event.

HTML form-element
If you have a normal HTML input field, then it is your control's responsibility to see if it has been changed on the client-side and raise any event, like DataChanged, if needed.
To do so, your control must implement the IPostBackDataHandler interface by defining LoadPostData and RaisePostDataChangedEvent methods.
In LoadPostData, your control must check to see if your HTMl input field's value is updated on the client side and if so, return true.
Note that the LoadPostData method is passed a collection of form elements and their values as one of its inputs and that your HTML input field will be one of them.
If LoadPostData returns true, the RaisePostDataChangedEvent method is called where you can raise any appropriate events, if needed, or handle it accordingly.

HTML non-form element (table, div, span etc.)
If you have an HTML non-form element, then again it is your control's responsibility to see if it has been changed on the client-side and raise any event, like DataChanged, if needed.
To do so, your control must again implement the IPostBackDataHandler interface by defining LoadPostData and RaisePostDataChangedEvent methods. In LoadPostData, your control must check to see if your HTMl input field's value is updated on the client side and if so, return true. But note that your non-form element will NOT be in the collection of form elements and their values passed to the LoadPostData method as one of its inputs.
So, we have to use hidden input fields that carry the data for non-form elements. These hidden fields need to be updated as the non-form element is changed on the client side so that when the page is posted back, the hidden fields store required information about the updates made to the non-form element and hence can be used by teh server to track the updates.
Like in the above case, if LoadPostData returns true, the RaisePostDataChangedEvent method is called where you can raise any appropriate events, if needed, or handle it accordingly.

When will the page framework call the LoadPostData method of a control that implements IPostBackDataHandler interface?
Sln: When one of the folowing is true...

1. When a postback occurs, the page framework searches the posted data for values matching the server controls' unique IDs that implement the IPostBackDataHandler interface. [The page framework uses the UniqueID property to route postback data back to the control]
Then, LoadPostData method is invoked on each control that implements the interface.

If you use this method to track changes on an HTML form-element, then you have to name that element with the control's UniqueID, for obvious reasons(so that there will be an element with the control's UniqueID in the posted data which tells the page framework to call that control's LoadPostData method).

If you use this method to track changes on an HTML non-form element, then you have to name the HTML hidden field, created only to save the updates made on the non-form element, with the control's UniqueID.

2. When your control registers itself to require postback as follows.
Page.RegisterRequiresPostBack(this);
In this case, even though the posted data has no element matching your controls' unique ID, it still calls your controls' LoadPostData method.

If you use this method to track changes on an HTML form-element, then you need not name that element with the control's UniqueID.

If you use this method to track changes on an HTML non-form element, then you again need not name the HTML hidden field, created only to save the updates made on the non-form element, with the control's UniqueID.

The page framework then tracks tracks all the controls that return true from the LoadPostData method and invokes RaisePostDataChangedEvent on them.