Link to home
Start Free TrialLog in
Avatar of virgo71il
virgo71ilFlag for United States of America

asked on

Need JavaScript Help To Sum Fields Based on Dropdown Selection

I have (1) dropdown field named (CAT) that contains (7) items and repeats in (31) rows.  I also have (3) different decimal fields (REG, TIMEHALF, and DBL) which may or may not contain data, that also repeat in the same (31) rows.  Lastly, I have a separate field (BASEBLDGTL) that is not connected to the table, which I want to use to calculate the (3) different decimal fields based on the selection of the dropdown field.  So basically, I'm looking for the BASEBLDGTL field to add all of the REG, TIMEHALF, and DBL fields together for each row if the first item in the dropdown field is selected.  I also want the BASEBLDGTL field to be able to pickup on possible changes to the selection of the CAT dropdown field.  Any help would be very much appreciated as I'm a complete idiot in JavaScript.
Avatar of vr6r
vr6r

If you're not already using jquery, I would suggest including it to simplify working with the elements as you describe.

Below is an example of how I would accomplish this...

It fires a calc function when the selection of any of the (CAT) dropdowns change, or when the values of any of the decimal fields changes.  (note: the decimal change event occurs when the element loses focus, ie: when you tab or click away from the field after editing it.)

When the calc function fires it finds any rows whose (CAT) dropdown = "1", and then adds the decimal values in that row to a temp variable.  When the function is done adding up all those rows, it replaces the value of the BASEBLDGTL field, which in this example has an id = "total".

HTML (only set up with 3 rows but you could easily expand this to 31 or as many rows as you need)
<table id="values">
	<tr>
		<th>CAT</th>
		<th>REG</th>
		<th>TIMEHALF</th>
		<th>DBL</th>
	</tr>
	<tr>
		<td>
			<select class="cat">
                <option value=""></option>
				<option value="1">1</option>
				<option value="2">2</option>
				<option value="3">3</option>
				<option value="4">4</option>
				<option value="5">5</option>
				<option value="6">6</option>
				<option value="7">7</option>
			</select>
		</td>
		<td><input type="text" class="reg" value="0.0" /></td>
		<td><input type="text" class="timehalf" value="0.0" /></td>
		<td><input type="text" class="dbl" value="0.0" /></td>
	</tr>
    <tr>
		<td>
			<select class="cat">
				<option value=""></option>
				<option value="1">1</option>
				<option value="2">2</option>
				<option value="3">3</option>
				<option value="4">4</option>
				<option value="5">5</option>
				<option value="6">6</option>
				<option value="7">7</option>
			</select>
		</td>
		<td><input type="text" class="reg" value="0.0" /></td>
		<td><input type="text" class="timehalf" value="0.0" /></td>
		<td><input type="text" class="dbl" value="0.0" /></td>
	</tr>
    <tr>
		<td>
			<select class="cat">
				<option value=""></option>
                <option value="1">1</option>
				<option value="2">2</option>
				<option value="3">3</option>
				<option value="4">4</option>
				<option value="5">5</option>
				<option value="6">6</option>
				<option value="7">7</option>
			</select>
		</td>
		<td><input type="text" class="reg" value="0.0" /></td>
		<td><input type="text" class="timehalf" value="0.0" /></td>
		<td><input type="text" class="dbl" value="0.0" /></td>
	</tr>
</table>
<br />
BASEBLDGTL: <input type="text" id="total" value="0" />

Open in new window


JS (using jquery)
$(function(){
    //update total when 'CAT' selection changes
    $('.cat').change(function(e){
        calcRows();
    });
    
    //update total when decimal fields change
    $('.reg, .timehalf, .dbl').change(function(){
        calcRows();
    });
});

function calcRows()
{
    //create var to hold new calculated total
	var total = 0;
    
    //loop through each row whose 'cat' dropdown selection = "1"
    $('.cat option:selected[value="1"]').each(function(ix, el){
		//set var equal to row element
        var tr = $(el).closest('tr');
        
        //add each decimal field in this row to the calc total
		total += parseFloat(tr.find('input.reg').val());
		total += parseFloat(tr.find('input.timehalf').val());
		total += parseFloat(tr.find('input.dbl').val());
	});
    
    //update 'BASEBLDGTL' field with new calc total
    $('#total').val(total);
}

Open in new window


Here is a working example of the above: http://jsfiddle.net/xx675z46/

Hope this helps!
Avatar of virgo71il

ASKER

vr6r - First of all, thank you so much for helping me with this.  I went to the jsfiddle link/example you provided and it works exactly as I need it to.  I should have mentioned in my post that I'm using Adobe LiveCycle Designer to put together this PDF form.  I put your code in the Base_Bldg_Hrs field on a calculate event, and I can't seem to get it to work.  I've attached the PDF form I'm working on.
Hours-Sheet-Form.pdf
jQuery only works in the context of a web page, not in PDF forms.

Use the following JavaScript as the calculation script for your REGTOTAL field:

var sum = 0;
for (var i=0; i&lt;32; i++) {
    var cat = xfa.resolveNode("CAT[" + i + "]");
    if (cat != null &amp;&amp; cat.rawValue == 1) {
        var val = xfa.resolveNode("REG[" + i + "]");
        if (val != null) {
            sum += val.rawValue;
        }
    }
}
if (sum != 0) {
    this.rawValue = sum;
}
else {
    this.rawValue = "";
}

