Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Limiting characters in a text box

40 views
Skip to first unread message

Rogue Chameleon

unread,
Nov 18, 2004, 10:21:09 AM11/18/04
to
Hi all

I have a input filed of type "textbox" into which I am expecting to get
currency values (ie. 199.99). Is there a way that I can restrict the
user to only entering 2 values after the decimal point?

I can restrict the maxlength to 5, but that wouldn't stop the user from
type in 1.987.

tia
rogue chameleon

Martin Honnen

unread,
Nov 18, 2004, 10:58:33 AM11/18/04
to

Rogue Chameleon wrote:

Your best bet is to use the onchange handler e.g.
<input type="text"
onchange="validateCurrency(this);"
to validate the value entered in the text control, that works reliably
in current browsers. It might even be better to validate all controls in
the onsubmit handler of the form. You have to write the function
validateCurrency of course.
Restricting the user while he types is more difficult, there are key
events fired and you can even cancel them but in many browsers there is
no API to keep track of the caret in the text control while the key
events fire. And pasting into the text control is also not covered by
key events.

--

Martin Honnen
http://JavaScript.FAQTs.com/

McKirahan

unread,
Nov 18, 2004, 11:17:07 AM11/18/04
to
"Rogue Chameleon" <rogue.c...@gmail.com> wrote in message
news:1100791269.5...@c13g2000cwb.googlegroups.com...

JavaScript can be used though some visitor's browsers may have it disabled.

Try this though there may be a better solution that uses a regular
expression.

<html>
<head>
<title>decimals.htm</title>
<script type="text/javascript">
function decimals(that) {
var s = that.value;
var i = s.indexOf(".");
if (i >= 0 && s.substr(i+1).length > 2) {
alert("Only 2 digits to the right of the decimal are allowed!");
that.value = s.substring(0,s.length-1);
}
}
</script>
</head>
<body>
<form>
<input type="text" size="5" maxlength="5" onkeyup="decimals(this)">
</form>
</body>
</html>


McKirahan

unread,
Nov 18, 2004, 11:22:37 AM11/18/04
to
"McKirahan" <Ne...@McKirahan.com> wrote in message
news:7W3nd.113848$R05.15686@attbi_s53...

> "Rogue Chameleon" <rogue.c...@gmail.com> wrote in message
> news:1100791269.5...@c13g2000cwb.googlegroups.com...
> > Hi all
> >
> > I have a input filed of type "textbox" into which I am expecting to get
> > currency values (ie. 199.99). Is there a way that I can restrict the
> > user to only entering 2 values after the decimal point?
> >
> > I can restrict the maxlength to 5, but that wouldn't stop the user from
> > type in 1.987.
> >
> > tia
> > rogue chameleon

[snip]

This version is better as it handles the issue of cut-and-pasting a value
"1.234".

