Tuesday, August 05, 2008

ASP.Net: Add Client Side JavaScript Codes

ASP.Net controls do not support all the control events like window form application. For example, OnKeyUp, OnMouseUp, and OnMouseMove events. It make sense that if these events were supported, there would be too many calls from client side back server, and it would make aspx pages very very slow.

However, there are some cases you would like your aspx page to support these events. For example, I have a asp:TextBox control with an attribute of OnTextChanged event. This even only fires back to the server when you change the text and leave the control to any where on the same page. If you click on another link on the page right after you change the text, this event would not be called at all.

In order to catch this event and set a flag on the page to indicate a change, I have added another asp:TextBox control called MonitorChangeControl. Then I added the following codes in the Page_Load event to insert client side JavaScript function to the aspx page so that on the client side the MonitorChangeControl text will be changed to a text "Some values may have been changed." when my monitored textbox is changed:

string changeScript = "<script language='javascript'> function SomeValueChanged() {" +
"document.getElementById('" + MonitorChangeControl.ClientID +
"').value = 'Some values may have been changed.'; }</script>";
// Add the JavaScript code to the page.
if (!ClientScript.IsClientScriptBlockRegistered("SomeValueChanged"))
ClientScript.RegisterClientScriptBlock(this.GetType(), "SomeValueChanged", changeScript);

After register the script function, then in the following codes I add an attribute "OnKeyUp" with a script call to the function "SomeValueChanged()":

TextBox myTextBox = WebPageUtil.FindControlRecursive(row, "curr_day"); //row is a GridViewRow
if (currValue != null)
myTextBox.Attributes.Add("OnKeyUp", "return SomeValueChanged()");

When I run the aspx page in a browser, the TextBox is converted to an Input document element with an attribute like this:

<input name="..." OnKeyUp=""return SomeValueChanged()" .../>

This attribute will cause the client side event fired whenever the input element's text is changed or key-is-up.

So far so good. However, for an asp:CheckBox control, if the attribute is added in a the same way, the attribute is actually added to a span element in the aspx page which is outside of the input element (converted from CheckBox):

<span ... OnKeyUp="" ...><input id=... type="checkbox" .../></span>

Therefore, I have to add the attributes in a different way:

// row is a GridViewRow control and FindControlRecursive is my function.
CheckBox box = WebPageUtil.FindControlRecursive(row, "ValidatedCheckBox");
if (box != null)
box.InputAttributes.Add("OnKeyUp", "return SomeValueChanged()");
box.InputAttributes.Add("onmouseup", "return SomeValueChanged()");

After that, I tried to view source from the browser. Here is the result of what I expected:

<input id=... type="checkbox" ... OnKeyUp="return SomeValueChanged()" onmouseup="return SomeValueChanged()" />

By the way, the event of OnChange is working for TextBox control but not for CheckBox controls. The OnChange is fired only after you make a change and at the moment whey you leave the control. For complete HTML element, properties/attributes, and events, see the page of HTML Event Attributes and JavaScript Event References.

For the function FindControlRecursive(), see my previous blog on May 29, 2008