Recipe 5.4 Customizing an ASP.NET TextBox Server Control

     

5.4.1 Problem

You want to customize an ASP.NET TextBox server control to allow only numeric input.

5.4.2 Solution

Create a custom control that inherits from the ASP text box control, and then add code to emit client-side script that limits the input to only numeric values.

Use the .NET language of your choice to:

  1. Create a class that inherits from the Control class in the System.Web.UI namespace.

  2. Override the OnPreRender method to have it generate the requisite client-side script.

  3. Override the AddAttributesToRender if you need to add an attribute to the rendered control.

To use the custom control in an ASP.NET page:

  1. Register the assembly containing the control.

  2. Insert the tag for the custom control anywhere in the page.

Example 5-15 and Example 5-16 show the VB and C# class files for an example custom control that we have written to illustrate our approach. This custom control emits client-side script that checks key presses and allows only numeric keys to be entered into a text box. Example 5-17 shows how to use the custom control in an ASP.NET page.

5.4.3 Discussion

Extending an existing ASP.NET server control is an easy way to create the functionality you need for an application. By inheriting your custom controls from existing controls, you are left to write only the code you need to add your special functionality.

To illustrate this approach, we've implemented a text box control that allows only numeric input, a common project requirement. Why is it necessary to implement a custom control to accomplish this? First, it turns out that none of the ASP.NET controls provides this functionality. And second, although you can check the data entered in a text box to ensure it is numeric and within a range with a range validator , this does not prevent the user from entering letters into the text box in the first place. Extending the standard text box control by adding client-side script that allows only numeric keys to be processed and their values entered into the text box is a better solution.

The first step in extending the ASP.NET text box control is to create a custom control class that inherits from System.Web.UI.WebControls.TextBox .

Next , you must override the OnPreRender method to generate the client-side script. (The reason for overriding OnPreRender is that you need to get the script onto the page before the control is rendered.) This is done by creating a string containing the script block, and then registering it to be output to the page with the Page.RegisterClientScriptBlock method.

The client script must be created and output in an event that occurs before the Render event or the script will not be output in the rendered page. This can be done in the Load or PreRender events.


Be sure to call the base class OnPreRender method. Failure to do so can result in lost functionality if the base control performs any operations in the OnPreRender method.


It is important to output the client script using the Page.RegisterClientScriptBlock method with the first parameter set to a constant value. This ensures that client script is output to the page only once. If the client script was output directly in the Render event and the page contained multiple instances of the custom control, the client script would be output for each instance of the control.


The client-side script that is output to the page in our example is shown next. It simply checks each key press to see if the keycode is in the 0-9 range and returns true if it is. Otherwise, it returns false .

 <script language='javascript'> <!--   function checkKey( )   {     var key = event.keyCode;     var processKey = false;     if ((key >= 0x30) && (key <= 0x39))     {       processKey = true;     }     return(processKey);   } //--> </script> 

This script will work only for Internet Explorer. You can use the Page.Request.Browser object in the OnPreRender method to determine the browser type and version so that you can output code specific to the browser requesting the page.


The last step to implement our sample custom control is to add an attribute to the rendered input control to cause the checkKey method to be executed when a key is pressed with the focus set to the input control. This is done by overriding the AddAttributesToRender method and adding the onkeypress attribute.

If your application has a similar requirement to add an attribute to the rendered input control, be sure to call the base class AddAttributesToRender method. Failure to do so can result in lost functionality if the base control performs any operations in the AddAttributesToRender method.


The rendered HTML input control is shown here:

 <input name="ccNumericInput" type="text" maxlength="10"         size="10" id="ccNumericInput"  onkeypress="return checkKey( );"  /> 

To complete the example, we insert the control into an ASP.NET page by first registering the control (see Example 5-17). We then place the control tag in the page just as if it were a plain- vanilla text box.

One of the great advantages of inheriting from an existing ASP.NET server control is the support for all the control's inherent functionality. In this case, we can set any of the attributes available for the asp:Textbox control, even though we did no coding for those properties in our control.

 <ASPCookbook:CH05CustomControlNumericInputVB               id="ccNumericInput" runat="server"  Columns="10" MaxLength="10"  /> 

