Introduction
All applications must be "stupids-proof", so we are creating controls that check users input, this is one of them. On this website I found only the solution for windows forms, so I'm presenting my solution for ASP.NET.
At the begining there was an idea of a control, that with these abilities:
- Optional entering negative numbers
- Optional enetring decimal numbers or integers
- Choose or load the decimal separator automatically from locale settings
- Handling Ctrl + V
- Cross-browser compatability
Solution - points of Interest
- Handling all characters - in the end I chose the "onkeypress" event, because if the function which is fired on this event returns false, the character will not be inserted into the textbox
- Filtering characters - All characters have a keyCode, so I had to make a list of allowed characters (numbers inserted by numpad buttons have different codes than numbers inserted by the top line of a keyboard), also the functional keys like Shift, BackSpace, Delete and arrows must be allowed - just a few minutes of testing
- Optional minus sign - The minus sign must be the first character of the value, so I had to check the cursor position that means problems with compatability, in the end solved like this:
function getCursorPosition(txt)
{
if(document.selection)
{
txt.focus();
var oSel = document.selection.createRange();
oSel.moveStart('character', -txt.value.length);
return oSel.text.length;
}
else(txt.selectionStart)
return txt.selectionStart;
}
- Optional decimal separator - which one? - This control allows entering decimals or integers, but different countries use different decimal separator, so I made a function that loads the settings dynamically from culture settings:
private char GetDecimalSeparatorFromLocale()
{
return (System.Globalization.CultureInfo.CurrentUICulture.NumberFormat.NumberDecimalSeparator.ToCharArray())[0];
}
- The decimal separator must meet several conditions:
- must not be the first character
- must not follow a minus sign
- there must be only one decimal separator in the value
this "beatiful" condition checks all of these conditions:
if(txt.value.replace("-", "").length > 0 && getCursorPosition(txt) > 0 && txt.value.indexOf(decimalSeparator) == -1 && decimals)
return true;
else
return false;
break;
- Handling Ctrl + V - I tried many ways to solve this problem, in the end, the simplest one worked best, on the "onchage" event a check function is fired. This function checks all characters if they are allowed or not, leave only numbers and optionally a minus sign and a decimal character
function CheckString(txt, negative, decimals, decimalSeparator)
{
var res = "";
var decimalSeparatorCount = 0;
for(i = 0; i < txt.value.length; i++)
{
if(i == 0 && txt.value.charAt(0) == "-" && negative)
res = "-";
else
{
if(IsNumber(txt.value.charAt(i)))
res += txt.value.charAt(i);
else
{
if(txt.value.charAt(i) == decimalSeparator && decimalSeparatorCount == 0 && decimals)
{
res += txt.value.charAt(i);
decimalSeparatorCount++;
}
}
}
}
txt.value = res;
}
-
Cross-browser compatability
- IE 6,7 have, as I metioned, problem with getting cursor position
- Safari returns different keyCode for functional keys - return 0 for all keys, but codes for numbers and other disallowed characters work fine
- Tested browsers: IE 6,7, Opera 9, Firefox 2, Safari for windows beta 3, Netscape 8 (same as firefox, it uses Gecko engine)
Using the code
Using this code is simple because it inherits the TextBox class, so you can use validators and access the value in the Text property.
<cp:NumericTextBox AllowNegative="true" AllowDecimals="true" runat="server" ID="NumericTextBox1" />
This control is mainly based on javascript, so it can be easily used in other platforms such as PHP, JSP etc. as well as in ASP.NET, if you translate it, please let me know.