One more thing - how do I pad the final result (assuming this is a cash
balance sheet), so 2.5 will appear as 2.50?
[...]
Here's a commented example, modified to suit your circumstance.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"
http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Add form values</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<style type="text/css">
#addform input {width: 5em; text-align: right;}
..eCell {width:5em; color: red; font-weight:bold;}
</style>
<script type="text/javascript">
function updateForm(el)
{
// Declare variables
var f = el.form; // A reference to the form
var total = 0; // Initialise total as a number
var i = 1; // The first number of our 'Value' sequence
var err = false; // Has an error been found?
var erEl, m, x; // See below
// For the contiguous sequence of form controls with a name
// of 'Value1', 'Value2', ...
while ( (x=f.elements['Value' + i++]) ){
// Get the element that errors will be written to
erEl = document.getElementById('er_' + x.id);
// If validMoney doesn't return false it will return a
// formatted string
if ( (m = validMoney(x.value))){
// Clear the error element (regardless of whether it needs it)
erWrite('', erEl);
// Write the formatted value back to the control
x.value = m;
// Add the value to the total - the unary '+' converts m
// from a string to a number
total += +m;
// But if validMoney returned false, the value isn't one we like
} else {
// Warn the the user to fix the value
erWrite('Check!', erEl);
// Note that we found an error
anError = true;
}
}
// Write a value to the control named 'Total' -
// if an error was found, write nothing, else write the total
f.elements['Total'].value = (err)? '' : validMoney(total);
}
// Given an input element, write txt into it
// If no element is passed, use an alert
function erWrite(txt, el)
{
if (el) {
el.innerHTML = txt;
} else {
alert(txt);
}
}
// Check that n is a valid number. If so, return
// the formatted number. Otherwise, return false.
function validMoney(n)
{
// Convert to cents and round
var m = Math.round(n*100)+'';
// Add a leading zero if the number is less than 10
// If above made m 'NaN', test is false, no added zero
if (m<10) m = '0' + m;
// Return false if m is not a number (isNaN)
// or a formatted string if it is.
return (isNaN(m))? false :
(m/100 | 0) + '.' + m.substring(m.length-2);
// m/100 | 0 returns the integer part of m/100 or
// zero if the result is less than 1 - c.f. Math.floor(m/100)
// m.substring(...) returns the last two characters of m.
}
</script>
</head>
<body>
<!--
The form controls that will have their values added are named
Value1, Value2, etc. in a contiguous sequence.
Each has an associated element that error messages are
written to. The error element has an ID of the associated
control ID prefixed by 'er_'.
e.g. for Value1 the associated error element is er_Value1.
Errors are written using innerHTML.
The total is written to a control call 'Total'
-->
<form name="addform" id="addform" action="">
<table>
<tr>
<td>Value 1:</td>
<td><input type="text" name="Value1" id="Value1" value=".04"
onblur="updateForm(this);"></td>
<td class="eCell" id="er_Value1"></td>
</tr>
<tr>
<td>Value 2:</td>
<td><input type="text" name="Value2" id="Value2" value="200"
onblur="updateForm(this);"></td>
<td class="eCell" id="er_Value2"></td>
</tr>
<tr>
<td>Value 3:</td>
<td><input type="text" name="Value3" id="Value3" value="1."
onblur="updateForm(this);"></td>
<td class="eCell" id="er_Value3"></td>
</tr>
<tr>
<td>Total:</td>
<td><input type="text" name="Total" id="Total" readonly></td>
<td><input type="reset"></td>
</tr>
</table>
</form>
</body>
</html>