5.4.4 See Also

JavaScript: The Definitive Guide , by David Flanagan (O'Reilly), for more information on browser-specific JavaScript; ASP.NET in a Nutshell , by G. Andrew Duthie and Matthew MacDonald (O'Reilly), and the MSDN Library for more on OnPreRender and AddAttributestoRender

Example 5-15. Numeric input-only text box (.vb)
 Option Explicit On  Option Strict On '----------------------------------------------------------------------------- ' '   Module Name: CH05CustomControlNumericInputVB.vb ' '   Description: This class provides a custom control that implements an  '                input control that only allows numbers to be input. ' '***************************************************************************** Imports System Imports System.Environment Imports System.Text Imports System.Web Imports System.Web.UI Namespace ASPNetCookbook.VBExamples   Public Class CH05CustomControlNumericInputVB     Inherits System.Web.UI.WebControls.TextBox     'the following constant defines the name of the name of the client-side     'JavaScript method used to process keystrokes     Private Const CHECK_KEY_NAME As String = "checkKey"     '*************************************************************************     '     '   ROUTINE: OnPreRender     '     '   DESCRIPTION: This routine handles the prerender event for the custom     '                control.  It adds clientside script to process keys     '                before adding them to the textbox.     '-------------------------------------------------------------------------  Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)   Dim clientScript As StringBuilder   MyBase.OnPreRender(e)   'generate the opening script tag   clientScript = New StringBuilder   clientScript.Append("<script language='javascript'>" & NewLine)   clientScript.Append("<!--" & NewLine)   'generate code to check the key pressed   clientScript.Append("function " & CHECK_KEY_NAME & "( )" & NewLine)   clientScript.Append("{" & NewLine)   clientScript.Append("var key = event.keyCode;" & NewLine)   clientScript.Append("var processKey = false;" & NewLine)   clientScript.Append("if ((key >= 0x30) && (key <= 0x39))" & NewLine)   clientScript.Append("{" & NewLine)   clientScript.Append("processKey = true;" & NewLine)   clientScript.Append("}" & NewLine)   clientScript.Append("return(processKey);" & NewLine)   clientScript.Append("}" & NewLine)   'generate the closing script tag   clientScript.Append("//-->" & NewLine)   clientScript.Append("</script>" & NewLine)   'register script to be output when the page is rendered   Page.RegisterClientScriptBlock(CHECK_KEY_NAME, _   clientScript.ToString( ))   End Sub  'OnPreRender  '*************************************************************************     '     '   ROUTINE: AddAttributesToRender     '     '   DESCRIPTION: This routine handles the AddAttributeToRender event      '                for the custom control.  It adds the onkeypress      '                attribute to the textbox to cause processing of all keys     '                pressed when the textbox has focus.     '-------------------------------------------------------------------------  Protected Overrides Sub AddAttributesToRender( _   ByVal writer As System.Web.UI.HtmlTextWriter)   MyBase.AddAttributesToRender(writer)   'add an attribute to the textbox to call client script to check   'keys pressed   writer.AddAttribute("onkeypress", _   "return " & CHECK_KEY_NAME & "( );")   End Sub  'AddAttributesToRender  End Class  'CH05CustomControlNumericInputVB End Namespace 

