...

View Full Version : stripping string to run calculation ... allow non-numeric data as input



FastCougar
01-06-2004, 11:06 PM
I have a calculator that I have written, but I now need to allow the input of large dollar amounts. Rather than throw an error if the value entered is not a number, I would like to allow someone to enter the dollar sign along with commas for large values. For example, allow someone to enter "$15,678.95" and have the javascript strip out the $ and the comma to see "15678.95" as the number. Obviously, I want to ONLY allow the commas and the dollar sign, nothing else. Is this possible? If so, how would I go about doing this??? Thanks in advance for your help!!!

Kor
01-07-2004, 09:32 AM
<head>
<script>
function bla() {
var field = document.forms[0].field1
var valo = new String();
var numere = "0123456789.$,";
var chars = field.value.split("");
for (i = 0; i < chars.length; i++) {
if (numere.indexOf(chars[i]) != -1) valo += chars[i];
else{alert("No non-numeric allowed, except $ . and ,");}
}
if (field.value != valo) field.value = valo;
}
</script>
</head>
<body>
<form>
<input name="field1" type="text" id="field1" onkeyup="bla()">
</form>
</body>
</html>

glenngv
01-07-2004, 10:20 AM
There is a similar thread (http://www.codingforums.com/showthread.php?s=&threadid=31029#post161050) for this from the same author. In that thread, I had this follow-up questions regarding invalid positions of commas (plus . and $ for that matter). I find it absurd to allow such kind of input. You're telling the user that it is a valid currency value.

Kor
01-07-2004, 10:36 AM
I find it absurd to allow such kind of input...


I agree... Furthermore, for instance, in my country (and in many other Latin cultures) we use to write 1.000.000,50$ instead of anglo-saxon $1,000,000.05

It looks easier and safer to allow 0-9 and decimal . only....

liorean
01-07-2004, 11:09 AM
How about countries that use comma instead of fullstop as decimal character, and either space, apostrophe or fullstop as thousands delimiter? And how about those that use hundreds separation instead of thousands? All of these variations (as well as a few that I have not mentioned) can be found among the European countries.

FastCougar
01-07-2004, 01:15 PM
Although I agree with these comments, this calculator will only be used by americans for their taxes as the formula's that are calculated only apply to american tax laws. Sometimes you need to put your personal difference aside and take into account:

1) Your audience/intended user base ... American Tax Payers in this case.
2) Your client's wishes ... they do after all pay the bills right?

Thanks for your help Kor. That should get me moving in the right direction. Since I am trying to learn Javascript, could you please explain what your code snippet is doing? Again, thanks for the help, it's greatly appreciated. Hopefully one day I will be compotent enough with Javascript to return the favor.

Kor
01-07-2004, 01:35 PM
<head>
<script>
function bla() {
//abbreviate the reference for future freqent use
var field = document.forms[0].field1
//make sure that the input will be treated as string and add
var valo = new String();
//define a string to include the allowed characters
var numere = "0123456789.$,";
//split this in unique characters and set each character as a var
var chars = field.value.split("");
for (i = 0; i < chars.length; i++) {
//if the character input is among the allowed let it go and add it to the previous
if (numere.indexOf(chars[i]) != -1) valo += chars[i];
//else alert...
else{alert("No non-numeric allowed, except $ . and ,");}
}
//... delete the non allowed and return the cursor after the last allowed character
if (field.value != valo) field.value = valo;
}
</script>
</head>
<body>
<form>
<!-- I added another event handler to fire the function even if copy/paste event with the mouse
-->
<input name="field1" type="text" id="field1" onkeyup="bla()" onmouseup="bla()">
</form>
</body>
</html>

