ASP.Net framework has a server control “TextBox” which is widely used as input control in ASP.Net web application. TextBox server control allows users to enter text (alphabets, numbers, and special characters). You might face a requirement to allow users to enter only alphabets or numbers. One way to implement this is allow users to enter any text (alphabets, numbers, and special characters) and validate the entered text before submitting the page. Second way is two allow users to enter only the allowed characters.

Recently I faced a requirement to use Numeric Text Box in an ASP.Net application, means to use a TextBox which allows users to enter only numeric characters. But such kind of server control is not available out-of-the-box in ASP.Net. To achieve this requirement, I have developed a custom server control named “NumericTextBox” which inherits ASP.Net’s default TextBox server control with new properties and functionalities. You can find below the source code of “NumericTextBox” server control written in VB.Net:

Option Explicit On

Imports System.ComponentModel

Imports System.Web.UI

 

Public Class NumericTextBox

    Inherits System.Web.UI.WebControls.TextBox

    Private _DecimalPlaces As Int32 = -1

    Private _AllowDecimal As Boolean

    Private _AllowNegative As Boolean

    Private _AutoText As Boolean

    Private js As String = "<script language='javascript'>" & vbCrLf & _

        "function extractNumber(obj, decimalPlaces, allowNegative)" & vbCrLf & _

        "{" & vbCrLf & _

        "   var temp = obj.value;" & vbCrLf & _

        "   " & vbCrLf & _

        "   // avoid changing things if already formatted correctly" & vbCrLf & _

        "   var reg0Str = '[0-9]*';" & vbCrLf & _

        "   if (decimalPlaces > 0) {" & vbCrLf & _

        "       reg0Str += '\\.?[0-9]{0,' + decimalPlaces + '}';" & vbCrLf & _

        "   } else if (decimalPlaces < 0) {" & vbCrLf & _

        "       reg0Str += '\\.?[0-9]*';" & vbCrLf & _

        "   }" & vbCrLf & _

        "   reg0Str = allowNegative ? '^-?' + reg0Str : '^' + reg0Str;" & vbCrLf & _

        "   reg0Str = reg0Str + '$';" & vbCrLf & _

        "   var reg0 = new RegExp(reg0Str);" & vbCrLf & _

        "   if (reg0.test(temp)) return true;" & vbCrLf & _

        "" & vbCrLf & _

        "   // first replace all non numbers" & vbCrLf & _

        "   var reg1Str = '[^0-9' + (decimalPlaces != 0 ? '.' : '') " & _

        "+ (allowNegative ? '-' : '') + ']';" & vbCrLf & _

        "   var reg1 = new RegExp(reg1Str, 'g');" & vbCrLf & _

        "   temp = temp.replace(reg1, '');" & vbCrLf & _

        "" & vbCrLf & _

        "   if (allowNegative) {" & vbCrLf & _

        "         // replace extra negative" & vbCrLf & _

        "         var hasNegative = temp.length > 0 && temp.charAt(0) == '-';" & vbCrLf & _

        "         var reg2 = /-/g;" & vbCrLf & _

        "         temp = temp.replace(reg2, '');" & vbCrLf & _

        "         if (hasNegative) temp = '-' + temp;" & vbCrLf & _

        "   }" & vbCrLf & _

        "   " & vbCrLf & _

        "   if (decimalPlaces != 0) {" & vbCrLf & _

        "         var reg3 = /\./g;" & vbCrLf & _

        "       var reg3Array = reg3.exec(temp);" & vbCrLf & _

        "       if (reg3Array != null) {" & vbCrLf & _

        "             // keep only first occurrence of . " & vbCrLf & _

        "             //  and the number of places specified by decimalPlaces " & _

        "or the entire string if decimalPlaces < 0" & vbCrLf & _

        "           var reg3Right = temp.substring(reg3Array.index " & _

        "+ reg3Array[0].length);" & vbCrLf & _

        "           reg3Right = reg3Right.replace(reg3, '');" & vbCrLf & _

        "           reg3Right = decimalPlaces > 0 ? reg3Right.substring(0, decimalPlaces) : reg3Right;" & vbCrLf & _

        "           temp = temp.substring(0,reg3Array.index) + '.' + reg3Right;" & vbCrLf & _

        "       }" & vbCrLf & _

        "   }" & vbCrLf & _

        "   " & vbCrLf & _

        "   obj.value = temp;" & vbCrLf & _

        "}" & vbCrLf & _

        "function blockNonNumbers(obj, e, allowDecimal, allowNegative)" & vbCrLf & _

        "{" & vbCrLf & _

        "   var key;" & vbCrLf & _

        "   var isCtrl = false;" & vbCrLf & _

        "   var keychar;" & vbCrLf & _

        "   var reg;" & vbCrLf & _

        "   " & vbCrLf & _

        "   if(window.event) {" & vbCrLf & _

        "         key = e.keyCode;" & vbCrLf & _

        "         isCtrl = window.event.ctrlKey" & vbCrLf & _

        "   }" & vbCrLf & _

        "   else if(e.which) {" & vbCrLf & _

        "         key = e.which;" & vbCrLf & _

        "         isCtrl = e.ctrlKey;" & vbCrLf & _

        "   }" & vbCrLf & _

        "   " & vbCrLf & _

        "   if (isNaN(key)) return true;" & vbCrLf & _

        "   " & vbCrLf & _

        "   keychar = String.fromCharCode(key);" & vbCrLf & _

        "         " & vbCrLf & _

        "   // check for backspace or delete, or if Ctrl was pressed" & vbCrLf & _

        "   if (key == 8 || isCtrl)" & vbCrLf & _

        "   {" & vbCrLf & _

        "         return true;" & vbCrLf & _

        "   }" & vbCrLf & _

        "   reg = /\d/;" & vbCrLf & _

        "   var isFirstN = allowNegative ? keychar == '-' && obj.value.indexOf('-') == -1 : false;" & vbCrLf & _

        "   var isFirstD = allowDecimal ? keychar == '.' && obj.value.indexOf('.') == -1 : false;" & vbCrLf & _

        "   " & vbCrLf & _

        "   return isFirstN || isFirstD || reg.test(keychar);" & vbCrLf & _

        "}" & vbCrLf & _

        "function handleFocusIn(obj)" & vbCrLf & _

        "{" & vbCrLf & _

        "   if (obj.value == 0)" & vbCrLf & _

        "   {" & vbCrLf & _

        "      obj.value = '';" & vbCrLf & _

        "   }" & vbCrLf & _

        "}" & vbCrLf & _

        "function handleFocusOut(obj, allowDecimal, decimalPlaces)" & vbCrLf & _

        "{" & vbCrLf & _

        "   var i;" & vbCrLf & _

        "   if (obj.value == '' || obj.value == 0)" & vbCrLf & _

        "   {" & vbCrLf & _

        "      obj.value = '0';" & vbCrLf & _

        "      if (allowDecimal == true)" & vbCrLf & _

        "      {" & vbCrLf & _

        "        obj.value=obj.value + '.'" & vbCrLf & _

        "        for(i=0;i<decimalPlaces;i++)" & vbCrLf & _

        "        {" & vbCrLf & _

        "           obj.value =obj.value + '0';" & vbCrLf & _

        "        }" & vbCrLf & _

        "      }" & vbCrLf & _

        "   }" & vbCrLf & _

        "}" & vbCrLf & _

        "</script>"

 

 

    Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)

        MyBase.OnPreRender(e)

        Dim decPlaces As Int32

        decPlaces = _DecimalPlaces

        Page.ClientScript.RegisterClientScriptBlock(System.Type.GetType("System.String"), "NumericValidation", js)

        Me.Attributes.Add("onchange", "extractNumber(this," & decPlaces & "," & _AllowNegative.ToString.ToLower & ");")

        Me.Attributes.Add("onkeyup", "extractNumber(this," & decPlaces & "," & _AllowNegative.ToString.ToLower & ");")

        Me.Attributes.Add("onkeypress", "return blockNonNumbers(this, event," & _AllowDecimal.ToString.ToLower & "," & _AllowNegative.ToString.ToLower & ");")

        If _AutoText = True Then

            Me.Attributes.Add("onfocusin", "return handleFocusIn(this);")

            Me.Attributes.Add("onfocusout", "return handleFocusOut(this," & _AllowDecimal.ToString.ToLower & "," & decPlaces & ");")

        End If

    End Sub

 

 

    Public Property DecimalPlaces() As Int32

        Get

            Return _DecimalPlaces

        End Get

        Set(ByVal Value As Int32)

            _DecimalPlaces = Value

        End Set

    End Property

 

 

    Public Property AllowDecimal() As Boolean

        Get

            Return _AllowDecimal

        End Get

        Set(ByVal Value As Boolean)

            _AllowDecimal = Value

        End Set

    End Property

 

 

    Public Property AutoText() As Boolean

        Get

            Return _AutoText

        End Get

        Set(ByVal Value As Boolean)

            _AutoText = Value

        End Set

    End Property

 

 

    Public Property AllowNegative() As Boolean

        Get

            Return _AllowNegative

        End Get

        Set(ByVal Value As Boolean)

            _AllowNegative = Value

        End Set

    End Property

 

 

    Private Sub NumericTextBox_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim i As Integer

        If _AutoText = True And Me.Text = "" Then

            Me.Text = "0"

            If _AllowDecimal Then

                Me.Text = Me.Text & "."

                For i = 1 To _DecimalPlaces

                    Me.Text = Me.Text & "0"

                Next

            End If

        End If

    End Sub

End Class