Example 5-16. Numeric input-only text box (.cs)
 //---------------------------------------------------------------------------- // //   Module Name: CH05CustomControlNumericInputCS // //   Description: This class provides a custom control that implements an  //                input control that only allows numbers to be input. // //**************************************************************************** using System; using System.Text; using System.Web; using System.Web.UI; namespace ASPNetCookbook.CSExamples {   public class CH05CustomControlNumericInputCS :                 System.Web.UI.WebControls.TextBox   {     // the following constant defines the name of the name of the client-side     // JavaScript method used to process keystrokes     private const String CHECK_KEY_NAME = "checkKey";     //************************************************************************     //     //   ROUTINE: OnPreRender     //     //   DESCRIPTION: This routine handles the prerender event for the custom     //                control.  It adds clientside script to process keys     //                before adding them to the textbox.     //------------------------------------------------------------------------  protected override void OnPreRender(System.EventArgs e)   {   StringBuilder clientScript = null;   base.OnPreRender(e);   // generate the opening script tag   clientScript = new StringBuilder( );   clientScript.Append("<script language='javascript'>\r");   clientScript.Append("<!--\r");   // generate code to check the key pressed   clientScript.Append("function " + CHECK_KEY_NAME + "( )\r");   clientScript.Append("{\r");   clientScript.Append("var key = event.keyCode;\r");   clientScript.Append("var processKey = false;\r");   clientScript.Append("if ((key >= 0x30) && (key <= 0x39))\r");   clientScript.Append("{\r");   clientScript.Append("processKey = true;\r");   clientScript.Append("}\r");   clientScript.Append("return(processKey);\r");   clientScript.Append("}\r");   // generate the closing script tag   clientScript.Append("//-->\r");   clientScript.Append("</script>\r");   // register script to be output when the page is rendered   Page.RegisterClientScriptBlock(CHECK_KEY_NAME,   clientScript.ToString( ));   }  // OnPreRender  //************************************************************************     //     //   ROUTINE: AddAttributesToRender     //     //   DESCRIPTION: This routine handles the AddAttributeToRender event      //                 for the custom control.  It adds the onkeypress      //                 attribute to the textbox to cause processing of all      //                 keys pressed when the textbox has focus.     //------------------------------------------------------------------------  protected override void AddAttributesToRender(   System.Web.UI.HtmlTextWriter writer)   {   base.AddAttributesToRender(writer);   // add an attribute to the textbox to call client script to check   // keys pressed   writer.AddAttribute("onkeypress", "return " + CHECK_KEY_NAME + "( );");   }  // AddAttributesToRender  }  // CH05CustomControlNumericInputCS } 

Example 5-17. Using the numeric input custom control (.aspx)
 <%@ Page Language="vb" AutoEventWireup="false"    Codebehind="CH05DisplayControlWIthNumericInputVB.aspx.vb"    Inherits="ASPNetCookbook.VBExamples.CH05DisplayControlWIthNumericInputVB" %>  <%@ Register TagPrefix="ASPCookbook" Namespace="ASPNetCookbook.VBExamples"   Assembly="ASPNetCookbookVB" %>  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html>   <head>     <title>Custom Control With Numeric Input</title>     <link rel="stylesheet" href="css/ASPNetCookbook.css">   </head>   <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0">     <form id="frmCustomControl" method="post" runat="server">       <table width="100%" cellpadding="0" cellspacing="0" border="0">         <tr>           <td align="center">             <img src="images/ASPNETCookbookHeading_blue.gif">           </td>         </tr>         <tr>           <td class="dividerLine">             <img src="images/spacer.gif" height="6" border="0"></td>         </tr>       </table>       <table width="90%" align="center" border="0">         <tr>           <td><img src="images/spacer.gif" height="10" border="0"></td>         </tr>         <tr>           <td align="center" class="PageHeading">             Custom Numeric Input Control (VB)           </td>         </tr>         <tr>           <td><img src="images/spacer.gif" height="10" border="0"></td>         </tr>         <tr bgcolor="#ffffcc">           <td align="center">  <ASPCookbook:CH05CustomControlNumericInputVB   id="ccNumericInput" runat="server"   Columns="10" MaxLength="10" />  </td>         </tr>         <tr>           <td align="center">             <br>             <asp:ImageButton ID="btnSubmit" Runat="server"                   ImageUrl="images/buttons/button_submit.gif" />           </td>         </tr>       </table>     </form>   </body> </html> 



ASP. NET Cookbook
ASP.Net 2.0 Cookbook (Cookbooks (OReilly))
ISBN: 0596100647
EAN: 2147483647
Year: 2006
Pages: 179

Similar book on Amazon

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net