<html>
<head>
<title>decimals.htm</title>
<script type="text/javascript">
function decimals(that) {
var s = that.value;
var i = s.indexOf(".");

if (i < 0 || s.substr(i+1).length < 3) return;


alert("Only 2 digits to the right of the decimal are allowed!");

that.value = s.substring(0,i+3);

Rogue Chameleon

unread,
Nov 18, 2004, 2:41:09 PM11/18/04
to
Thanks everyone.... I'll try all posted solutions, and see which one
reacts the way I need.

rc

RobB

unread,
Nov 19, 2004, 2:03:04 AM11/19/04
to
"Rogue Chameleon" <rogue.c...@gmail.com> wrote in message news:<1100791269.5...@c13g2000cwb.googlegroups.com>...

I concur with M. Honnen's caveats in re key handlers - although
onchange can be circumvented by pasting in a copy of the same string.
Similarly, onkeyup alone will fire for mouse/keystroke pasting, but
not for menu pastes. Just for the heck of it...

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>untitled</title>
<script type="text/javascript">
//<![CDATA[

chkfld.running = false; //keep handlers separate
function chkfld(oText)
{
if (chkfld.running) //one at a time
return;
chkfld.running = true;
var msg = '', v = oText.value;
if (!/^\d*\.?\d*$/.test(v))
msg += 'Only numbers, please !';
else if (/\.\d{3,}$/.test(v))
msg += 'Only two decimal places, please !';
if (msg != '')
{
alert(msg);
oText.value = v.replace(/[^\d.]/g,
'').replace(/(\d*)(\.)(\d*)\.(\d*)/g,
'$1$2$3$4').replace(/^(\d*\.\d{2}).+$/,'$1');
return (chkfld.running = false);
}
chkfld.running = false;
}

//]]>
</script>
</head>
<body>
<form>
<input type="text" size="5" maxlength="5" onkeyup="return
chkfld(this)" onblur="return chkfld(this)" />
</form>
</body>
</html>

Tested iewin, NS7.2, Op7 - no mac handy at the moment. I'd shop this
around before using, if at all. Price is right, tho....

J. J. Cale

unread,
Nov 19, 2004, 2:15:40 AM11/19/04
to
You can use a regex to check the format.
The following should allow any number of digits before and including the
decimal point, and only two after it.
/^\d+.\d{2}$/ Checked briefly in IE6.
You can limit the user input to only digits and/or periods but that is
tantamount to terrorizing the user. Unless you have a serious reason, it is
totally unnecessary and should be avoided.

Take Martin Honnens advice and do the validation on form submission.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD><TITLE>validate currency</TITLE>
<script type=text/javascript>
function validateCurrency(sText) {
if(!/^\d+.\d{2}$/.test(sText)) {
alert('not formatted correctly');
document.forms[0].elements[0].focus();
return false;
}
return true;
}
</script>
</HEAD>
<BODY>
<form onsubmit="return validateCurrency(this.elements[0].value)">
<input type=text)></form>
</BODY></HTML>
Finally read Martins post 2 or 3 more times. Though he tends to be brief ALL
of his points are significant.
HTH
Jimbo


"Rogue Chameleon" <rogue.c...@gmail.com> wrote in message
news:1100791269.5...@c13g2000cwb.googlegroups.com...

RobB

unread,
Nov 19, 2004, 1:26:17 PM11/19/04
to
"Rogue Chameleon" <rogue.c...@gmail.com> wrote in message news:<1100806869.9...@f14g2000cwb.googlegroups.com>...

> Thanks everyone.... I'll try all posted solutions, and see which one
> reacts the way I need.
>
> rc

OK, somewhat better imo. Also minus a linefeed error inflicted by this board. :(

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>untitled</title>
<script type="text/javascript">
//<![CDATA[

$format.running = false; //keep handlers separate
function $format(fld, leaving)
{
if ($format.running) //one at a time
return;
$format.running = true;
var v = fld.value;
if (!/^\d*\.?\d*$/.test(v) || /\.\d{3,}$/.test(v))
{
fld.value = v.replace(/[^\d.]/g,'').
replace(/\.(.*)\./g,'$1.').


replace(/^(\d*\.\d{2}).+$/,'$1');

return ($format.running = false);
}
if (leaving && /\.\d$/.test(fld.value))
fld.value += '0';
$format.running = false;
}

//]]>
</script>
</head>
<body style="font-family:arial;margin:100px;"
onload="document.forms[0].foo.focus()">
<form style="font-size:100%;" onreset="foo.focus()">
&#36; <input type="text" name="foo" value="" size="8" maxlength="8"
onkeyup="return $format(this,false)"
onblur="return $format(this,true)" />
<input type="reset" value="clear" />
</form>
</body>
</html>

Rob B

unread,
Nov 21, 2004, 11:35:39 PM11/21/04
to
OK...final answer.

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>untitled</title>
<script type="text/javascript">
//<![CDATA[

$format.RE1 = /^\d*\.?\d*$/;
$format.RE2 = /\.\d{3,}$/;
$format.RE3 = /\.(?=[^.]*\.)/g;
$format.RE4 = /[^\d.]/g;
$format.RE5 = /\.(?=[^.]*\.)/g;
$format.RE6 = /^(\d*\.\d{2}).+$/;
$format.RE7 = /(\.\d{0,1})$/;

function $format(fld, leaving)
{
function sReverse(str)
{
for (var s = '', i = str.length - 1; i != -1; --i)
s += str.charAt(i);
return s;
}

var v = fld.value;
if (!$format.RE1.test(v) || $format.RE2.test(v))
{
var ltdot = (fld.dotpos == v.indexOf('.') ?
v.lastIndexOf('.') < fld.dotpos :
v.indexOf('.') < fld.dotpos);
if (ltdot)
v = sReverse(v);
v = v.replace($format.RE3,'');
if (ltdot)
v = sReverse(v);
v =
v.replace($format.RE4,'').replace($format.RE5,'').replace($format.RE6,'$
1');
fld.value = v;
}
fld.dotpos = v.indexOf('.');
if (leaving)
fld.value = v.replace($format.RE7, '$10').replace($format.RE7, '$10');
}

//]]>
</script>
</head>
<body style="font:110% arial;margin:100px;"
onload="f=document.forms[0];f.reset();f.foo.focus()">
<form onreset="foo.focus()">
$ <input type="text" name="foo" value="" size="10" maxlength="8"
style="text-align:center;border:1px black solid;"

onkeyup="return $format(this,false)"
onblur="return $format(this,true)" />
<input type="reset" value="clear" />
</form>
</body>
</html>

The O.P. seems to be long gone, so, maybe someone else can use
this...good exercise, in any event.

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!

Rogue Chameleon

unread,
Nov 23, 2004, 8:41:01 AM11/23/04
to
LOL, RobB!
Thanks for looking into this so much... your dedication is admirable :)

Rob B

unread,
Nov 23, 2004, 12:25:13 PM11/23/04
to
The Chameleon Lives! :-)
Your welcome, Rogue.

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>untitled</title>
<script type="text/javascript">
//<![CDATA[

cF.RE1 = /^\d*\.?\d*$/;
cF.RE2 = /\.\d{3,}$/;
cF.RE3 = /\.(?=[^.]*\.)/g;
cF.RE4 = /[^\d.]/g;
cF.RE5 = /\.(?=[^.]*\.)/g;
cF.RE6 = /^(\d*\.\d{2}).+$/;
cF.RE7 = /(\.\d{0,1})$/;
cF.RE8 = /^([^.]+)$/;

String.prototype.reverse = function()
{
return this.split('').reverse().join('');
}

function cF(fld, onblur)
{
var v = fld.value;
if (!cF.RE1.test(v) || cF.RE2.test(v))


{
var ltdot = (fld.dotpos == v.indexOf('.') ?
v.lastIndexOf('.') < fld.dotpos :
v.indexOf('.') < fld.dotpos);
if (ltdot)

v = v.reverse();
v = v.replace(cF.RE3,'');
if (ltdot)
v = v.reverse();
v = v.replace(cF.RE4,'').
replace(cF.RE5,'').
replace(cF.RE6,'$1');


fld.value = v;
}
fld.dotpos = v.indexOf('.');

if (onblur)
fld.value = v.replace(cF.RE7, '$10').
replace(cF.RE7, '$10').
replace(cF.RE8, '$1.00');
}

//]]>
</script>
</head>
<body style="font:100% arial;margin:300px;"

onload="f=document.forms[0];f.reset();f.foo.focus()">
<form onreset="foo.focus()">
$ <input type="text" name="foo" value="" size="10" maxlength="8"

style="font:75% arial;text-align:center;border:1px black solid;"
onkeyup="return cF(this,false)"
onblur="return cF(this,true)" />
<input type="reset" value="clear" style="font:75% arial;border:1px black
solid;" />
</form>
</body>
</html>

0 new messages