currency format

M

Michael Hill

I found this javascript on javascript.internet.com and it returns a
decimal value i.e. 88,999.45 and if I didn't want a decimal value
returned what changes should I make. Given the example above I'd like to
return 8,899,945.

Any help is appreciated. Mike
<form>
Enter Value:
<input type=text name=test length=15
onKeyPress="return(currencyFormat(this,',','.',event))">
</form>

function currencyFormat(fld, milSep, decSep, e)
{
var sep = 0;
var key = '';
var i = j = 0;
var len = len2 = 0;
var strCheck = '0123456789';
var aux = aux2 = '';
var whichCode = (window.Event) ? e.which : e.keyCode;
if (whichCode == 13) return true; // Enter
key = String.fromCharCode(whichCode); // Get key value from key code
if (strCheck.indexOf(key) == -1) return false; // Not a valid key
len = fld.value.length;
for(i = 0; i < len; i++)
if ((fld.value.charAt(i) != '0') && (fld.value.charAt(i) != decSep))
break;
aux = '';
for(; i < len; i++)
if (strCheck.indexOf(fld.value.charAt(i))!=-1) aux +=
fld.value.charAt(i);
aux += key;
len = aux.length;
if (len == 0) fld.value = '';
if (len == 1) fld.value = '0'+ decSep + '0' + aux;
if (len == 2) fld.value = '0'+ decSep + aux;
if (len > 2) {
aux2 = '';
for (j = 0, i = len - 3; i >= 0; i--) {
if (j == 3) {
aux2 += milSep;
j = 0;
}
aux2 += aux.charAt(i);
j++;
}
fld.value = '';
len2 = aux2.length;
for (i = len2 - 1; i >= 0; i--)
fld.value += aux2.charAt(i);
fld.value += decSep + aux.substr(len - 2, len);
}
return false;
}
 
Y

Yep

Michael Hill said:
Given the example above I'd like to
return 8,899,945.

<script type="text/javascript">
function f(field){
if(/^\d+$/.test(field.value))
field.value=field.value.split("").reverse().join("").
replace(/(\d{3})/g,"$1,").
replace(/,$/,"").
split("").reverse().join("");
}
</script>
<input type="text" onblur="f(this)">

(after a conception by Boniface Lau, IIRC)
 
L

Lasse Reichstein Nielsen

replace(/(\d{3})/g,"$1,").
replace(/,$/,"").

These two lines can be shortened to one as
replace(/(\d{3})\B/g,"$1,").
The "\B" matches a zero-width non-word-boundary, so it will not add a
comma after the end of the string.

Why do I find it annoying that it is necessary to reverse the string,
when I know that regular languages are indifferent to direction?

/L
 
L

Lasse Reichstein Nielsen

Lasse Reichstein Nielsen said:
Why do I find it annoying that it is necessary to reverse the string,
when I know that regular languages are indifferent to direction?

Hmm, as an (almost) completely unrelated side note ...
The regular expressions of Javascript (or Perl) are actually more
powerful that "real" regular expressions, in the sense that they
recognize languages that are not regular (or even recursive).
So my annoyance is misplaced.

Bonus points for telling which strings (containing only the digit 1)
this RegExp recognizes: /^(?!(11+)\1+$)/

/L
 
Y

Yep

Well in our case you're not obliged to reverse the string, you could
also use something like
/(?=(\d{3})+\b)/g
and remove the leading comma with another replace. In languages
supporting lookbehind operators (not js) that'd be even easier.
Bonus points for telling which strings (containing only the digit 1)
this RegExp recognizes: /^(?!(11+)\1+$)/

Your chain could be only of the form 1+, so the first (11+) will match
all the 1 of the string (being greedy), that is, all the string. Then
the backtracking starts; the first possible match is when the regexp
has backtracked half part of it (division by 2); we'd have (11+) ==
\1. If it cannot succeed, then it continues backtracking until the
initial number of one can be "divided by three", i.e. we'd have 111
for the (11+) part, (111)(111) for the \1+. If it cannot succeed, then
it goes on...

To conclude, the regexp will try have have n parts of equal number of
"1", with n belonging to [1; N]. If the regexp cannot succeed, this
means it has not been able to make the correct repartion; put it
another way, the number cannot be divided by any of [1; N-1]. So your
regexp will match any prime number of "1".

I'm not a regexp expert, but the way I understand how regexps work,
that'd be quite heavy a calculation just to get prime numbers
(especially since the \1+ would imply far more states than actually
described in my explanation).


Regards,
Yep.
 
L

Lasse Reichstein Nielsen

Well in our case you're not obliged to reverse the string, you could
also use something like
/(?=(\d{3})+\b)/g
and remove the leading comma with another replace. In languages
supporting lookbehind operators (not js) that'd be even easier.

Smart move! It can even get better:
string.replace(/(?=(\d{3})+$)\B/g,",")
replaces the non-boundary with a positive multiple of three number of
digits after it.
So your regexp will match any prime number of "1".

Bonus points gøs to you.
The point of that exercise was not to show how inefficient it could get,
but to point out that it was possible at all.

The theory of regular languages tells us that they can be recognized
by a finite state machine. Regular expressions have been compiled into
such state machines (in, e.g., lexical analysers like Lex or Flex,
that work in linear time without backtracking (building the state
machine is hard work, though)).

The addition of the back reference (\1) changes the computational
power of the "regular expressions". They can now recognize a language
(like primes in unary notation) that is not regular. It is recursive,
meaning that it requires the equivalent of a Turing machine to
recognize ... or a general purpose computer. It can no longer be
implemented in finite space and without backtracking.

In practice, nobody complains, because we already have the entire
string in memory.

/L
 
Y

Yep

Lasse Reichstein Nielsen said:
string.replace(/(?=(\d{3})+$)\B/g,",")
replaces the non-boundary with a positive multiple of three number of
digits after it.

Seems perfect, I'm just unfamiliar with \B, although I do use nonword
boundaries every day :)
Bonus points gøs to you.

I'd rather get a beer. Thanks anyway.
The addition of the back reference (\1) changes the computational
power of the "regular expressions". They can now recognize a language
(like primes in unary notation) that is not regular.

Never going to bed without my ECMA copy, I can tell you there's a GCD
regexp (or iregexp should I say) that will please you in the regexp
algorithms part (you may already have read it).


Cheers,
Yep 'simple machine'.
 
D

Dr John Stockton

JRS: In article <[email protected]>, seen in
news:comp.lang.javascript said:
Smart move! It can even get better:
string.replace(/(?=(\d{3})+$)\B/g,",")
replaces the non-boundary with a positive multiple of three number of
digits after it.

Such solutions seem to need a warning that only browsers later than ...
can handle them.

Various perhaps more compatible ways to insert commas are in my
<URL:http://www.merlyn.demon.co.uk/js-maths.htm#OutComma>. The
shortest, albeit heavily criticised, of those is :-

function RComma(S) { S = String(S)
var RgX = /^(.*\s)?([-+\u00A3\u20AC]?\d+)(\d{3}\b)/
return S == (S=S.replace(RgX, "$1$2,$3")) ? S : RComma(S) }

which will comma-ise the integer parts of all numbers in S, in at least
MSIE4 & presumably later. A "g" at the end of RgX is optional. A
number must be preceded by whitespace or nothing at all.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top