function update_totals(field) {
var check = Number(field.value);
if (isNaN(check)) {
alert("Your input is not valid. Please enter a number.");
field.value = "";
return;
}
var form = field.form;
var fyRE = /fy_\d+_/;
var suffix = field.name.split(fyRE)[1];
var inputs = form.getElementsByTagName("input");
var total = 0;
for (var i = 0; i < inputs.length; ++i) {
var inp = inputs[i];
if (inp.name.split(fyRE)[1] == suffix) {
var val = Number(inp.value);
if (isNaN(val)) val = 0;
total += val;
}
}
form.elements["total_" + suffix].value = total;
if (suffix == 'most_likely_mitigation_cost' || suffix == 'cost_in_scope') {
var most_likely_mitigation_total = document.getElementById('total_most_likely_mitigation_cost').value;
var cost_in_scope_total = document.getElementById('total_cost_in_scope').value;
var unfunded_threat;
if (most_likely_mitigation_total == 0) {
unfunded_threat = 0 - total;
} else if (cost_in_scope_total == 0) {
unfunded_threat = total;
} else {
unfunded_threat = most_likely_mitigation_total - cost_in_scope_total;
}
form.elements["total_unfunded_threat"].value = unfunded_threat;
}
}
I would like the fy_{$fy.fy}_most_likely_impact_cost and total_most_likely_impact_cost fields to be auto populated.
The fy_{$fy.fy}_most_likely_impact_cost fields should be auto populated when the fy_{$fy.fy}_high_impact_cost changes. When it does change, it needs to be multiplied by the likelihood radio button value as follows:
if likelihood = 1, then fy_{$fy.fy}_high_impact_cost * .1
if likelihood = 2, then fy_{$fy.fy}_high_impact_cost * .2
if likelihood = 3, then fy_{$fy.fy}_high_impact_cost * .4
if likelihood = 4, then fy_{$fy.fy}_high_impact_cost * .6
if likelihood = 5, then fy_{$fy.fy}_high_impact_cost * 1 (so no data manipulation necessary in this case)
When the fy_{$fy.fy}_most_likely_impact_cost is auto populated, the total_most_likely_impact_cost field needs to be auto updated so that it adds together all of the fy_{$fy.fy}_most_likely_impact_cost fields.
I've have tried this over and over again but I cannot seem to get it exactly right. Please help. =) Thanks!
You are trying to reference the parent form from the reference to the object that triggered the onchange event, and thus, will end up in an error.
Try this instead:
Code:
var form = document.forms['formName'];
OR
Code:
var form = document.getElementById('formId');
OPTIONALLY (and by this I mean that this is the absurd, but still functional, method)
Code:
var form = field.parentNode.parentNode.parentNode.parentNode...
/*You have to use as many .parentNode for as many levels of nesting you that that input in.
If I assume your <form> tag is directly before the 1st <table> code, you'd need 4, like my example.*/
if(suffix == 'high_impact_cost'){
var likelihood = 0;
for(var i in form.elements['likelihood']){
if(form.elements['likelihood'][i].checked){
likelihood = form.elements['likelihood'][i].value;
break;
}
}
var mostLikelyImpactCost = field.parentNode.nextSibling;
// Some browsers ignore whitespaces, others dont
if(mostLikelyImpactCost.nodeType == 3)
mostLikelyImpactCost = mostLikelyImpactCost.nextSibling;
mostLikelyImpactCost = mostLikelyImpactCost.getElementsByTagName('input')[0];
mostLikelyImpactCost.value = field.value * likelihood;
var mlicFields = getElementsByClassName(form, 'input', 'mlic');
var totalMlic = 0;
for(var j = 0; l = mlicFields.length, j < l; j++){
totalMlic += +mlicFields[j].value;
}
form.elements['total_most_likely_impact_cost'].value = totalMlic;
}
/**
* @param mixed p = parent
* @param string t = tag
* @param string c = class
*/
function getElementsByClassName(p, t, c)
{
var elems = [];
var parent = p ? (typeof(p) == 'object' ? p : document.getElementById(p)) : document.documentElement;
var tag = t ? t : '*';
var nodes = parent.getElementsByTagName(tag);
var nLen = nodes.length;
for (var i = 0; i < nLen; i++)
{
if (nodes[i].className && nodes[i].className.indexOf(c) >= 0)
elems.push(nodes[i]);
}
return elems;
}
Notice I added a class to the fy_{$fy.fy}_most_likely_impact_cost fields called mlic, makes life a lot easier. Of course, I added a function to get elements by their class name.
I implemented the code you listed, and it didn't seem to work properly. I need to multiply the mostLikelyImpactCost.value by a value associated with the likelihood value the user selected using the radio buttons.
Also, when the user inputs an entry into one of the high impact cost fields, is there a way to check and make sure that the user has selected a radio button? That was I can prevent the most likely impact fields from being blank.
I wish I could do that, but I need those values to stay as they are because they are used elsewhere for various things =/.
However, I tried the following and it seemed to work:
Code:
if (likelihood == 1)
mostLikelyImpactCost.value = field.value * 0.1;
if (likelihood == 2)
mostLikelyImpactCost.value = field.value * 0.2;
if (likelihood == 3)
mostLikelyImpactCost.value = field.value * 0.4;
if (likelihood == 4)
mostLikelyImpactCost.value = field.value * 0.6;
I would like a 0 (zero) to be placed in the fy_{$fy.fy}_most_likely_impact_cost fields if the user does not select a likelihood value.
I've also noticed that after a value is entered in the fy_{$fy.fy}_high_impact_cost field(s), the fy_{$fy.fy}_most_likely_impact_cost is updated, but the total_most_likely field does not auto update.
Well, I had already set likelihood as 0 by default. To fix the other issue @ hand use this:
Code:
var likelihood = 0;
for(var i in form.elements['likelihood']){
if(form.elements['likelihood'][i].checked){
likelihood = form.elements['likelihood'][i].value;
break;
}
}
var multiplyBy = ['', 0.1, 0.2, 0.4, 0.6, 1];
likelihood = multiplyBy[likelihood];
Going to check the other part.
The total_most_likely_impact_cost is updating properly for me when I change any input value. I saw it did not change if I first put in the value AND then selected a radio button. But you don't have a onchange option on those.
Can you send me your finalized code so I can compare it to mine in order to find out why my total_most_likely_impact cost is not updated automatically?
Good catch SparoHawk. I made that change and everything seems to be working properly now. I also used Math.floor(totalMlic * 100) / 100; to truncate the summations to 2 decimal places.
Bookmarks