Search KB Filter article types
Handling KeyPress Events on a VWG Textbox using a Client-Side Timer
By: jr365
Categories: Texts, Custom Controls
Tags: Architects, Developers, Events, C#, 3. Advanced, Customization, v6.3
Revision: 2
Posted: 07/Jan/2009
Updated: 27/Oct/2010
Status: Publish
Types: Code

Standard ajax involves a heavy use of client side timers. Visual Web Gui shields developers from alot of the messy details, but there are times when you have to get messy. I want to filter data based on the value in a textbox. However, I don't want to require a button click or enter press, and I don't want to handle all the keypress events on the server as postbacks. Take this for example:

All I did was type kite, and some search results were returned. To accomplish this in Visual Web Gui, we could handle each textchanged event on the server, but this requires a postback for every key press. Not a good solution for the web. The original idea was to create a client side timer that would be started when the text was changed. I collaborated with Ryan Hatch, who did all of the coding, to put this together - thanks, Ryan!

Here is a live demonstration:

Could not parse video source.
Please follow the next instructions to embed video fragments:
 - you can directly use videos from: 
   www.youtube.com
   video.google.com
   www.vimeo.com
 - you can directly reference video fragments of types: FLV, MOV, MP4 and F4V
 - for SWF Camtasia flash files should be HTML/HTML file and additional 
   [videoname]_config.xml or ProductionInfo.xml file.

Check the video URL if you can't see the fragment.

As you can see, we've got 2 ways to fire the events: while typing is occurring, or after typing is completed. That behavior is set here:

How does this work? First, a quick look at the Visual Studio Solution:

Ryan took the TextBox.js and TextBox.xslt files from the VWG Sources folder, modified them, and created a class that inherits from the TextBox class:

public partial class TimedTextBox : TextBox
{
    public TimedTextBox()
    {
        InitializeComponent();
    }
 
    /// <summary>
    /// Number of milliseconds that the timer will run before KeyPress event is raised
    /// </summary>
    [Description("Number of milliseconds that the timer will run before KeyPress event is raised")]
    public int TimerLength { get; set; }
 
    /// <summary>
    /// Sets whether or not a running client timer will be reset when a key is pressed on the client.
    /// </summary>
    [Description("Sets whether or not a running client timer will be reset when a key is pressed on the client.")]
    public bool ResetClientTimerOnKeyPress { get; set; }
 
    protected override void RenderAttributes(
        Gizmox.WebGUI.Common.Interfaces.IContext objContext, 
        Gizmox.WebGUI.Common.Interfaces.IAttributeWriter objWriter)
    {
        objWriter.WriteAttributeString("TimerLength", TimerLength);
 
        if (this.ResetClientTimerOnKeyPress == true)
            objWriter.WriteAttributeString("ResetClientTimerOnKeyPress", 1);
        else
            objWriter.WriteAttributeString("ResetClientTimerOnKeyPress", 0);
 
        base.RenderAttributes(objContext, objWriter);
    }
 
}

We added 2 properties:

* TimerLength: Number of milliseconds that the timer will run before code is executed
* ResetClientTimerOnKeyPress: A boolean value that sets whether or not a running client timer will be reset when a key is pressed on the client.

And we've overriden the RenderAttributes() method in the base class to include these properties as attributes in the html output. TimedTextBox.xslt: here we've added a an event handler to the html textbox, to call a javascript method:

<!--This is our hook into JavaScript, using OnKeyPress-->
<xsl:attribute name="onkeypress">
    mobjApp.TimedTextBox_SetTimer('<xsl:value-of select="@Id"></xsl>',this,window);
    mobjApp.TextBox_KeyPress('<xsl:value-of select="@Id"/>',
    '<xsl:value-of select="@Attr.CharacterValidationMask"/>',
    '<xsl:value-of select="@Attr.CharacterValidationExpression"/>',window,this,event);
</xsl:attribute>

and here are the javascript methods: TimedTextBox.js

