Recipe 6.6. Customizing an ASP.NET TextBox Server Control


Problem

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

Solution

Create a custom control that inherits from the ASP.NET text box control and 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 TextBox class in the System.Web.UI.WebControls 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.

Examples 6-20 and 6-21 show the VB and C# class files for an example custom control 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 6-22 shows how to use the custom control in an ASP.NET page.

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 only have to write 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, none of the ASP.NET controls provides this functionality. 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.ClientScript. 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.


Output the client script using the Page.ClientScript.RegisterClientScriptBlock method with the first parameter set to the type of your control. This ensures that client script is output to the page only once if multiple instances of your control are used on a page. 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 output to the page in our example is shown next. It checks each key press to see if the keycode is in the 09 range and returns TRue if it is. Otherwise, it returns false.

 <script type="text/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 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, 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="ctl00$PageBody$ccNumericInput" type="text"   maxlength="10" size="10"      onkeypress="return checkKey();" /> 

To complete the example, we insert the control into an ASP.NET page by first registering the control (see Example 6-22). 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, though we did no coding for those properties in our control:

 <ASPCookbook:CH06CustomControlNumericInputVB  runat="server" Columns="10" MaxLength="10" /> 

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 6-20. Numeric input-only text box (.vb)

 Option Explicit On Option Strict On Imports System.Environment Imports System.Web.UI Namespace ASPNetCookbook.VBExamples ''' <summary> ''' This class provides a custom control that implements an input control ''' that only allows numbers to be input. ''' </summary> Public Class CH06CustomControlNumericInputVB   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" '''*********************************************************************** ''' <summary> ''' This routine handles the prerender event for the custom control. ''' It adds clientside script to process keys before adding them to ''' the text box. ''' </summary> ''' ''' <param name="e">Set to the event arguments</param> Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)   Dim scriptBlock As StringBuilder     MyBase.OnPreRender(e) 'generate code to check the key pressed scriptBlock = New StringBuilder scriptBlock.Append("function " & CHECK_KEY_NAME & "( )" & NewLine) scriptBlock.Append("{" & NewLine) scriptBlock.Append("var key = event.keyCode;" & NewLine) scriptBlock.Append("var processKey = false;" & NewLine) scriptBlock.Append("if ((key >= 0x30) && (key <= 0x39))" & NewLine) scriptBlock.Append("{" & NewLine) scriptBlock.Append("processKey = true;" & NewLine) scriptBlock.Append("}" & NewLine) scriptBlock.Append("return(processKey);" & NewLine) scriptBlock.Append("}" & NewLine) 'register script to be output when the page is rendered Page.ClientScript.RegisterStartupScript(Me.GetType( ), _ CHECK_KEY_NAME, _ scriptBlock.ToString( ), _ True) End Sub 'OnPreRender '''*********************************************************************** ''' <summary> ''' This routine handles the AddAttributeToRender event for the custom ''' control. It adds the onkeypress attribute to the text box to cause ''' processing of all keys pressed when the text box has focus. ''' </summary> ''' ''' <param name="writer">Set to the HtmlTextWriter to use to output the ''' rendered HTML for the control ''' </param> Protected Overrides Sub AddAttributesToRender( _ ByVal writer As HtmlTextWriter) MyBase.AddAttributesToRender(writer) 'add an attribute to the text box to call client script to check 'keys pressed writer.AddAttribute("onkeypress", _ "return " & CHECK_KEY_NAME & "( );") End Sub 'AddAttributesToRender   End Class 'CH06CustomControlNumericInputVB End Namespace 

Example 6-21. Numeric input-only text box (.cs)

 using System; using System.Drawing; using System.Text; using System.Web.UI; using System.Web.UI.WebControls; namespace ASPNetCookbook.CSExamples { /// <summary> /// This class provides a custom control that implements an input control /// that only allows numbers to be input. /// </summary> public class CH06CustomControlNumericInputCS : 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"; ///*********************************************************************** /// <summary> /// This routine handles the prerender event for the custom control. It /// adds clientside script to process keys before adding them to the /// text box. /// </summary> /// /// <param name="e">Set to the event arguments</param> protected override void OnPreRender(System.EventArgs e) {   StringBuilder scriptBlock = null;   base.OnPreRender(e);   // generate code to check the key pressed   scriptBlock = new StringBuilder( );   scriptBlock.Append("function " + CHECK_KEY_NAME + "( )\r");   scriptBlock.Append("{\r");   scriptBlock.Append("var key = event.keyCode;\r");   scriptBlock.Append("var processKey = false;\r");   scriptBlock.Append("if ((key >= 0x30) && (key <= 0x39))\r");   scriptBlock.Append("{\r");   scriptBlock.Append("processKey = true;\r");   scriptBlock.Append("}\r");   scriptBlock.Append("return(processKey);\r");   scriptBlock.Append("}\r");   // register script to be output when the page is rendered   Page.ClientScript.RegisterStartupScript(this.GetType( ), CHECK_KEY_NAME, scriptBlock.ToString( ), true); } // OnPreRender //************************************************************************ // // ROUTINE: AddAttributesToRender // // DESCRIPTION: //------------------------------------------------------------------------ /// <summary> /// This routine handles the AddAttributeToRender event for the custom /// control. It adds the onkeypress attribute to the text box to cause /// processing of all keys pressed when the text box has focus. /// </summary> /// /// <param name="writer">Set to the HtmlTextWriter to use to output the /// rendered HTML for the control /// </param> protected override void AddAttributesToRender( System.Web.UI.HtmlTextWriter writer) { base.AddAttributesToRender(writer); // add an attribute to the text box to call client script to check // keys pressed writer.AddAttribute("onkeypress", "return " + CHECK_KEY_NAME + "( );"); } // AddAttributesToRender   } // CH06CustomControlNumericInputCS } 

Example 6-22. Using the numeric input custom control (.aspx)

 <%@ Page Language="VB" MasterPageFile="~/ASPNetCookbookVB.master"   AutoEventWireup="false"   CodeFile="CH06DisplayControlWithNumericInputVB.aspx.vb"   Inherits="ASPNetCookbook.VBExamples.CH06DisplayControlWithNumericInputVB"   Title="Custom Control With Numeric Input" %> <%@ Register TagPrefix="ASPCookbook" Namespace="ASPNetCookbook.VBExamples" %> <asp:Content  runat="server" ContentPlaceHolder>   <div align="center" > Custom Numeric Input Control (VB)   </div>   <table width="90%" align="center" border="0">     <tr bgcolor="#ffffcc">   <td align="center">     <ASPCookbook:CH06CustomControlNumericInputVB  runat="server" Columns="10" MaxLength="10" /> </td>   </tr>   <tr> <td align="center"> <br/> <asp:Button  runat="server" Text="Submit" /> </td>   </tr>    </table> </asp:Content> 



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

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