0

Any help would be greatly appreciated. I am adding JavaScript fields with a onChange command with decimals but when the onChange command is moved back to option "NO" to remove the number (example. 1.7) it only removes 1.69999 and not the 1.7.

Below is the onChange code I am using.

<div id="onewindow">
   <label for="txtoneside" class="editor-label"><strong>1 Side </strong></label>
    <div align="right">
      <input type = "text" name = "txtoneside" id="txtoneside" value = "1.7" />
      <select name="txtoneside_slider" id="txtoneside_slider" data-role="slider" data-mini="true" onChange="javascript: if(this.value=='yes'){ document.getElementById('txtgrandtotal').value= parseFloat(document.getElementById('txtgrandtotal').value) + parseFloat(document.getElementById('txtoneside').value); calculate()}
if(this.value=='no'){ document.getElementById('txtgrandtotal').value= parseFloat(document.getElementById('txtgrandtotal').value) - parseFloat(document.getElementById('txtoneside').value); calculate()}"/>
         <option value="no">No</option>
         <option value="yes">Yes</option>
       </select> 
</div>
<div id="twowindow">
   <label for="txtoneside" class="editor-label"><strong>2 Side </strong></label>
<div align="right">
  <input type = "text" name = "txttwoside" id="txttwoside" value = "19.3" />
  <select name="txttwoside_slider" id="txttwoside_slider" data-role="slider" data-mini="true" onChange="javascript: if(this.value=='yes'){ document.getElementById('txtgrandtotal').value= parseFloat(document.getElementById('txtgrandtotal').value) + parseFloat(document.getElementById('txttwoside').value); calculate()}
if(this.value=='no'){ document.getElementById('txtgrandtotal').value= parseFloat(document.getElementById('txtgrandtotal').value) - parseFloat(document.getElementById('txttwoside').value); calculate()}" />
         <option value="no">No</option>
         <option value="yes">Yes</option>
       </select> 
</div>
<div id="grandtotal">
   <label for="txtgrandtotal" class="editor-label"><strong>JOB TOTAL</strong></label>
   <div align="right">
   <input type = "text" name = "txtgrandtotal" id="txtgrandtotal" value = "0" />
   </div>

</div>
Adder
  • 33
  • 9

1 Answers1

0

parseFloat() is converting to a double which is never an exact conversion when going from binary to decimal. I would recommend using toFixed() to truncate the output or find a library decimal data type depending on your needs.

see:

Also, it is a bad practice to add a value to a total then subtract it back out in this case for the very reason that the conversion is not precise - rounding errors will be accumulated in that way. I would suggest getting a sum over each of the included values any time one of them changes. By using jQuery you could:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>New Web Project</title>
        <script src="jquery-1.9.1.min.js"></script>
    </head>
    <body>
        <div id="onewindow">
            <label for="txtoneside" class="editor-label"><strong>1 Side </strong></label>
            <div align="right">
                <input type="text" name="txtoneside" id="txtoneside" value = "1.7" />
                <select name="txtoneside_slider" id="txtoneside_slider" data-role="slider" data-mini="true" onChange="update()"/>
                    <option value="no">No</option>
                    <option value="yes">Yes</option>
                </select>
            </div>
            <div id="twowindow">
                <label for="txtoneside" class="editor-label"><strong>2 Side </strong></label>
                <div align="right">
            <input type = "text" name = "txttwoside" id="txttwoside" value = "19.3" />
                    <select name="txttwoside_slider" id="txttwoside_slider" data-role="slider" data-mini="true" onChange="update()"/>
                        <option value="no">No</option>
                        <option value="yes">Yes</option>
                    </select>
                </div>
                <div id="grandtotal">
                    <label for="txtgrandtotal" class="editor-label"><strong>JOB TOTAL</strong></label>
                    <div align="right">
                        <input type = "text" name = "txtgrandtotal" id="txtgrandtotal" value = "0" />
                    </div>
                </div>
            </div>
        </div>
        <script>
            update = function(){
                var all_values = [],
                    sum = 0,
                    i = 0;
                $('input:not(#txtgrandtotal)').each(function(){
                    var val = parseFloat($(this).attr('value'));
                    all_values.push((isNaN(val)) ? 0 : val) // store each value
                });
                $('select').each(function(){
                    var $option = $(this).find(':selected');
                    if($option.text()){
                        if($option.text()==="Yes")
                            sum+=all_values[i];  // sum only the ones that are selected
                    }
                    ++i;
                });
                $('#txtgrandtotal').attr('value', sum.toFixed(2));
                calculate(); // if that is required somewhere else in your code?
            }
        </script>
    </body>
</html>

Edit: The code above is corrected for when the input field's value is "" or not a number. In this case a value of 0 is used as opposed the NaN result of parseInt().

Community
  • 1
  • 1
Nolo
  • 846
  • 9
  • 19
  • Thanks Nolo. One more question what if I want to change the values? Example change the 1.7 to value= "" and value="19.3" to value= "" When I do this then go to the page and place in a value to add I get a NaN. Could you please help me with that? – Adder Mar 26 '13 at 13:29
  • @Adder: Be careful how you are extracting the value from the page - when value="", parseInt("") is (undefined), this might be where NaN is coming from. Try using "0" when you are working with numerical values, or check before doing the conversion. – Nolo Mar 26 '13 at 20:16