FastCougar
01-07-2004, 01:38 PM
Originally posted by glenngv
There is a similar thread (http://www.codingforums.com/showthread.php?s=&threadid=31029#post161050) for this from the same author. In that thread, I had this follow-up questions regarding invalid positions of commas (plus . and $ for that matter). I find it absurd to allow such kind of input. You're telling the user that it is a valid currency value. Yes, your question in the other thread is extremely valid and I appreciate your input on how to solve this problem. After rereading Kor's solution, it appears that only the string is evaluated to contain the allowed characters. I would then need to strip out the commas and let the remaineder be viewed as a number by using parseFloat(). Obviously, your question brings up a good point ... the regulatiry and pattern to comma use in the way that americans use commas in their money strings. After some thought, I would need to detect the first comma, then count of the number of space between it and the next comma OR period. There should always be 3 characters between commas and other commas or periods. For example:

1,000,000.00 = valid because comma, 3 characters, comma, 3 characters, period.
10,0,0000.00 = invalid because there are multiple instances where there are not EXACTLY 3 characters between commas.

So, I would need to impliment a counter and reset it after every comma or period is encountered. If the counter is reset before the count of 3 or after the count of 3, I would have to throw an error. Does that sound right? Same goes for the period except now I am looking for ONLY one period ... any more than one and the value isn't a US dollar amount.

As I have always said, I appreciate the help as it is helping me learn a new language. I would rather learn what is going on that just be given the answer. I certainly am knowledgeable enough of programming techniques to understand once code snippets are posted, but I'm always affraid that I might be mis-interpriting something when reverse thinking a solution. Thanks again! You guys rock :thumbsup:

Kor
01-07-2004, 01:52 PM
...anyway, don't forget that javascript does not permit math operation if the numeric variables are written separated with commas.... That means if you need further operation you have to reconvert the input and get rid of the commas....

FastCougar
01-07-2004, 02:02 PM
Originally posted by Kor
...anyway, don't forget that javascript does not permit math operation if the numeric variables are written separated with commas.... That means if you need further operation you have to reconvert the input and get rid of the commas.... Exactly ... thus why the thread is titled "stripping string to run calculation" ;)

FastCougar
01-07-2004, 02:32 PM
OK, here is an outline of my logic, please confirm that if I can program this into javascript, that it should work:

First, some basic error checking.

1) 1st character in the sting may be a dollary symbol ($) ... make sure there is only one and that it comes first. If it's the first character, strip it from the string and move on. If there is more than one dollar symbols in the string, throw an error.

2) period symbol may be used as well, but it can only be used once and can not be the first character of our modified/unmodified string. If there is more than one period in the string, throw an error.

Now the tricky part:

3) Loop over the string and look for the first comma. If it's the first character, throw an error. Otherwise, set a flag to "true" and initialize a counter and start at 0 once the first comma is found. Each following character that is not a comma or a period incriments the count by 1. Once another comma or period is found, record the count. If the count is not exactly 3, set the flag to false and throw an error. If the count is 3 (comma being the 4th character), reinitialize the counter and continue in this fashion if the resetting character is not a period. Now the kicker ... after commas are found and the string is validated, they must all be replaced with "" (nothing) so that the string can be converted to a number with parseFloat().

So,

$1,000,000.00 = valid
$1,00,000.00 = invalid (less than 3 characters between commas)
$1,0000,0.00 = invalid (more than 3 characters between commas)
1000000.00 = valid
$1,000.00.000 = invalid (2 periods)
$1,000,000.0$0 = invalid (2 dollar symbols)

Hopefully you can see now why I need your help. This problem is hard enough for a verteran javascript programmer. Now imagine trying to solve this problem as your first javascript :D

