www.webdeveloper.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16

Thread: [RESOLVED] use onchange to change two fields?

  1. #1
    Join Date
    Apr 2012
    Posts
    19

    resolved [RESOLVED] use onchange to change two fields?

    Before I describe my issue, here is my code.

    html:

    Code:
    <table>
    <tr>
    <td align="right" width="20%"><b>Likelihood:</b></td>
    <td align="left" colspan="3">
    <input id="likelihood" type="radio" name="likelihood" value="1" {$likelihood_one} />1 Very Low, P&nbsp;&le;&nbsp;10%<br/>
    <input id="likelihood" type="radio" name="likelihood" value="2" {$likelihood_two} />2 Low, 10% < P&nbsp;&le;&nbsp;10%<br/>
    <input id="likelihood" type="radio" name="likelihood" value="3" {$likelihood_three} />3 Medium, 25% < P&nbsp;&le;&nbsp;50%<br/>
    <input id="likelihood" type="radio" name="likelihood" value="4" {$likelihood_four} />4 High, 50% < &nbsp;P&nbsp;&le;&nbsp;70%<br/>
    <input id="likelihood" type="radio" name="likelihood" value="5" {$likelihood_five} />5 Very High, P > 75%
    </td>
    </tr>
    </table>
    
    <table border="box" width="100%">
    <tr>
    <td align="center" bgcolor="#000099" colspan="5"><font color="white"><b>Impact Cost Totals</b></font></td>
    <td align="center" bgcolor="#000099" colspan="5"><font color="white"><b>Mitigation Cost Totals</b></font></td>
    </tr>
    <tr>
    <td align="center" bgcolor="#000099" rowspan="2"><font color="white"><b>Totals</b></font></td>
    <td align="center" bgcolor="#000099"><font color="white"><b>High</b></font></td>
    <td align="center" bgcolor="#000099"><font color="white"><b>Most Likely</b></font></td>
    <td align="center" bgcolor="#000099"><font color="white"><b>Low</b></font></td>
    <td align="center" bgcolor="#000099"><font color="white"><b>Actual</b></font></td>
    <td align="center" bgcolor="#000099"><font color="white"><b>High</b></font></td>
    <td align="center" bgcolor="#000099"><font color="white"><b>Most Likely</b></font></td>
    <td align="center" bgcolor="#000099"><font color="white"><b>Low</b></font></td>
    <td align="center" bgcolor="#000099"><font color="white"><b>Cost in Scope</b></font></td>
    <td align="center" bgcolor="#000099"><font color="white"><b>Unfunded Threat</b></font></td>
    </tr>
    <tr>
    <td align="center">$<input id="total_high_impact_cost" size="3" name="total_high_impact_cost" maxlength="20" style="text-align: right" readonly="readonly" value="{$values.total_high_impact_cost}" />M</td>
    <td align="center">$<input id="total_most_likely_impact_cost" size="3" name="total_most_likely_impact_cost" maxlength="20" style="text-align: right" readonly="readonly" value="{$values.total_most_likely_impact_cost}" />M</td>
    <td align="center">$<input id="total_low_impact_cost" size="3" name="total_low_impact_cost" maxlength="20" style="text-align: right" readonly="readonly" value="{$values.total_low_impact_cost}" />M</td>
    <td align="center">$<input id="total_actual_expense" size="3" name="total_actual_expense" maxlength="20" style="text-align: right" readonly="readonly" value="{$values.total_actual_expense}" />M</td>
    <td align="center">$<input id="total_high_mitigation_cost" size="3" name="total_high_mitigation_cost" maxlength="20" style="text-align: right" readonly="readonly" value="{$values.total_high_mitigation_cost}" />M</td>
    <td align="center">$<input id="total_most_likely_mitigation_cost" size="3" name="total_most_likely_mitigation_cost" maxlength="20" style="text-align: right" readonly="readonly" value="{$values.total_most_likely_mitigation_cost}" />M</td>
    <td align="center">$<input id="total_low_mitigation_cost" size="3" name="total_low_mitigation_cost" maxlength="20" style="text-align: right" readonly="readonly" value="{$values.total_low_mitigation_cost}" />M</td>
    <td align="center">$<input id="total_cost_in_scope" size="3" name="total_cost_in_scope" maxlength="20" style="text-align: right" readonly="readonly" value="{$values.total_cost_in_scope}" />M</td>
    <td width="10%" align="center">$<input id="total_unfunded_threat" size="3" name="total_unfunded_threat" maxlength="20" style="text-align: right" readonly="readonly" value="{$values.total_unfunded_threat}" />M</td>
    </tr>
    </table>
    
    {foreach value=fy from=$costs_for_fys_array}
    <table border="0" width="100%">
    <tr>
    <td align="center" bgcolor="#000099"><font color="white"><b>FY {$fy.fy}</b></font></td>
    <td>
    <table border="box" width="100%">
    <tr>
    <td align="center" bgcolor="#000099" colspan="3"><font color="white"><b>Impact Cost</b></font></td>
    <td align="center" bgcolor="#000099" rowspan="2"><font color="white"><b>Actual Expense</b></font></td>
    <td align="center" bgcolor="#000099" colspan="3"><font color="white"><b>Mitigation Cost Estimate</b></font></td>
    <td align="center" bgcolor="#000099" rowspan="2"><font color="white"><b>Cost in Scope</b></font></td>
    </tr>
    <tr>
    <td align="center" bgcolor="#000099"><font color="white"><b>High</b></font></td>
    <td align="center" bgcolor="#000099"><font color="white"><b>Most Likely</b></font></td>
    <td align="center" bgcolor="#000099"><font color="white"><b>Low</b></font></td>
    <td align="center" bgcolor="#000099"><font color="white"><b>High</b></font></td>
    <td align="center" bgcolor="#000099"><font color="white"><b>Most Likely</b></font></td>
    <td align="center" bgcolor="#000099"><font color="white"><b>Low</b></font></td>
    </tr>
    <tr>
    <td align="center">$<input id="fy_{$fy.fy}_high_impact_cost" size="3" name="fy_{$fy.fy}_high_impact_cost" maxlength="20" style="text-align: right" value="{$fy.high_impact_cost}" onchange="update_totals(this)" />M</td>
    <td align="center">$<input id="fy_{$fy.fy}_most_likely_impact_cost" size="3" name="fy_{$fy.fy}_most_likely_impact_cost" maxlength="20" style="text-align: right" value="{$fy.most_likely_impact_cost}" onchange="update_totals(this)" />M</td>
    <td align="center">$<input id="fy_{$fy.fy}_low_impact_cost" size="3" name="fy_{$fy.fy}_low_impact_cost" maxlength="20" style="text-align: right" value="{$fy.low_impact_cost}" onchange="update_totals(this)" />M</td>
    <td align="center">$<input id="fy_{$fy.fy}_actual_expense" size="3" name="fy_{$fy.fy}_actual_expense" maxlength="20" style="text-align: right" value="{$fy.actual_expense}" onchange="update_totals(this)" />M</td>
    <td align="center">$<input id="fy_{$fy.fy}_high_mitigation_cost" size="3" name="fy_{$fy.fy}_high_mitigation_cost" maxlength="20" style="text-align: right" value="{$fy.high_mitigation_cost}" onchange="update_totals(this)" />M</td>
    <td align="center">$<input id="fy_{$fy.fy}_most_likely_mitigation_cost" size="3" name="fy_{$fy.fy}_most_likely_mitigation_cost" maxlength="20" style="text-align: right" value="{$fy.most_likely_mitigation_cost}" onchange="update_totals(this)" />M</td>
    <td align="center">$<input id="fy_{$fy.fy}_low_mitigation_cost" size="3" name="fy_{$fy.fy}_low_mitigation_cost" maxlength="20" style="text-align: right" value="{$fy.low_mitigation_cost}" onchange="update_totals(this)" />M</td>
    <td align="center">$<input id="fy_{$fy.fy}_cost_in_scope" size="3" name="fy_{$fy.fy}_cost_in_scope" maxlength="20" style="text-align: right" value="{$fy.cost_in_scope}" onchange="update_totals(this)" />M</td>
    </tr>
    </table>
    </td>
    </tr>
    </table>
    {/foreach}
    Javascript:

    Code:
    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!

  2. #2
    Join Date
    Jul 2007
    Posts
    386
    Well, first of all you have this line:
    Code:
    var form = field.form;
    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.*/

  3. #3
    Join Date
    Apr 2012
    Posts
    19
    Is there a way to print out the error from
    Code:
    var form = field.form;
    ?

    The code that I am using now is working exactly as it should, so I am curious.

  4. #4
    Join Date
    Jul 2007
    Posts
    386
    Lol, certainly. I did see an error on my Firebug console saying form was undefined. Strangely now, its working. I'll keep looking at this, hang on.

    I understand what you want, and I am looking for a way to reduce coding horrors and burden, so hang on.
    Last edited by SparoHawk; 07-17-2012 at 12:23 PM.

  5. #5
    Join Date
    Jul 2007
    Posts
    386
    Here is what I added:

    Code:
        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.

    Please let me know if something does not work.

  6. #6
    Join Date
    Apr 2012
    Posts
    19
    Thanks for the help!

    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.

    For example, instead of

    Code:
    mostLikelyImpactCost.value = field.value * likelihood;
    could I do

    Code:
    if (likelihood == 1)
       mostLikelyImpactcost.value = field.value * .1;
    if (likelihood == 2)
       mostLikelyImpactcost.value = field.value * .2;
    if (likelihood == 3)
       mostLikelyImpactcost.value = field.value * .4;
    if (likelihood == 4)
       mostLikelyImpactcost.value = field.value * .6;
    I tried implementing this and it didn't seem to work. Any suggestions?

  7. #7
    Join Date
    Apr 2012
    Posts
    19
    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.

  8. #8
    Join Date
    Jul 2007
    Posts
    386
    Alright. First of all, make the radio buttons have the values you want to multiply by.

    Code:
    <input id="likelihood" type="radio" name="likelihood" value="0.1" {$likelihood_one} />1 Very Low, P&nbsp;&le;&nbsp;10%<br/>
    <input id="likelihood" type="radio" name="likelihood" value="0.2" {$likelihood_two} />2 Low, 10% < P&nbsp;&le;&nbsp;10%<br/>
    <input id="likelihood" type="radio" name="likelihood" value="0.4" {$likelihood_three} />3 Medium, 25% < P&nbsp;&le;&nbsp;50%<br/>
    <input id="likelihood" type="radio" name="likelihood" value="0.6" {$likelihood_four} />4 High, 50% < &nbsp;P&nbsp;&le;&nbsp;70%<br/>
    <input id="likelihood" type="radio" name="likelihood" value="1" {$likelihood_five} />5 Very High, P > 75%
    That saves us from having to do an extra switch or string of ifs.

    As for the other option, yes, its possible.

    What should happen if a user changes a value without a selected radio option?

  9. #9
    Join Date
    Apr 2012
    Posts
    19
    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.

  10. #10
    Join Date
    Jul 2007
    Posts
    386
    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.
    Last edited by SparoHawk; 07-17-2012 at 03:33 PM.

  11. #11
    Join Date
    Apr 2012
    Posts
    19
    is this
    Code:
    var multiplyBy = ['', 0.1, 0.2, 0.4, 0.6, 1];
    likelihood = multiplyBy[likelihood];
    supposed to take the place of this?

    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;

  12. #12
    Join Date
    Apr 2012
    Posts
    19
    Nevermind... I see what you did with the array. =)

  13. #13
    Join Date
    Apr 2012
    Posts
    19
    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?

  14. #14
    Join Date
    Jul 2007
    Posts
    386
    Did you apply the class to the input fields?

    Example:
    Code:
    <td align="center">$<input id="fy_{$fy.fy}_most_likely_impact_cost" size="3" name="fy_{$fy.fy}_most_likely_impact_cost" maxlength="20" style="text-align: right" value="2" onchange="update_totals(this)" class="mlic" />M</td>
    Notice the class="mlic"

  15. #15
    Join Date
    Apr 2012
    Posts
    19
    Oh! No, I didn't!

    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.

    Thank you so much for your help! =)

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