// Called whenever the user changes text in textbox
function TimedTextBox_SetTimer(strGuid, objInput, objWindow) {
 
    // Get Current TimerID
    var myTimerID = Data_GetAttribute(strGuid, "TimerID");
 
    // Get ResetTimerOnKeyPress Flag
    var myResetTimerOnKeyPress = Data_GetAttribute(strGuid, "ResetClientTimerOnKeyPress");
 
    // Is there a Timer already running?
    var myHasTimerRunning = false;
    if (myTimerID != null && myTimerID != 'null') { myHasTimerRunning = true; }
 
    // Should we start a new Timer?
    if (myResetTimerOnKeyPress == 1 || myHasTimerRunning == false) {
 
    // Create TimerID
    var myNewTimerID = TimedTextBox_CreateGuid();
 
    // Set Current TimerID
    Data_SetAttribute(strGuid, "TimerID", myNewTimerID);
 
    // Create Callback
    var myFunction = function() { TimedTextBox_TimerExpired(myNewTimerID, strGuid, objInput, objWindow); };
 
    // Get Timer Length
    var myTimerLength = Data_GetAttribute(strGuid, "TimerLength");
 
    // Start Timer
    var myTimeout = Web_SetTimeout(myFunction, myTimerLength);
}

The behavior of the textbox is determined by attributes that we set earlier. Line 44 invokes VWG code that starts a timer, and then executes code when the timer is complete. Here is the code when the timer is complete:

function TimedTextBox_TimerExpired(strTimerID, strGuid, objInput, objWindow)
{
    // Get Current TimerID
    var myTimerID = Data_GetAttribute(strGuid, "TimerID");
 
    // Is our TimerID the latest TimerID?
    // We need this because - If user keeps typing, multiple timers will be running at once.  
    // Especially with the ResetClientTimerOnKeyPress flag
    if (strTimerID == myTimerID) {
 
    // Clear Timer - VWG Bug - setting null actually sets it to string 'null'!
    Data_SetAttribute(strGuid, "TimerID", null);
 
    // Raise Event (Fake the EnterKey to get TextChanged to Fire)
    TextBox_Change(strGuid, objInput.value, objWindow, true);
}

By checking the TimerId value in line 56, we allow for the behavior to only send a call to the server if the id given for the timer matches what is currently stored in the textbox as an attribute. In line 62, we raise the Textbox_Change event. By the way, don't forget to declare the control in web.config:

<Controls>
   <Control Type="MyControls.TimedTextBox.TimedTextBox, MyControls" ></Control>
</Controls>

Caveat: Does not yet work on multiline textboxes.

This is a working concept that we hope can be integrated into the standard VWG textbox.

Note: Codes are submitted as a .zip file to shorten your download time. After downloading it, you will need a program like Winzip to decompress it.

About the author

Related Articles

Texts  
Title Update Author
Tags: Developers, Data Binding, Navigation, 1. Beginner, 2. Intermediate, Data Binding, Navigation, ASP.NET, Pre v6.3, v6.3, v6.4 and Later, 3. Advanced
11/Jan/2009    2009/01/11
This video demonstrates how to create and use a FCK Editor.
Tags: Architects, Developers, Wrapper, 1. Beginner, 2. Intermediate, Pre v6.3, v6.3, v6.4 and Later, 3. Advanced
01/Jan/2009    2009/01/01
Tags: Developers, 1. Beginner, 2. Intermediate, Customization, Pre v6.3, v6.3, v6.4 and Later, 3. Advanced
02/Jan/2009    2009/01/02
This is a code example to how to use the TextBox Validation class.
Tags: Developers, 1. Beginner, 2. Intermediate, Customization, Pre v6.3, v6.3, v6.4 and Later, 3. Advanced
10/Jan/2008    2008/01/10
This application demonstrates how to use the Timer to update a TextBox and a ProgressBar control.
Tags: Developers, Events, 1. Beginner, Pre v6.3, v6.3, v6.4 and Later, 2. Intermediate, 3. Advanced
12/Jan/2009    2009/01/12
Tags: Architects, Developers, Wrapper, 1. Beginner, 2. Intermediate, 3. Advanced, Pre v6.3, v6.3, v6.4 and Later
15/Aug/2010    2010/08/15
.NET Web, Cloud and Mobile application delivery platform | Sitemap | Terms of Use | Privacy Statement | Copyright © 2005-2011 Visual WebGui®       Visual WebGui weblog on ASP.NET Visual WebGui Group on LinkedIn Visual WebGui updates on Twitter Visual WebGui Page on Facebook Visual WebGui YouTube Channel Visual WebGui Platform News RSS