liorean
01-07-2004, 03:12 PM
function fnValidMoney(elm){
var
sOrig = elm.value.replace(/^\s*/,'').replace(/\s*$/,''), // trim spaces
aTemp = sOrig.split(/\./), // Split at fullstop
sDec,
i;
if(aTemp.length>2)
return false:
sDec = aTemp.length != 0 && /^\d\d$/.test(aTemp[1])?
aTemp.pop():
'00'; // put decimals aside if present
aTemp = aTemp[0].split(/,/); // separate at commas
aTemp[0] = aTemp[0].replace(/^\$/,''); // remove initial dollar sign
if(!/^d{1,4}$/.test(aTemp[0]))
return false; // Accept only one to four digits in first group
i = aTemp.length;
while(0<--i)
if(!/^d{3}$/.test(aTemp[i]))
return false; // and accept only three digits in the rest of the groups
aTemp.push(sDec); // add the decimals again
alert(parseFloat(aTemp.join(''))); // alert the resulting, javascript computational number for testing
return true;
}

Try if that works. It's a bit large for that action, but this way you won't let any unwanted numbers in.

Kor
01-07-2004, 03:46 PM
First, some basic error checking...


I have answered your basic question. You have not asked (not in this thread) for further conditions... You may have had as it to the genuine code...

To liorean... no try, but I think your code is good solve.

FastCougar
01-07-2004, 06:17 PM
Originally posted by Kor
I have answered your basic question. You have not asked (not in this thread) for further conditions... You may have had as it to the genuine code...

To liorean... no try, but I think your code is good solve. Yes, and the code worked great. Thanks!

Now, I just need to get the two working together. My head is spinning from all this. Not knowing REGEX is making understanding liorean's code a nightmare :confused:

In a nutshell, the form will have 5 inputs and the values need to be checked as outlined in my previous post on my logic. The 5 inputs, once confirmed to be numbers, after the error checking and after the allowed character stripping and conversion to numbers with parseFloat(), will be used to run the calculations. I have the output code working fine with my existing inputs, but I need this error checking and stripping to finish the calculator.

liorean
01-07-2004, 06:22 PM
If you need to learn more about regular expressions, I have written a tutorial about it, you can find it in my sig.

FastCougar
01-07-2004, 07:03 PM
Originally posted by liorean
If you need to learn more about regular expressions, I have written a tutorial about it, you can find it in my sig. Thanks, after reading your tutorial, it's starting to make some sense. However, since I am so new to JavaScript, how would I call this function?

liorean
01-07-2004, 07:38 PM
Either on the onchange event of the form field, using this as argument, or in the onsubmit event of the form, sending it a reference to the form field in question as argument. Event handlers are best called like this:

<element ... onevent="return fnEventHandler(arguments...);">

FastCougar
01-07-2004, 08:01 PM
I tried to implement your code, but nothing happens. I entered "asdf" and tabbed to the next field and then entered "$1,00,000.0.0" and hit tab again ... nothing.

<head>
<script language="javascript">
function fnValidMoney(elm){
var
sOrig = elm.value.replace(/^\s*/,'').replace(/\s*$/,''), // trim spaces
aTemp = sOrig.split(/\./), // Split at fullstop
sDec,
i;
if(aTemp.length>2)
return false;
sDec = aTemp.length != 0 && /^\d\d$/.test(aTemp[1])?
aTemp.pop():
'00'; // put decimals aside if present
aTemp = aTemp[0].split(/,/); // separate at commas
aTemp[0] = aTemp[0].replace(/^\$/,''); // remove initial dollar sign
if(!/^d{1,4}$/.test(aTemp[0]))
return false; // Accept only one to four digits in first group
i = aTemp.length;
while(0<--i)
if(!/^d{3}$/.test(aTemp[i]))
return false; // and accept only three digits in the rest of the groups
aTemp.push(sDec); // add the decimals again
alert(parseFloat(aTemp.join(''))); // alert the resulting, javascript computational number for testing
return true;
}
</script>
</head>
<body>
<form>
<input name="field1" type="text" id="field1" onBlur="return fnValidMoney(this);">
<input name="field2" type="text" id="field2" onBlur="return fnValidMoney(this);">
</form>
</body>
</html>

liorean
01-07-2004, 08:28 PM
Oh, that was a slight typo. Change
if(aTemp.length>2)
return false:to
if(aTemp.length>2)
return false;

