All of the examples have add the AjaxControlToolkit.DLL removed in order to save space. Once you have installed the toolkit, you will need to add a reference to it.
Introduction
I needed a way to react to a user typing in a text box on my web page. At the time, I was using the Atlas framework and found some JavaScript that would take care of the problem for me. Everything was great until the Atlas framework started maturing and turned into ASP.NET AJAX. Unfortunately I could not get the previous code to work in the new environment. I figured it was time for me to figure out how to get an extender to work so I took the previous JavaScript and updated it so it fit into the new framework.
Fortunately there were not many changes that needed to take place to move this code into the new extender model. Once the extender is built and included in your web project, everything can be hooked up through the extenders properties.
In order to test this, you will need to install ASP.NET AJAX 1.0 RC and the ASP.NET AJAX Control Toolkit from AJAX Downloads. All of the code has been tested against the RC and may not work with previous versions.
I will not be covering the details on how to setup and use a basic extender. These links will provide good sources of information on using an extender and creating your own extenders.
Extending a Control
ASP.NET Ajax allows you to add features to the existing ASP.NET controls via extenders. Once an extender is written, you hook it into an existing control and the new features are added to the previous control. The following snippet shows the typical usage for the extender. The first thing that needs to happen is registering the new extender on the web page.
<%@ Register Assembly="TextChangedExtender"
Namespace="TextChangedExtender" TagPrefix="tce" %>
The TextChangedExtender
has two custom properties that determine its behavior.
Timeout
- Gets or sets the timeout. This value determines how long before the last keystroke is pressed before notifying via the TextChangedFunction
. TextChangedFunction
- Gets the name of the function to call when a text change event has occurred.
Next a textbox
is declared and the extender is setup to reference it via the TargetControlID
property and the two custom properties are also set.
<asp:TextBox ID="Test1" runat="server" TabIndex="10" Width="250px"></asp:TextBox>
<tce:TextChangedExtender ID="TextChangedExtender1" runat="server"
TargetControlID="Test1" Timeout="250" TextChangedFunction="onTextChanged" />
Once that has been set up, all that is left to do is declare the onTextChanged
function. A simple one is shown below:
<script type="text/javascript">
function onTextChanged()
{
alert('onTextChanged Fired');
}
</script>
If the text changes, or the control loses focus, the extender will call the onTextChanged
defined above. It will wait up to 250 milliseconds for another character to be entered before determining it is time to notify.
TextChangedFunction Details
Finding a way to notify a function in my aspx web page was something that I struggled with. The solution that I have come up with works for me. I am interested in hearing how others have solved this problem. One thing that I was not able to determine was how to have the script call directly into my code behind. I had to use an intermediate layer which I will demonstrate below, but first I will cover my current implementation.
TextChangedExtenderBehavior.js contains all of the custom code that determines the extenders behavior. It follows the current model and is based on the previously mentioned links. When the extender is created, it saves the current text from the control it is attached to, creates a timer and hooks into the keyDown
, keyUp
, and onBlur
DOM event handlers. When one of the events happen, or the timer fires, the code determines if the text has changed. If it has changed, then the function is called.
Minus calling the text changed function, getting all of the above set up was very straight forward. Since working with properties was very easy, I decided to define the text change function as a property. When the TextChangedFunction
property is modified, any previous function is removed and the new function is wired in using code similar to that shown below:
if (this._textChangedFunction != null)
{
var fn = new Function('return ' + this._textChangedFunction + '(); ');
this.add_textChanged(fn);
},
add_textChanged : function(handler)
{
this.get_events().addHandler('textChanged', handler);
},
AJAX class event handling uses a consistent naming convention to add or remove events. The name of the event is prefixed with either add or remove. Then to raise the event, all you need to do is get the handler associated with the eventName
and call it.
handleTextChanged : function()
{
this._timer.set_enabled(false);
var curText = this.get_element().value;
if (this._savedText != curText)
{
this._savedText = curText;
this.raiseEvent('textChanged');
}
},
Finding a Way to Call Methods on the Server
Things started moving along once I figured out how to use a property to hook an AJAX class event handler. There are other ways that I tried but they all required more setup in each and every aspx page that would need them. Properties seemed like a natural extension of an extender.
The only problem I had left was finding a way to call a method on the server. My needs required me to filter some data based on the information that was being displayed and I was not able to accomplish this with JavaScript. I knew there had to be a way since ASP.NET is already doing this. I found out that there is a method called __doPostBack
that will be generated if a control on the form requires this. I hook into this in my aspx page with the following code. Here is a detailed analysis of the doPostBackFunction
.
<script type="text/javascript">
function onTextChanged()
{
__doPostBack('_hiddenFilter','');
}
</script>
<!-- A dummy field used so __doPostBack can be called when the
text has changed. In order to then process the results the server
code needs to run The postBack will use the onClick handler to fire.
It must be visible as a control so it is hidden via a CSS style -->
<asp:LinkButton ID="_hiddenFilter" runat="server" CssClass="hidden"
OnClick="_hiddenFilter_Click">Filter</asp:LinkButton>
Now when the text changes, a post back is made and the _hiddenFilter_Click
method is called.
protected void _hiddenFilter_Click(object sender, EventArgs e)
{
Label1.Text = "onTextChanged Fired : New Text : " + Test1.Text;
}
Wrapping Up
I am interested in finding out how others have solved this problem and I hope that this helps someone to get done what they need to. If anyone has any tips on other ways to setup an event on an extender and call back into the server side code, I would like to hear them.
History
- 24th December, 2006: Original article
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.