Open in new window


You would have to adjust the script for your TIMEHALFTOTAL and DBLTOTAL fields by just chaining the way the individual fields are getting references.
Karl Heinz Kremer - Thank you also for getting back to me.  Unfortunately, the field I need to sum the REG, TIMEHALF, and DBLT fields based on the CAT selection is Base_Bldg_Hrs.
Then just use the script as the calculation script for the Base_Bldg_Hrs field. There is nothing in the script that is specific to the target field.
Karl Heinz Kremer - Yes, I put the code in the Base_Bldg_Hrs field and it's not working.  I'm sorry.
Somehow when I pasted the code, something got changed. Let me try again:

var sum = 0;
for (var i=0; i<32; i++) {
    var cat = xfa.resolveNode("CAT[" + i + "]");
    if (cat != null && cat.rawValue == 1) {
        var val = xfa.resolveNode("REG[" + i + "]");
        if (val != null) {
            sum += val.rawValue;
        }
    }
}
if (sum != 0) {
    this.rawValue = sum;
}
else {
    this.rawValue = "";
}

Open in new window

Karl Heinz Kremer - We're almost there.  It's only calculating the 1st field REG, and not including the TIMEHALF, and DBLT fields.
Correct, that's why I said "You would have to adjust the script for your TIMEHALFTOTAL and DBLTOTAL fields by just changing the way the individual fields are getting references."
Karl Heinz Kremer - I'm sorry but how do I do that?  As I said in my original posting, I'm an idiot in JavaScript.
In line #5 change "REG[" to "TIMEHALF[" and to "DBL[" for the respective fields.
Karl Heinz Kremer - Is this what I should have?
 
 topmostSubform.Page1.Base_Bldg_Hrs::calculate - (JavaScript, client)
var sum = 0;
for (var i=0; i<32; i++) {
    var cat = xfa.resolveNode("CAT[" + i + "]");
    if (cat != null && cat.rawValue == 1) {
        var val = xfa.resolveNode("REG[" + i + "]");
        var val = xfa.resolveNode("TIMEHALF[" + i + "]");
        var val = xfa.resolveNode("DBLT[" + i + "]");
        if (val != null) {
            sum += val.rawValue;
        }
    }
}
if (sum != 0) {
    this.rawValue = sum;
}
else {
    this.rawValue = "";
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Karl Heinz Kremer
Karl Heinz Kremer
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Karl Heinz Kremer  - So the script is now only adding up the DBLT fields and not retaining the values from the REG and TIMEHALF fields.  I need to be able to retain the values from all (3) fields.

var sum = 0;
for (var i=0; i<32; i++) {
    var cat = xfa.resolveNode("CAT[" + i + "]");
    if (cat != null && cat.rawValue == 1) {
        var val = xfa.resolveNode("REG[" + i + "]");
        if (val != null) {
            sum += val.rawValue;
        }
    }
}
if (sum != 0) {
    this.rawValue = sum;
}
else {
    this.rawValue = "";
}
    var sum = 0;
for (var i=0; i<32; i++) {
    var cat = xfa.resolveNode("CAT[" + i + "]");
    if (cat != null && cat.rawValue == 1) {
        var val = xfa.resolveNode("TIMEHALF[" + i + "]");
        if (val != null) {
            sum += val.rawValue;
        }
    }
}
if (sum != 0) {
    this.rawValue = sum;
}
else {
    this.rawValue = "";
}
     var sum = 0;
for (var i=0; i<32; i++) {
    var cat = xfa.resolveNode("CAT[" + i + "]");
    if (cat != null && cat.rawValue == 1) {
        var val = xfa.resolveNode("DBLT[" + i + "]");
        if (val != null) {
            sum += val.rawValue;
        }
    }
}
if (sum != 0) {
    this.rawValue = sum;
}
else {
    this.rawValue = "";
}                 

Open in new window

You need _THREE_ different scripts for the three fields DBLTOTAL, HALFTIMETOTAL and REGTOTAL.
Karl Heinz Kremer - I made adjustments to the sum references for each field and it's seems to be working:

 
var sumA = 0;
for (var i=0; i<32; i++) {
    var cat = xfa.resolveNode("CAT[" + i + "]");
    if (cat != null && cat.rawValue == 1) {
        var val = xfa.resolveNode("REG[" + i + "]");
        if (val != null) {
            sumA += val.rawValue;
        }
    }
}
if (sumA != 0) {
    this.rawValue = sumA;
}
var sumB = 0;
for (var i=0; i<32; i++) {
    var cat = xfa.resolveNode("CAT[" + i + "]");
    if (cat != null && cat.rawValue == 1) {
        var val = xfa.resolveNode("TIMEHALF[" + i + "]");
        if (val != null) {
            sumB += val.rawValue;
        }
    }
}
if (sumB != 0) {
    this.rawValue = sumB + sumA;
}
var sumC = 0;
for (var i=0; i<32; i++) {
    var cat = xfa.resolveNode("CAT[" + i + "]");
    if (cat != null && cat.rawValue == 1) {
        var val = xfa.resolveNode("DBLT[" + i + "]");
        if (val != null) {
            sumC += val.rawValue;
        }
    }
}
if (sumC != 0) {
    this.rawValue = sumC + sumB + sumA;
}
else {
    this.rawValue = "";
}                 

Open in new window

Karl Heinz Kremer - Thank you so much for your help and patience with me.