ASP.NET NumberBox Control

By Fons Sonnemans, posted on
2738 Views

The NumberBox control is an ASP.NET control, which lets the user only input numerical values. The base class of NumberBox class is the TextBox class. It uses JavaScript to validate the KeyPress event. An extra RegularExpresionValidator can be used to validate the control.

Special public properties:

  • AllowNegatives
  • DecimalPlaces
  • DecimalSymbol
  • Text
  • Value
  • ValidationRegularExpression

 

Demo

Number:     

Sample Project

NumberBox Class

using System;
using System.Web.UI;
using System.ComponentModel;
using System.Web.UI.WebControls;
using System.Text;
using System.Text.RegularExpressions;

namespace NumberBoxDemo
{
    /// <summary>
    /// Number Box ASP.NET control
    ///
    /// Created by Fons Sonnemans, Reflection IT
    ///
    /// Be sure to notice that this code is provided as a technology sample
    /// and 'as is', no warranties are made by the author.
    ///
    /// For questions and comments: Fons.Sonnemans@reflectionit.nl
    ///
    /// </summary>
    [
    ToolboxData("<{0}:NumberBox runat=server></{0}:NumberBox>"),
    DefaultProperty("DecimalPlaces")
    ]
    publicclass NumberBox : TextBox
    {

        privateintmDecimalPlaces=0;
        privatecharmDecimalSymbol='.';
        privateboolmAllowNegatives=true;

        /// <summary>
        /// Gets or sets the number of decimals for the number box.
        /// </summary>
        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue(0),
        Description("Indicates the number of decimal places to display.")
        ]
        publicvirtualint DecimalPlaces
        {
            get{return mDecimalPlaces;}
            set{mDecimalPlaces=value;}
        }

        /// <summary>
        /// Gets or sets the digit grouping symbol for the number box.
        /// </summary>
        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue("."),
        Description("The digit grouping symbol.")
        ]
        publicvirtualchar DecimalSymbol
        {
            get{return mDecimalSymbol;}
            set{mDecimalSymbol=value;}
        }

        /// <summary>
        /// Gets or sets wheter negative numbers are allowed in the number box.
        /// </summary>
        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue(true),
        Description("True when negative values are allowed")
        ]
        publicvirtualbool AllowNegatives
        {
            get{return mAllowNegatives;}
            set{mAllowNegatives=value;}
        }

        /// <summary>
        /// Gets or sets the value of the number box.
        /// </summary>
        publicvirtualdouble Value
        {
            get
            {
                try
                {
                    return ParseStringToDouble(this.Text);
                }
                catch(FormatException e)
                {
                    thrownew
                    InvalidOperationException("NumberBox does nog contain a valid Number.");
                }
                catch(Exception e)
                {
                    throw e;
                }

            }
            set
            {
                if((value < 0)&!AllowNegatives)
                    thrownew
                    ArgumentOutOfRangeException("
                    Only positivevaluesareallowedforthis NumberBox");

                //base.Text = value.ToString(this.Format);
                base.Text =value.ToString(GetFormat()).Replace(".", DecimalSymbol.ToString());
            }
        }

        /// <summary>
        /// Gets or sets the text content of the number box.
        /// </summary>
        overridepublicstring Text
        {
            get
            {
                returnbase.Text;
            }
            set
            {
                try{
                    this.Value = ParseStringToDouble(value);
                }catch (FormatException e) {
                    base.Text =value;
                }
                catch(Exception e)
                {
                    throw e;
                }
            }
        }


        /// <summary>
        ///    Add a JavaScript to the Page and call it from the onKeyPress event
        /// </summary>
        /// <param name="e"></param>
        overrideprotectedvoid OnPreRender(EventArgs e) {

            if(this.Page.Request.Browser.JavaScript ==true)
            {
                // Build JavaScript        
                StringBuilder s =new StringBuilder();
                s.Append("\n<script type='text/javascript' language='JavaScript'>\n");
                s.Append("<!--\n");
                s.Append("    function NumberBoxKeyPress(event, dp, dc, n) {\n");
                s.Append("         var myString = new String(event.srcElement.value);\n");
                s.Append("         var pntPos = myString.indexOf(String.fromCharCode(dc));\n");
                s.Append("         var keyChar = window.event.keyCode;\n");
                s.Append("     if ((keyChar < 48) || (keyChar > 57)) {\n");
                s.Append("         if (keyChar == dc) {\n");
                s.Append("             if ((pntPos != -1) || (dp < 1)) {\n");
                s.Append("                 return false;\n");
                s.Append("             }\n");
                s.Append("         } else \n");
                s.Append("if (((keyChar == 45) && (!n || myString.length != 0)) || (keyChar != 45)) \n");
                s.Append("             return false;\n");
                s.Append("     }\n");
                s.Append("     return true;\n");
                s.Append("    }\n");
                s.Append("// -->\n");
                s.Append("</script>\n");

                // Add the Script to the Page
                this.Page.RegisterClientScriptBlock("NumberBoxKeyPress", s.ToString());

                // Add KeyPress Event
                try{
                    this.Attributes.Remove("onKeyPress");
                }finally {
                    this.Attributes.Add("onKeyPress","return NumberBoxKeyPress(event, "
                                        + DecimalPlaces.ToString() +", "
                                        +((int)DecimalSymbol).ToString()+", "
                                        + AllowNegatives.ToString().ToLower() +")");
                }
            }
        }

        /// <summary>
        /// Returns the RegularExpression string which can be used for validating
        /// using a RegularExpressionValidator.
        /// </summary>
        virtualpublicstring ValidationRegularExpression
        {
            get
            {
                StringBuilder regexp= new StringBuilder();

                if(AllowNegatives)
                    regexp.Append("([-]|[0-9])");

                regexp.Append("[0-9]*");

                if(DecimalPlaces > 0)
                {
                    regexp.Append("([");
                    regexp.Append(DecimalSymbol);
                    regexp.Append("]|[0-9]){0,1}[0-9]{0,");
                    regexp.Append(DecimalPlaces.ToString());
                    regexp.Append("}$");
                }

                returnregexp.ToString();
            }
        }

        /// <summary>
        /// Parse a String to a Double
        /// </summary>
        /// <param name="s">string to be parsed to a double</param>
        /// <returns>double value</returns>
        virtualprotecteddouble ParseStringToDouble(string s)
        {
            s = s.Replace(DecimalSymbol.ToString(),".");
            returndouble.Parse(s);
        }

        /// <summary>
        /// Returns the FormatString used to display the value in the number box
        /// </summary>
        /// <returns>Format string</returns>
        virtualprotectedstring GetFormat()
        {
            StringBuilder f =new StringBuilder();
            f.Append("0");
            if(DecimalPlaces > 0)
            {
                f.Append(".");
                f.Append('0', DecimalPlaces);
            }

            return f.ToString();
        }

    }
}

Validation

You can use a normal RegularExpressionValidator control to validate the NumberBox. Invalid nummers are then rejected without causing a roundtrip to the server. Invalid numbers can still be entered using the clipboard Paste option. I don't know how to avoid this.

You can use the NumberBox.ValidationRegularExpression property to set the RegularExpressionValidator.ValidationRegularExpression property to the correct RegularExpression.

        private voidPage_Load(objectsender, System.EventArgs e)
        { 
            if(!IsPostBack)
            {
                valOne.ValidationExpression=numOne.ValidationRegularExpression;
                valTwo.ValidationExpression=numTwo.ValidationRegularExpression;
            }
        }


 

 

WebForm1.aspx

<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false"
Inherits="NumberBoxDemo.WebForm1"%>
<%@ Register TagPrefix="rit" Namespace="NumberBoxDemo" Assembly="NumberBoxDemo"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
    <HEAD>
        <metacontent="Microsoft Visual Studio 7.0"name="GENERATOR">
        <metacontent="C#"name="CODE_LANGUAGE">
        <metacontent="JavaScript (ECMAScript)"name="vs_defaultClientScript">
        <metacontent="http://schemas.microsoft.com/intellisense/ie5"name="vs_targetSchema">
    </HEAD>
    <body style="FONT-FAMILY: Verdana">
        <formid="Form1"method="post"runat="server">
            <H2>
                NumberBox Demo Page
            </H2>
            <P>
                <TABLE cellSpacing="1"cellPadding="1"width="100%"border="0">
                    <TR>
                        <TD style="WIDTH: 300px">
                            Numberbox1:
                        </TD>
                        <TD>
                            <rit:numberboxid="numOne"runat="server" DecimalSymbol=","
                             MaxLength="8" DecimalPlaces="2">
                                32,46
                            </rit:numberbox>
                        </TD>
                        <TD>
                            <asp:regularexpressionvalidatorid="valOne"runat="server"
                            ControlToValidate="numOne">
                            Invalid Number</asp:regularexpressionvalidator>
                        </TD>
                    </TR>
                    <TR>
                        <TD style="WIDTH: 300px"vAlign="top">
                            <FONT size="1">(Double, 2decimals,','&nbsp;DecimalSymbol)</FONT>
                        </TD>
                        <TD>
                        </TD>
                        <TD>
                        </TD>
                    </TR>
                    <TR>
                        <TD style="WIDTH: 300px">
                            &nbsp;
                        </TD>
                        <TD>
                        </TD>
                        <TD>
                        </TD>
                    </TR>
                    <TR>
                        <TD style="WIDTH: 300px">
                            Numberbox2:
                        </TD>
                        <TD>
                            <rit:numberboxid="numTwo"runat="server" MaxLength="8"
                             DecimalSymbol="." AllowNegatives="False">
                            </rit:numberbox>
                        </TD>
                        <TD>
                            <asp:RegularExpressionValidator id="valTwo"runat="server"
                            ControlToValidate="numTwo">
                            Invalid Number</asp:RegularExpressionValidator>
                        </TD>
                    </TR>
                    <TR>
                        <TD style="WIDTH: 300px"vAlign="top">
                            <FONT size="1">(Poisitive Integer)</FONT>
                        </TD>
                        <TD>
                        </TD>
                        <TD>
                        </TD>
                    </TR>
                    <TR>
                        <TD style="WIDTH: 300px">
                        </TD>
                        <TD>
                        </TD>
                        <TD>
                        </TD>
                    </TR>
                </TABLE>
            </P>
            <P>
            </P>
            <P>
                <asp:buttonid="btnSubmit"runat="server" Text="Submit"></asp:button>
            </P>
            <P>
                <asp:PlaceHolder id="PlaceHolder1"runat="server"></asp:PlaceHolder>
            </P>
            <P>
            </P>
        </form>
    </body>
