www.webdeveloper.com
Page 1 of 3 123 LastLast
Results 1 to 15 of 44

Thread: Javascript sums for 2 different sub total fields help

  1. #1
    Join Date
    Apr 2014
    Posts
    36

    Javascript sums for 2 different sub total fields help

    Hello, I have a form that has item 1 - item 1's cost is determined by the length and width (square feet) and by the material price. This generates totalcost (for item 1)

    Same thing happens for item 2.. This generates totalcost2 (for item2)

    Now I need to create a function that will grab the content/values of these totals and display a TOTAL VALUE.. I would think this would be simple but I can't seem to figure it out.

    Again totalcost + totalcost2 = grandTotal

    Any help would be appreciated - function code and html for webpage.
    Thx

  2. #2
    Join Date
    Mar 2005
    Location
    Behind you...
    Posts
    873
    Do you have any code at all to base this off of? I'd like to see what you have so I know exactly what you need added.

    In your original post your equation would appear to be correct for the most part, thus I don't think I understand what you are needing in order to get your page working as desired. Is it that you aren't getting the right value? If that's the case you merely need to make sure you add the values as numbers (and not strings).
    Code:
    var grandTotal = Number(totalcost) + Number(totalcost2);
    var grandTotal = (totalcost * 1) + (totalcost2 * 1);
    There's two simple ways to force the variables to numbers before adding (to ensure it doesn't concat them as strings).

    Or is your problem just that you need a function to return the sum of these values? (though I feel a function is unecessary, you could just combine the totals elsewhere).
    Code:
    function _GetTotal($a, $b) {
      return ($a * 1) + ($b * 1);
    }
    
    var totalcost = 123;
    var totalcost2 = 456;
    var grandTotal = _GetTotal(totalcost, totalcost2);
    Again, I'm not really sure what you are asking in context. You already seem to have a working system for most of this, just not the grand total, however it's hard to tell you what to do in relation to your code, since none of that is here for reference. So if you need the grand total displayed on the page for example, we here at the forum have no idea where to display it on the page without seeing code. Or if you already have something set up to do this but it just isn't working right, we here at the forum cannot fix the code you have without seeing it.
    "Given billions of tries, could a spilled bottle of ink ever fall into the words of Shakespeare?"

  3. #3
    Join Date
    Dec 2005
    Location
    FL
    Posts
    7,377

    Red face

    Quote Originally Posted by Sup3rkirby View Post
    "Given billions of tries, could a spilled bottle of ink ever fall into the words of Shakespeare?"
    Stupid side question: "into" or "onto"?
    My stupid guess answer: "no" or "yes".

    Additional information request: Are we near any gravity?

  4. #4
    Join Date
    Apr 2014
    Posts
    36
    Hi, thanks for the quick reply. Below is the code.
    I was trying to add the grandtotal code to the file calculator.js with these functions which basically add calculate the square footage and the price of each item.

    function Calculate(frm) {
    var order_total, length, width, i;
    order_total = 0;


    length = parseFloat(frm.length.value);
    width = parseFloat(frm.width.value);

    if (length > 0 && width > 0) {
    order_total = length * width;
    for (i = 0; i < frm.tooling.length; i++) {
    if (frm.tooling[i].value === "withouttooling" && frm.tooling[i].checked === true) {
    order_total = order_total * ".30";
    }
    if (frm.tooling[i].value === "withtooling" && frm.tooling[i].checked === true) {
    order_total = order_total * ".40";
    }
    }
    //order_total = order_total * .35
    order_total = order_total + 25;
    }
    else {
    order_total = 0;
    }

    // Run through all the form fields
    //for (var i=0; i < frm.elements.length; ++i) {

    // Get the current field
    //form_field = frm.elements[i]

    // Get the field's name
    //form_name = form_field.name

    // Is it a "product" field?
    //if (form_name.substring(0,4) == "PROD") {

    // If so, extract the price from the name
    //item_price = parseFloat(form_name.substring(form_name.lastIndexOf("_") + 1))

    // Get the quantity
    //item_quantity = parseInt(form_field.value)

    // Update the order total
    //if (item_quantity >= 0) {
    //order_total += item_quantity * item_price
    //}
    //}
    //}

    // Display the total rounded to two decimal places
    frm.totalcost.value = '$ ' + round_decimals(order_total, 2);
    }

    function round_decimals(original_number, decimals) {
    var result1 = original_number * Math.pow(10, decimals);
    var result2 = Math.round(result1);
    var result3 = result2 / Math.pow(10, decimals);
    return pad_with_zeros(result3, decimals);
    }

    function pad_with_zeros(rounded_value, decimal_places) {

    // Convert the number to a string
    var value_string = rounded_value.toString();

    // Locate the decimal point
    var decimal_location = value_string.indexOf(".");

    // Is there a decimal point?
    if (decimal_location == -1) {

    // If no, then all decimal places will be padded with 0s
    decimal_part_length = 0;

    // If decimal_places is greater than zero, tack on a decimal point
    value_string += decimal_places > 0 ? "." : "";
    }
    else {

    // If yes, then only the extra decimal places will be padded with 0s
    decimal_part_length = value_string.length - decimal_location - 1;
    }

    // Calculate the number of decimal places that need to be padded with 0s
    var pad_total = decimal_places - decimal_part_length;

    if (pad_total > 0) {

    // Pad the string with 0s
    for (var counter = 1; counter <= pad_total; counter++) {
    value_string += "0";
    }
    }
    return value_string;
    }


    function Calculateitem2(frm) {
    var order_total2, length2, width2, i;
    order_total2 = 0;


    length = parseFloat(frm.length2.value);
    width = parseFloat(frm.width2.value);

    if (length > 0 && width > 0) {
    order_total2 = length * width;
    for (i = 0; i < frm.tooling2.length; i++) {
    if (frm.tooling2[i].value === "withouttooling" && frm.tooling2[i].checked === true) {
    order_total2 = order_total2 * ".30";
    }
    if (frm.tooling2[i].value === "withtooling" && frm.tooling2[i].checked === true) {
    order_total2 = order_total2 * ".40";
    }
    }
    //order_total2 = order_total2 * .35
    order_total2 = order_total2 + 25;
    }
    else {
    order_total2 = 0;
    }

    // Run through all the form fields
    //for (var i=0; i < frm.elements.length; ++i) {

    // Get the current field
    //form_field = frm.elements[i]

    // Get the field's name
    //form_name = form_field.name

    // Is it a "product" field?
    //if (form_name.substring(0,4) == "PROD") {

    // If so, extract the price from the name
    //item_price = parseFloat(form_name.substring(form_name.lastIndexOf("_") + 1))

    // Get the quantity
    //item_quantity = parseInt(form_field.value)

    // Update the order total
    //if (item_quantity >= 0) {
    //order_total2 += item_quantity * item_price
    //}
    //}
    //}

    // Display the total rounded to two decimal places
    frm.totalcost2.value = '$ ' + round_decimals(order_total2, 2);
    }

    function round_decimals(original_number, decimals) {
    var result1 = original_number * Math.pow(10, decimals);
    var result2 = Math.round(result1);
    var result3 = result2 / Math.pow(10, decimals);
    return pad_with_zeros(result3, decimals);
    }

    function pad_with_zeros(rounded_value, decimal_places) {

    // Convert the number to a string
    var value_string = rounded_value.toString();

    // Locate the decimal point
    var decimal_location = value_string.indexOf(".");

    // Is there a decimal point?
    if (decimal_location == -1) {

    // If no, then all decimal places will be padded with 0s
    decimal_part_length = 0;

    // If decimal_places is greater than zero, tack on a decimal point
    value_string += decimal_places > 0 ? "." : "";
    }
    else {

    // If yes, then only the extra decimal places will be padded with 0s
    decimal_part_length = value_string.length - decimal_location - 1;
    }

    // Calculate the number of decimal places that need to be padded with 0s
    var pad_total = decimal_places - decimal_part_length;

    if (pad_total > 0) {

    // Pad the string with 0s
    for (var counter = 1; counter <= pad_total; counter++) {
    value_string += "0";
    }
    }
    return value_string;
    }

  5. #5
    Join Date
    Apr 2014
    Posts
    36
    html form code
    <form class="order-form" method="post" action="emaileverything.php">
    <ul class="colleft">
    <li>
    <p>Company<br/><br />
    <input name="company"></p>
    <p>Contact<br/><br />
    <input name="contact"></p>
    <p>Address<br/><br />
    <input name="address"></p>
    <p>City<br/><br />
    <input name="city"></p>
    <p>State/Province<br/></p>
    <select size="1" name="state">
    <option selected="selected" value=""></option>
    <p><optgroup label="United States"></p>
    <option value="AL">Alabama</option>
    <p></optgroup><br />
    <optgroup label="Canadian Provinces"></p>
    <option value="AB">Alberta</option>
    <p></optgroup><br />
    </select>
    </p>
    <p>Zip/Postal Code<br/><br />
    <input name="Zip"></p>
    <p>Phone<br/><br />
    <input name="phone"></p>
    <p>Email address<br/><br />
    <input name="email"></p>
    <p>Fax<br/><br />
    <input name="fax"></p>
    <p>Shipping address<br />
    <input class="checkbox" name="shipping" type="checkbox"><small>(Same)</small><br/><br />
    <textarea style="WIDTH: 202px; HEIGHT: 50px" rows="1" name="shippingaddress"></textarea><br/><br />
    <br/><br />
    Comments<br/><br />
    <textarea style="WIDTH: 202px; HEIGHT: 44px" rows="1" cols="50" name="comments"></textarea>&nbsp;<br/>
    </p>
    </li>
    <p><strong>Item 1</strong><BR>
    <li><input class="checkbox" name="colorcardonly" type="checkbox"><strong>Order color card only</strong></p>
    <p>Dimensions of leather to the nearest .25 <br/></p>
    <p>Width<br />
    <input class="short" onchange="Calculate(this.form)" name="width"><small>(in)</small><br/><br />
    Length<br />
    <input class="short" onchange="Calculate(this.form)" name="length"><small>(in)</small></p>
    <p><input class="checkbox" onclick="Calculate(this.form)" value="withouttooling" checked="checked" name="tooling" type="radio"> No Tooling Design<br/><br />
    <input class="checkbox" onclick="Calculate(this.form)" value="withtooling" name="tooling" type="radio"> With tooling design<br/><br />
    <small style="FONT: 10px Arial,Helvetica,sans-serif">(All tooling Gold unless otherwise specified)</small></p>
    <p>Tooling design inset<br/><br />
    Choose<br />
    <input class="checkbox" value="1/2 inch" name="inset" type="radio"> 1/2<br />
    <input class="checkbox" value="3/4 inch" name="inset" type="radio"> 3/4<br />
    <input class="checkbox" value="1 inch" name="inset" type="radio"> 1</p>
    <p>Plus $25.00 shipping</p>
    <hr/><BR></p>
    <p style="PADDING-BOTTOM: 0pt"><strong>Total Cost</strong><input class="short" onfocus="this.form.elements[0].focus()" name="totalcost" id="totalcost" / onChange="updatesum()" /></p>
    <p><BR><BR><strong>Item 2</strong><br />
    <BR><br />
    <input class="checkbox" type="checkbox" name="colorcardonly2" /><strong>Order color card only</strong></p>
    <p>Dimensions of leather to the nearest .25 <br />
    <BR><br />
    <BR> Colour</p>
    <p>&nbsp;</p>
    <select name="item2colour" size="1">
    <option value="Blk">Black</option>
    <option value="Rust">Rust</option>
    </select>
    <p>&nbsp;</p>
    <p><BR></p>
    <p> <BR>Tooling Style</p>
    <p>&nbsp;</p>
    <select name="item2tooling2" size="1">
    <option value="patter1">Pattern 1</option>
    <option value="patter2">Pattern 2</option>
    </select>
    <p>&nbsp;</p>
    <p><BR><br />
    Width<br />
    <input class="short" type="text" name="width2" onchange="Calculateitem2(this.form)" /><small>(in)</small><br />
    <BR><br />
    Length<br />
    <input class="short" type="text" name="length2" onchange="Calculateitem2(this.form)" /><small>(in)</small></p>
    <p><input class="checkbox" onclick="Calculateitem2(this.form)" type="radio" name="tooling2" value="withouttooling" checked="checked" > No Tooling Design</p>
    <p> <input class="checkbox" onclick="Calculateitem2(this.form)" type="radio" name="tooling2" value="withtooling" /> With tooling design</p>
    <p><BR> <small style="font: 10px Arial,Helvetica,sans-serif;">(All tooling Gold unless otherwise specified)</small><br />
    <BR><br />
    Tooling design inset</p>
    <p> Choose<br />
    <input class="checkbox" type="radio" name="inset" value="1/2 inch" /> 1/2<br />
    <input class="checkbox" type="radio" name="inset" value="3/4 inch" /> 3/4<br />
    <input class="checkbox" type="radio" name="inset" value="1 inch" /> 1</p>
    <p>Plus $25.00 shipping</p>
    <hr />
    <BR></p>
    <p><strong>Total Cost</strong><input class="short" type="text" name="totalcost2" onfocus="this.form.elements[0].focus()" /onChange="updatesum()" /><BR></p>
    </li></form>
    working example with added attempts at "grandTotal" - http://www.webcrawldesigns.com/dct/order-form-test/

  6. #6
    Join Date
    Mar 2005
    Location
    Behind you...
    Posts
    873
    First things first, I have to admit, your HTML is pretty jumbled. It certainly wouldn't pass a validator as it's missing some closing tags, and other tags don't follow the 'order of operations' (ie. closing inner-most tags before closing outer-most tags). I won't really address all of the HTML issues though as that's not what this topic is about and it'd be quite a task to rebuild/reformat all of the code.

    Now, for the javascript. A few quick notes: you duplicated your round_decimals() and pad_with_zeroes() functions. I also felt those two functions were awfully... bulky. I included a minified function for formatting numbers. I also removed some of the commented code.

    The first thing to do would be add the HTML element to hold your grand total. Something like this will suffice:
    HTML Code:
    Grand Total: <span id="grandTotal"></span>
    I feel like it makes more sense to be putting these values in regular text elements rather than <input> elements since they are not editable values. Of course, I guess this assumes you aren't actually wanting to submit the value with the form. But in that case I feel it's a little silly to pass the total values via form since it's possible to easily modify those values and thus your submitted data would be tainted and wrong. You should be processing order totals that actually get used on the server's side to avoid potential issues.

    Now for the script, below is essentially all you need. I do feel you could optimize your calculate functions (for instance, you could set up just 1 that takes in 3 parameters, the length field, width field and the output element/field for the total), but it's not a huge deal, it would just be cleaner and more optimized code.
    Code:
    if(typeof(_N) != "function") function _N($n, $d) { return ($d) ? Number($n).toFixed($d).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") : $n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); }
    
    function Calculate(frm) {
    	var order_total, length, width, i;
    	order_total = 0;
    
    	length = parseFloat(frm.length.value);
    	width = parseFloat(frm.width.value);
    
    	if(length > 0 && width > 0) {
    		order_total = length * width;
    		for(i = 0; i < frm.tooling.length; i++) {
    			if (frm.tooling[i].value === "withouttooling" && frm.tooling[i].checked === true) order_total = order_total * ".30";
    			if (frm.tooling[i].value === "withtooling" && frm.tooling[i].checked === true) order_total = order_total * ".40";
    		}
    		//order_total = order_total * .35
    		order_total = order_total + 25;
    	} else {
    		order_total = 0;
    	}
    
    	// Display the total rounded to two decimal places
    	//frm.totalcost.value = '$ ' + round_decimals(order_total, 2);
    	frm.totalcost.value = '$' + _N(order_total, 2);
    	_CalculateTotal(frm);
    }
    
    
    function Calculateitem2(frm) {
    	var order_total, length, width, i;
    	order_total = 0;
    
    	length = parseFloat(frm.length2.value);
    	width = parseFloat(frm.width2.value);
    
    	if(length > 0 && width > 0) {
    		order_total = length * width;
    		for(i = 0; i < frm.tooling2.length; i++) {
    			if(frm.tooling2[i].value === "withouttooling" && frm.tooling2[i].checked === true) order_total = order_total * ".30";
    			if(frm.tooling2[i].value === "withtooling" && frm.tooling2[i].checked === true) order_total = order_total * ".40";
    		}
    		//order_total2 = order_total2 * .35
    		order_total = order_total + 25;
    	} else {
    		order_total = 0;
    	}
    
    	// Display the total rounded to two decimal places
    	//frm.totalcost2.value = '$ ' + round_decimals(order_total, 2);
    	frm.totalcost2.value = '$' + _N(order_total, 2);
    	_CalculateTotal(frm);
    }
    
    function _CalculateTotal($f) {
    	var $total1 = parseFloat($f.totalcost.value.replace(/[^0-9.]/g, ""));
    	var $total2 = parseFloat($f.totalcost2.value.replace(/[^0-9.]/g, ""));
    	console.log($total1, $total2);
    	document.getElementById("grandTotal").innerHTML = (!isNaN($total1) && !isNaN($total2)) ? "$" + _N($total1 + $total2, 2) : "";
    }
    
    function round_decimals(original_number, decimals) {
    	var result1 = original_number * Math.pow(10, decimals);
    	var result2 = Math.round(result1);
    	var result3 = result2 / Math.pow(10, decimals);
    	return pad_with_zeros(result3, decimals);
    }
    
    function pad_with_zeros(rounded_value, decimal_places) {
    	// Convert the number to a string
    	var value_string = rounded_value.toString();
    
    	// Locate the decimal point
    	var decimal_location = value_string.indexOf(".");
    
    	// Is there a decimal point?
    	if(decimal_location == -1) {
    		// If no, then all decimal places will be padded with 0s
    		decimal_part_length = 0;
    
    		// If decimal_places is greater than zero, tack on a decimal point
    		value_string += decimal_places > 0 ? "." : "";
    	} else {
    		// If yes, then only the extra decimal places will be padded with 0s
    		decimal_part_length = value_string.length - decimal_location - 1;
    	}
    
    	// Calculate the number of decimal places that need to be padded with 0s
    	var pad_total = decimal_places - decimal_part_length;
    
    	if(pad_total > 0) {
    		// Pad the string with 0s
    		for(var counter = 1; counter <= pad_total; counter++) {
    			value_string += "0";
    		}
    	}
    	return value_string;
    }
    Each time a total is calculated, the grand total also gets calculated. This isn't the most optimal way to do it, but again your calculate functions could be optimized and merged into one, and could be built to actually check to make sure a total exist for both items before calculating the grand total. But for now, this is a working version that does the job just fine. It will strip any 'bad' characters to get the totals as numbers, then of course adds them and places them in the <span> element I gave you earlier in this post.
    "Given billions of tries, could a spilled bottle of ink ever fall into the words of Shakespeare?"

  7. #7
    Join Date
    Apr 2014
    Posts
    36
    Thank you so much for this. I just didn't copy all the html.. It is complete and coded right in my form
    A question: If I add a drop down that can show up to 4 items will this code calculate totalcost3 totalcost4 etc... if I modify the function Calculateitem2(frm) { code by changing all the 2's to 3's etc?

  8. #8
    Join Date
    Apr 2014
    Posts
    36
    Also when I receive the form results via email
    Grand Total:<span id="grandTotal"> doesn't have a "form" label. Can I add this to the span so that the total amount is visible in the email?

  9. #9
    Join Date
    Mar 2005
    Location
    Behind you...
    Posts
    873
    Again, I think you'd be much better off combining your calculate functions into one. Having 4 separate functions to calculate 4 items is a bad practice, especially if these items all use the same equation/algorithm for their calculation. You end up with a bunch of repeated code (and only 1 or 2 things changing per function).

    If you are wanting to dynamically change the number of items being calculated, it would be even more beneficial to change how things are set up. Bascially, everything right now is static. Each calculation is coded for one specific thing/item and thus the grand total is coded for the 2 specific items you have right now. I don't know if you have any sort of deadlines or schedules to adhere to with this but I can certainly take a look later today and a unified calculate and grand total function that would calculate any number of items.

    And as for the labeling issue of the grand total, as I don't know what the content of the email looks like I can't really tell you what you should or shouldn't do to get a proper label showing up. If the grand total itself is showing up then I suppose you could always just modify my _CalculateTotal() function to write "Grand Total: " in the <span> innerHTML as well (and just remove the text label from the page. But by default have this string in the <span> so the area is not blank to begin with).
    HTML Code:
    <span id="grandTotal">Grand Total: </span>
    Code:
    // This goes inside of the _CalculateTotal() function
    // Replacing the last line of the function
    document.getElementById("grandTotal").innerHTML = (!isNaN($total1) && !isNaN($total2)) ? "Grand Total: $" + _N($total1 + $total2, 2) : "Grand Total: ";
    "Given billions of tries, could a spilled bottle of ink ever fall into the words of Shakespeare?"

  10. #10
    Join Date
    Apr 2014
    Posts
    36
    Hello, I used the code you posted above but would be OPEN and THANKFUL FOR A MORE EFFECTIVE APPROACH.

    I think the shipping cost of $25 should only be applied to item 1 unless my requirements change.
    If it is easy the code could show the option to add more items if a button is pressed. In most cases someone will only order 1 item but need the ability to add more.

    As for the grandtotal coming through in my php email script.
    Example of what I mean here is I have input for customer to fill in company name (html form)
    <input name="company">

    in my php form calls on the field name
    $company = $_POST['company']; and the value will come through in the received email.

    maybe the grandTotal will work the same, I will test it out. (from id)

  11. #11
    Join Date
    Apr 2014
    Posts
    36
    or I guess it would be more like this in php script
    $email_message .= "Company: ".clean_string($company)."\n";

  12. #12
    Join Date
    Apr 2014
    Posts
    36
    One more thing.. sorry for all the posts.. I noticed that if only 1 product is entered the grandTotal doesn't calculate until item 2 is identified. There might not be an item 2 so it needs to calculate no matter how many items.

  13. #13
    Join Date
    Mar 2005
    Location
    Behind you...
    Posts
    873
    As far as the grand total not calculating until a second item is entered, this would mainly be because there is no default value for these items. Thus no total (an invalid total actually) and so the function can't display the total. If the length and width fields had a default value of "0" the grand total should be calculated regardless of how many items were entered.

    But in all fairness, it's more the overall method for all calculations that needs to be adjusted for a proper result. Having one function that dynamically calculates a total for any item will resolve that issue (and others).

    As for getting the grand total in your email, because you are checking $_POST variables you will never see the grand total. $_POST variables are set from form input values. Thus the only way to see values in $_POST (AJAX aside) is having the value in an <input> with a valid name property set (id is not used in $_POST).

    I do feel I need to refer back to something I mentioned earlier when I mentioned putting the grand total in a <span> and not an <input>. It's a bad idea and practice to pass total values like your grand total via a form <input> when you are already passing all of the values necessary to calculate the total in PHP. Especially if you are dealing with an order system that deals with real live orders (and money), you shouldn't be using Javascript, a client-side language, to handle the official order totaling for your records. I'm not saying it's something that could often be a problem but it's an extremely simple task to edit the input values and submit the form. For instance I could enter my typical order information then press the magical F12 button (or right-click and 'Inspect Element') and then edit the value of the grand total. When I submit you could get a grand total of $0.01 which would be absolutely incorrect. You'd receive the email with the invalid info and if the order info is sent anywhere else (a database for instance) the info would be incorrect there as well. Sure, you could just look at the other order details and actually calculate the real grand total yourself, but why put yourself through all of the extra trouble? You should really only be passing the base information to PHP and then actually calculate the total in PHP before sending an email and saving the order. And don't get me wrong, you should still be calculating this on the front-end with Javascript to display the value to the user, but that value shouldn't be your 'final' total that you immediately save and send off because it's less likely to be correct all of the time than having the server (PHP) do the calculations instead.

    That's just one case scenario as well. Overall you could run into other issues with values not always being passed correctly, javascript errors, disabled javascript, etc. And without PHP there to do the actual calculations you will be getting invalid orders and totals.
    "Given billions of tries, could a spilled bottle of ink ever fall into the words of Shakespeare?"

  14. #14
    Join Date
    Apr 2014
    Posts
    36
    Ok.. if you could come up with a function that would calculate the totals regardless of what is selected that would be great - this would resolve the number of items ordered and always show a total.. or suggest another method.

    As for the post method.. I have taken an existing form that has a post method .. and customizing based on requirements. I would rather use a wordpress plugin but I need the square feet measured and values for the tooling as well as the image mouseovers as seen here - http://www.webcrawldesigns.com/dct/order-form-test/

  15. #15
    Join Date
    Mar 2005
    Location
    Behind you...
    Posts
    873
    Below I have what should be a unified function that will calculate the total of any particular item, as well as a slightly updated grand total function.

    I do want to note that this is sort of a 'hack job', which is something I hate to do, but if I'm being honest, a more proper solution would involve numerous changes to the rest of your HTML, which is something I wasn't looking to get into at the moment.
    Code:
    if(typeof(_N) != "function") function _N($n, $d) { return ($d) ? Number($n).toFixed($d).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") : $n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); }
    
    $itemCount = 2;
    $lFields = ["length", "length2", "length3", "length4"];
    $wFields = ["width", "width2", "width3", "width4"];
    $tFields = ["totalcost", "totalcost2", "totalcost3", "totalcost4"];
    
    function Calculate($a) {
    	var order_total, length, width, i;
    	order_total = 0;
    
    	length = parseFloat(document.forms[1][$lFiends[$a]].value);
    	width = parseFloat(document.forms[1][$wFiends[$a]].width.value);
    
    	if(length > 0 && width > 0) {
    		order_total = length * width;
    		for(i = 0; i < document.forms[1]["tooling"].length; i++) {
    			if (document.forms[1]["tooling"][i].value === "withouttooling" && document.forms[1]["tooling"][i].checked === true) order_total = order_total * ".30";
    			if (document.forms[1]["tooling"][i].value === "withtooling" && document.forms[1]["tooling"][i].checked === true) order_total = order_total * ".40";
    		}
    		//order_total = order_total * .35
    		order_total = order_total + 25;
    	} else {
    		order_total = 0;
    	}
    
    	// Display the total rounded to two decimal places
    	//frm.totalcost.value = '$ ' + round_decimals(order_total, 2);
    	document.forms[1]["totalcost"].value = '$' + _N(order_total, 2);
    	_CalculateTotal();
    }
    
    function _CalculateTotal() {
    	var $grandTotal = 0;
    	var $f = document.forms[1];
    	for(var $i = 0; $i < $itemCount; $i++) {
    		$grandTotal = ($grandTotal) + parseFloat($f[$tFields[$i]].value.replace(/[^0-9.]/g, ""));
    	}
    	document.getElementById("grandTotal").innerHTML = _N($grandTotal, 2);
    }
    This code should work, but to be fair it hasn't been tested. I should also note that I'm using document.forms[1] which is only done as your actual page seems to have another form on it, making the order form the second form (1 instead of 0). If the order form were the only form on the page it should be using document.forms[0] instead. And again as I mentioned earlier, a more proper way to do this would be to assign a 'name' attribute to the <form> tag and instead use that (document.forms["formName"]).

    In order to use this new version of the function you will also have to change how you call the function. So for your first item you'd have something like
    HTML Code:
    <input class="short" onchange="Calculate(0)" name="width">
    And for the second item you'd use
    HTML Code:
    <input class="short" onchange="Calculate(1)" name="width">
    And so on for each new item (the same scheme applies to the length.

    Lastly, I'll talk about the extra variables I added at the top. $itemCount could be set dynmaically, so that when you say, change a drop down to choose the number of items you want, this number would update. It's currently used to calculate the grand total (so that it loops through all available items). The other 3 variables are arrays that hold field names. There was probably a 'better' way to go about this, but I found it to be a simple solution for your specific case. Those arrays would need to be updated if you added more than 4 items for instance, or if the 'name' attribute was different than what I have listed there.
    "Given billions of tries, could a spilled bottle of ink ever fall into the words of Shakespeare?"

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles