NumberBox ASP.NET Control


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

Requirements:

  • Microsoft Visual Studio.NET beta 2 

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")

    ]

    public class NumberBox : TextBox

    { 

        private int mDecimalPlaces = 0;

        private char mDecimalSymbol = '.';

        private bool mAllowNegatives = 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.")

        ]

        public virtual int 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.")

        ]

        public virtual char 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")

        ]

        public virtual bool AllowNegatives

        {

            get { return mAllowNegatives; }

            set { mAllowNegatives = value; }

        }

 

        /// <summary>

        /// Gets or sets the value of the number box.

        /// </summary>

        public virtual double Value

        {

            get

            {

                try

                {

                    return ParseStringToDouble(this.Text);

                }

                catch (FormatException e)

                {

                    throw new

                    InvalidOperationException("NumberBox does nog contain a valid Number.");

                }

                catch (Exception e)

                {

                    throw e;

                } 

            }

            set

            {

                if ((value < 0) & !AllowNegatives)

                    throw new

                    ArgumentOutOfRangeException("

                    Only positive values are allowed for this 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>

        override public string Text

        {

            get

            {

                return base.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>

        override protected void 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>

        virtual public string 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("}$");

                }

 

                return regexp.ToString();

            }

        }

 

        /// <summary>

        /// Parse a String to a Double

        /// </summary>

        /// <param name="s">string to be parsed to a double</param>

        /// <returns>double value</returns>

        virtual protected double ParseStringToDouble(string s)

        {

            s = s.Replace(DecimalSymbol.ToString(), ".");

            return double.Parse(s);

        }

 

        /// <summary>

        /// Returns the FormatString used to display the value in the number box

        /// </summary>

        /// <returns>Format string</returns>

        virtual protected string 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 void Page_Load(object sender, 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>

        <meta content="Microsoft Visual Studio 7.0" name="GENERATOR">

        <meta content="C#" name="CODE_LANGUAGE">

        <meta content="JavaScript (ECMAScript)" name="vs_defaultClientScript">

        <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">

    </HEAD>

    <body style="FONT-FAMILY: Verdana">

        <form id="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:numberbox id="numOne" runat="server" DecimalSymbol="," 

                              MaxLength="8" DecimalPlaces="2">

                                32,46

                            </rit:numberbox>

                        </TD>

                        <TD>

                            <asp:regularexpressionvalidator id="valOne" runat="server" 

                            ControlToValidate="numOne">

                            Invalid Number</asp:regularexpressionvalidator>

                        </TD>

                    </TR>

                    <TR>

                        <TD style="WIDTH: 300px" vAlign="top">

                            <FONT size="1">(Double, 2 decimals, ','&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:numberbox id="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:button id="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);

        }

 

        private void Page_Load(object sender, System.EventArgs e)

        {

            // Put user code to initialize the page here

 

            if (!IsPostBack)

            {

                valOne.ValidationExpression = numOne.ValidationRegularExpression;

                valTwo.ValidationExpression = numTwo.ValidationRegularExpression;

            }

        }

 

        private void Page_Init(object sender, 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>

        private void InitializeComponent()

        {

            this.btnSubmit.Click += new System.EventHandler(this.btnSubmit_Click);

            this.Load += new System.EventHandler(this.Page_Load);

 

        }

        #endregion

 

        private void btnSubmit_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>"));

        } 

    }

}