</HTML>

WebForm1.aspx.cs

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace NumberBoxDemo
{
    /// <summary>
    /// Summary description for WebForm1.
    /// </summary>
    public class WebForm1: System.Web.UI.Page
    {
        protected NumberBoxDemo.NumberBox numOne;
        protected System.Web.UI.WebControls.RegularExpressionValidator valOne;
        protected NumberBoxDemo.NumberBox numTwo;
        protected System.Web.UI.WebControls.RegularExpressionValidator valTwo;
        protected System.Web.UI.WebControls.PlaceHolder PlaceHolder1;
        protected System.Web.UI.WebControls.Button btnSubmit;

        public WebForm1()
        {
            Page.Init +=new System.EventHandler(Page_Init);
        }

        privatevoid Page_Load(objectsender, System.EventArgs e)
        {
            // Put user code to initialize the page here

            if(!IsPostBack)
            {
                valOne.ValidationExpression =numOne.ValidationRegularExpression;
                valTwo.ValidationExpression =numTwo.ValidationRegularExpression;
            }
        }

        privatevoid Page_Init(objectsender, EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
        }

        #region Web Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        privatevoid InitializeComponent()
        {
            this.btnSubmit.Click += new System.EventHandler(this.btnSubmit_Click);
            this.Load +=new System.EventHandler(this.Page_Load);

        }
        #endregion

        privatevoidbtnSubmit_Click(object sender, System.EventArgs e)
        {
            numTwo.Value = new Random().NextDouble()*1000;

            this.PlaceHolder1.Controls.Clear();
            this.PlaceHolder1.Controls.Add(new LiteralControl(
             "Numberbox1.Value = "
             +numOne.Value.ToString()+"<br>"));
            this.PlaceHolder1.Controls.Add(new LiteralControl(
             "Numberbox1.Text = "
             +numOne.Text +"<br>"));
            this.PlaceHolder1.Controls.Add(new LiteralControl(
             "Numberbox1.ValidationRegularExpression = "
             +numOne.ValidationRegularExpression +"<br>"));
        }

    }
}

Any suggestions and feedback for improving this article is most welcome. Send your suggestions and feedback to Fons.Sonnemans@reflectionit.nl

Download

Tags

Web ASP.NET

All postings/content on this blog are provided "AS IS" with no warranties, and confer no rights. All entries in this blog are my opinion and don't necessarily reflect the opinion of my employer or sponsors. The content on this site is licensed under a Creative Commons Attribution By license.

Leave a comment

Blog comments

0 responses