Also, change
aTemp.length != 0 to
aTemp.length > 1

FastCougar
01-07-2004, 08:45 PM
Made the change and still nothing ... no matter what I enter, nothing happens. Updated code below:
<head>
<script language="javascript">
function fnValidMoney(elm){
var
sOrig = elm.value.replace(/^\s*/,'').replace(/\s*$/,''), // trim spaces
aTemp = sOrig.split(/\./), // Split at fullstop
sDec,
i;
if(aTemp.length>2)
return false;
sDec = aTemp.length > 1 && /^\d\d$/.test(aTemp[1])?
aTemp.pop():
'00'; // put decimals aside if present
aTemp = aTemp[0].split(/,/); // separate at commas
aTemp[0] = aTemp[0].replace(/^\$/,''); // remove initial dollar sign
if(!/^d{1,4}$/.test(aTemp[0]))
return false; // Accept only one to four digits in first group
i = aTemp.length;
while(0<--i)
if(!/^d{3}$/.test(aTemp[i]))
return false; // and accept only three digits in the rest of the groups
aTemp.push(sDec); // add the decimals again
alert(parseFloat(aTemp.join(''))); // alert the resulting, javascript computational number for testing
return true;
}
</script>
</head>
<body>
<form>
<input name="field1" type="text" id="field1" onBlur="return fnValidMoney(this);">
<input name="field2" type="text" id="field2" onBlur="return fnValidMoney(this);">
</form>
</body>
</html>

Owl
01-08-2004, 12:08 AM
Hi Guys,
:
:
if(!/^\d{1,3}$/.test(aTemp[0]))
:
if(!/^\d{3}$/.test(aTemp[i]))
:
aTemp.push('.'+sDec); // add the decimals again

( ) ( )
>>V

liorean
01-08-2004, 01:32 AM
Argh! That's vBulletin's doing! Those back slashes were there in my original code. (George, does vB3 fix this, you think?)

And no, that 4 was intended to be a 4, not 3 as you changed it to. This because it is quite common for people to not insert the comma if it's just one additional digit in the first group.

The aTemp.push('.'+sDec); part needs changing entirely, to aTemp[aTemp.length]+'.'+sDec;. Also, I noticed it does not support someone not using thousands separation at all.

FastCougar
01-08-2004, 04:20 AM
OK, I'm completely lost :D

Decyphering what you two just said, I now have this as my code and it still is not working. I get no errors, just nothing happens.


<head>
<script language="javascript">
function fnValidMoney(elm){
var
sOrig = elm.value.replace(/^\s*/,'').replace(/\s*$/,''), // trim spaces
aTemp = sOrig.split(/\./), // Split at fullstop
sDec,
i;
if(aTemp.length>2)
return false;
sDec = aTemp.length>1 && /^\d\d$/.test(aTemp[1])?
aTemp.pop():
'00'; // put decimals aside if present
aTemp = aTemp[0].split(/,/); // separate at commas
aTemp[0] = aTemp[0].replace(/^\$/,''); // remove initial dollar sign
if(!/^\d{1,4}$/.test(aTemp[0]))
return false; // Accept only one to four digits in first group
i = aTemp.length;
while(0<--i)
if(!/^\d{3}$/.test(aTemp[i]))
return false; // and accept only three digits in the rest of the groups
aTemp[aTemp.length]+'.'+sDec; // add the decimals again
alert(parseFloat(aTemp.join(''))); // alert the resulting, javascript computational number for testing
return true;
}
</script>
</head>
<body>
<form>
<input name="field1" type="text" id="field1" onBlur="return fnValidMoney(this);">
<input name="field2" type="text" id="field2" onBlur="return fnValidMoney(this);">
</form>
</body>
</html>

If the board is getting in the way of properly displaying code, feel free to email me the proper code. tcole@hgl.com



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum