Handling the Client-Side onblur event of an asp:TextBox wth Server-Side code...


By: Brett Burch Spacer (www.brettresources.net) Spacer Date: June 11, 2006Spacer

A recent project required me to handle more client-side events than the usual click, onchange and submit events that are easily wired up with the .Net framework. Here's a way to handle additional client-side events with server-side code. WARNING: This does involve what I would consider a hack, but does solve the business problem.

What I had to do was add a button to the page, and then wire up an event (as usual) for that button's click event. This is as easy as drag, drop, and double-click in Visual Studio. To display this, I have added an aspx web form to a project called "testing.aspx"... Here is my .cs code:

    public class testing : System.Web.UI.Page

    {

        protected System.Web.UI.WebControls.TextBox txt1;

        protected System.Web.UI.WebControls.Button btnBlur;

 

        private void Page_Load(object sender, System.EventArgs e)

        {

            // Put user code to initialize the page here

            string eventHandler = this.GetPostBackEventReference(this.btnBlur, "");

            this.txt1.Attributes.Add("onblur",eventHandler);

        }

 

        private void btnBlur_Click(object sender, System.EventArgs e)

        {

            Response.Write("btnBlur_Click fired from txt1's onblur event.  I can do anything server-side here.");

        }

 

        //the rest of your code-behind class

        ...

 

        private void InitializeComponent()

        {   

            this.btnBlur.Click += new System.EventHandler(this.btnBlur_Click);

        }

    }

What we have essentially done in the above code is hijack the button's server-side Click event. This is dangerous, because if the button were to be displayed, clicking it would cause our asp:TextBox's onblur server-side code to run. We would obviously not want that to happen. The best way I have found to prevent the button from being clicked is to hide it from our users. I set the Visible property of my button (btnBlur) to False, and additionally wrapped it in a div HTML element with a style tag on the div including "display:none" just to be safe. Call it paranoia, since the Visible="False" on the asp:Button tag will prevent it from being rendered on the form, but I felt it important to include. The critical piece of my testing.aspx code is below.

<asp:TextBox Runat="server" ID="txt1"></asp:TextBox>
<div style="display:none"><asp:Button ID="btnBlur" Text="" Runat="server" Visible="False"></asp:Button></div>

Exiting your asp:Textbox now will cause server-side code to fire.

Taking It a Step Further
So what if we want to do this in a DataList, DataGrid, or Repeater? Not a problem. My business requirement led me to use a DataList. Our asp:Button's click event is going to get bubbled to the DataList's ItemCommand event. Some sample DataList code shows how we set this up.

<asp:DataList Runat="server" ...
<ItemTemplate>
  <!-- txt onblur stuff -->
  <asp:TextBox Runat="server" ID="txt1" Width="225px"></asp:TextBox>
  <div style="display:none"><asp:Button ID="btnBlur" CommandName="Blur" Text="" Runat="server" Visible="False"></asp:Button></div>
  <!-- end txt onblur stuff -->
</ItemTemplate>

This is no different than the previous snippet, except that we don't explicitly set up a Click event for the Button. Instead, we set a CommandName for the Button, which we can use in the DataList's ItemCommand event. To see this, review the code below.

    private void DataList_ItemDataBound(object sender, System.Web.UI.WebControls.DataListItemEventArgs e)

    {

        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)

        {

            // the next 4 lines are required to handle the textbox's onblur event with server-side code...

            Button btn = (Button)e.Item.FindControl("btnBlur");

            string eventHandler = this.GetPostBackEventReference(btn, "");

            TextBox txt = (TextBox)e.Item.FindControl("txt1");

            txt.Attributes.Add("onblur",eventHandler);

            //end onblur code

        }

    }

 

    private void DataList_ItemCommand(object source, System.Web.UI.WebControls.DataListCommandEventArgs e)

    {

        switch (e.CommandName)

        {

            case "Blur":

                //do whatever you like here to handle the onblur event

                break;

        ...

As you can see, I used the ItemDataBound event of the DataList to set up the onblur hijack rather that Page_Load. This is because the TextBox lives in a different place in the Page's control tree (and is more easily accessible here). As you can also see, setting up the code to handle our Blur command is just like setting up any othe DataList command. Hopefully this helps others in future endeavors. It stands to reason that any JavaScript event could be handled in this way.

My question is, will future ASP.Net controls have this functionality built-in? Just for experimentation purposes, I think I'll create a server control that is capable of handling any client-side event for an HTML input control. More about that later...