Like I was saying, the javascript needs to be tailored to what each form element is and what it represents. From what you're saying, you may need to pass more information to calculateTotal or get more information from each form element that invokes it. A class could be given to the checkboxes that you want to fire calculateTotal, for instance - say 'clac'. And you could grab all select elements. For those, the function that assigns events would be:
Code:
(function(){
var form, puts = (form = document.forms.selectionForm).elements;
form.onreset = function(){InitForm(); return false;};
for (var i = puts.length - 1; i > -1; --i) {
if (puts[i].type === 'radio') {
puts[i].onclick = function(){calculateTotal(this);};
} else if (puts[i].type === 'checkbox' && puts[i].className === 'calc') { // only grabs checkboxes with the class 'calc'
puts[i].onclick = function(){calculateTotal(this);};
} else if (puts[i].tagName.toLowerCase() === 'select') { // grabs all select elements
puts[i].onchange = function(){calculateTotal(this);};
} else if (puts[i].name === 'total') {
puts[i].onfocus = function(){this.blur();};
}
}
})();
But once you get up into the calculateTotal() function, perhaps you need to treat some or each of the elements differently to get the result you're after.
Another thing to consider is that with the original script and all versions I've put forward so far, each time calculateTotal() is run, it works off of the previous total, adding to and/or subtracting from it to get the new total.
But you could use a different approach, starting each run of calculateTotal() with the total set to 0, check each element that can impact the total and add it up from scratch each time. As more and more elements get added and the actions to take for each one become more diverse, this is perhaps easier to work with, for example (this one also fixes the problem with multiple sized pizzas I mentioned before):
Code:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!-- Paste this code into an external JavaScript file (remove the opening and closing <script> tags) -->
<script type="text/javascript">
/* This script and many more are available free online at
The JavaScript Source :: http://javascript.internet.com
Created by: Kevin Hartig :: http://www.grafikfx.net/ */
// Calculate the total for items in the form which are selected.
function calculateTotal(inputItem) {
var calculatedTotal = multiplier = i = 0, form = inputItem.form, els = form.elements, tot;
for(i; i < els.length; ++i){
if (els[i].type === "checkbox" && els[i].checked) {
calculatedTotal += +els[i].value;
++multiplier;
} else if (els[i].type === "radio" && els[i].checked) {
calculatedTotal += els[i].value * (multiplier || 1);
}
}
calculatedTotal *= form.quantity.value;
// Total value should never be less than 0.
if (calculatedTotal < 0) {
InitForm();
return;
}
// Set total field(s) to total value.
tot = formatCurrency(calculatedTotal);
for (i = form.total.length - 1; i > -1; --i){
form.total[i].value = tot;
}
}
// Format a value as currency.
function formatCurrency(num) {
num = num.toString(10).replace(/[$,]/g,'');
if(isNaN(num)){num = 0;}
return ((num == (num = Math.abs(num))?'':'-') + '$' + num.toFixed(2));
}
// This function initialzes all the form elements to default values.
function InitForm(form) {
// Reset values on form.
var tots = form.total, els = form.elements;
for (var i = tots.length - 1; i > -1; --i){
tots[i].value = '$0.00';
}
// Set all checkboxes and radio buttons on form to unchecked.
for (i = els.length - 1; i > -1; --i){
if (els[i].checked) {
els[i].checked = false;
} else if (els[i].tagName.toLowerCase() === 'select'){
els[i].options.selectedIndex = 0;
}
}
}
</script>
<!-- Paste this code into the HEAD section of your HTML document
Change the file name and path to match the one you created
<script type="text/javascript" src="yourFileName.js"></script> -->
<style type="text/css">
form {
font: normal 90% verdana, helvetica, arial, sans-serif;
}
fieldset, legend {
border: 2px solid #aaa;
border-radius: 7px;
}
legend {
padding: 3px 5px;
font-weight: bold;
font-size: 90%;
}
form b {
font-size: 110%;
}
</style>
</head>
<body>
<!-- Paste this code into the BODY section of your HTML document -->
<div style="width: 430px; margin: auto;">
<form method="post" name="selectionForm">
<b>Pizza Order</b><br><br>
<fieldset><legend>Choose Size(s)</legend>
<label>Small $10.00
<input type="checkbox" name="small" value="10.00" ></label>
<label>Medium $12.00
<input type="checkbox" name="medium" value="12.00"></label>
<label>Large $15.00
<input type="checkbox" name="large" value="15.00" ></label>
<br><br>
<strong>Your total is:</strong>
<input type="text" name="total" readonly>
</fieldset>
<br><br>
<fieldset><legend>Extra Toppings (only one selection allowed)</legend>
<label><input type="radio" name="Sauce" value="0.00"> None</label>
<br>
<label><input name="Sauce" type="radio" value="1.00"> Extra Cheese $1.00</label>
<br>
<label><input type="radio" name="Sauce" value="2.00"> Vegetarian $2.00</label>
<br>
<label><input type="radio" name="Sauce" value="3.00"> Meat $3.00</label>
<br><br>
<strong>Your total is:</strong>
<input type="text" name="total" readonly>
</fieldset>
<br><br>
<fieldset><legend>Quantity</legend>
<select name="quantity">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</fieldset>
<br><br>
<strong>Your total is:</strong>
<input type="text" name="total" readonly>
<input type="reset">
</form>
</div>
<p><div style="text-align: center;">
<span style="font: normal 10px arial, helvetica, sans-serif;">Free JavaScripts provided<br>
by <a href="http://javascriptsource.com">The JavaScript Source</a></span>
</div><p>
<script type="text/javascript">
(function(){
var form = document.forms.selectionForm, puts = form.elements;
InitForm(form);
form.onreset = function(){InitForm(this); return false;};
for (var i = puts.length - 1; i > -1; --i){
if(/radio|checkbox/.test(puts[i].type)){
puts[i].onclick = function(){calculateTotal(this);};
} else if (puts[i].name === 'quantity') {
puts[i].onchange = function(){calculateTotal(this);};
} else if (puts[i].name === 'total') {
puts[i].onfocus = function(){this.blur();};
}
}
})();
</script>
</body>
</html>
When I have more time, I'll look at your code and see what I can make of it. From what you're saying there may need to be separate totals for certain areas of the form and then perhaps a grand total at the end. That can be done, but the code gets more complicated.
The bottom line is there's no one size fits all for this sort of thing, we have to make it do what you want/need it to do.
Bookmarks