0

I'm currently developing a form that needs to sum the values of select fields (integer values) and the result should be displayed in another input field. The layout is that of a scoring sheet, with multiple row, showing partial totals and grand totals and the sum of scores has to be done in stages (or rows). So, all the scores of a single row will have a partial total for that row only.

The problem I have, not being very good at javascript, is that I found a script that is somehow working, but is adding the results of ALL rows into the partial total field of the first row (please see image below).

Link to image: http://postimg.org/image/77fxwl2db/

The right way for the form to work would be that the scores selected in the select fields in a single row will show a partial total in the light grey field of the same row, and that field only, while the dark grey (black) field will show the sum of the previous partial total PLUS the one of that row as well. (please see image below)

Link to image: http://postimg.org/image/ddolwjfft/

Hopefully that will make sense... As for the code, this is what I'm using:

<form method="post" action="#" >
    <fieldset class="scores_row_1">
    <select class="input1" onchange="OnChange(this.value)" name="score_1">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0">M</option>
    </select>
    <select class="input1" onchange="OnChange(this.value)" name="score_2">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0">M</option>
    </select>
    <select class="input1" onchange="OnChange(this.value)" name="score_3">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0">M</option>
    </select>
    <select class="input1" onchange="OnChange(this.value)" name="score_4">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0">M</option>
    </select>
    <select class="input1" onchange="OnChange(this.value)" name="score_5">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0">M</option>
    </select>
    <select class="input1" onchange="OnChange(this.value)" name="score_6">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0">M</option>
    </select>


    <span class="spacer"></span>
    <input type="text" maxlength="2" class="input2" id="total_row_1" />
    <input type="text" maxlength="2" class="input3" />
</fieldset>
</form>

The code above represents one single row, but several rows will be required. As for the javascript used, this is the code:

<script type="text/javascript" language="javascript">
var row = 1;
var sum = 0;

function OnChange(value) {
    sum += new Number(value);
    document.getElementById('total_row_'+ row).value = sum;
}

Please any help regarding this would be appreciated. I have looked for some options but I haven't been able to find anything that matches this specific situation!

2 Answers 2

1

I have developed a solution for you , extending your problem to that of two rows. Have made various changes in your original source which had many bugs. Have added comments which hopes makes the solution self explanatory.

The respective total of each column is shown next to the select fields, and the overall total of each row is shown in the input field below,

Javascript:-

function OnChange(node) {
var row=1; 
var sum = 0;

    if(node.parentNode.className=="scores_row_1"){row=1;} //Row selector
    if(node.parentNode.className=="scores_row_2"){row=2;}

    var value=node.value;
    if(value=="X"){
    value=10;  //dont know what you intend to do with X value, for me i have set it as 10,make your changes in the if condition accordingly
    }
    if(value=="M"){
    value=0; //for option M
    }
    //made changes to previous source, now added loop to loop through the select elements, note that you have to assign a default value to the select tags like M 
    for(var i=1;i<7;i++)
    { //sum is total of select elements, get each by their unique name attribute
sum+=parseInt(document.getElementsByName("score_"+row+"_"+i)[0].value);
}

    document.getElementById('total_row_'+ row).value = sum; //assign sum to the input element


}

function OnChangeFinal() {   
    //function keeps calling on mousemove and sums total of both rows input fields and assignto the final input field. You can change the event type i just used this for demo
    document.getElementById('final_row').value= parseInt(document.getElementById('total_row_1').value) + parseInt(document.getElementById('total_row_2').value);
    }

HTML:-

   <form method="post" action="#" onmousemove="OnChangeFinal()"> <!--assigned event to the form to call OnChangeFinal()--> 
    <fieldset class="scores_row_1">
    <select class="input1" onchange="OnChange(this)" name="score_1_1">//assign names as score_rowNumber_scoreNumber to uniquely identify each element.
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0" selected="selected">M</option>
    </select>
    <select class="input1" onchange="OnChange(this)" name="score_1_2">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0" selected="selected">M</option>
    </select>
    <select class="input1" onchange="OnChange(this)" name="score_1_3">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0" selected="selected">M</option>
    </select>
    <select class="input1" onchange="OnChange(this)" name="score_1_4">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0" selected="selected">M</option>
    </select>
    <select class="input1" onchange="OnChange(this)" name="score_1_5">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0" selected="selected">M</option>
    </select>
    <select class="input1" onchange="OnChange(this)" name="score_1_6">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0" selected="selected">M</option>
    </select>


    <span class="spacer"></span>
        <input type="text" maxlength="2" class="input2" value="0" id="total_row_1" /><!--assigned default value 0 and id-->

</fieldset>
     <fieldset class="scores_row_2">
    <select class="input1" onchange="OnChange(this)" name="score_2_1">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0" selected="selected">M</option>
    </select>
    <select class="input1" onchange="OnChange(this)" name="score_2_2">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0" selected="selected">M</option>
    </select>
    <select class="input1" onchange="OnChange(this)" name="score_2_3">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0" selected="selected">M</option>
    </select>
    <select class="input1" onchange="OnChange(this)" name="score_2_4">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0" selected="selected">M</option>
    </select>
    <select class="input1" onchange="OnChange(this)" name="score_2_5">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0" selected="selected">M</option>
    </select>
    <select class="input1" onchange="OnChange(this)" name="score_2_6">
        <option value=""></option>
        <option value="X">X</option>
        <option value="9">9</option>
        <option value="7">7</option>
        <option value="5">5</option>
        <option value="3">3</option>
        <option value="1">1</option>
        <option value="0" selected="selected">M</option>
    </select>


    <span class="spacer"></span>
    <input type="text" maxlength="2" class="input2" value="0" id="total_row_2" /><!--assigned default value 0 and id-->
         <input type="text" maxlength="2" class="input3" value="0" id="final_row"/><!--The grand total appears here-->
</fieldset>

</form>

Fiddle:-http://jsfiddle.net/TRV4f/3/

Edit 1:- added comments in source

Edit 2:- As pointed out by user made changes to the previous source, which had bugs.

Sign up to request clarification or add additional context in comments.

5 Comments

Hi Mustafa, thank you for your answer. Your solution actually works great, however, my only concern is that I will require a diferent function for each row, and in some occasions, some score sheets could require up to 12 of them. I wonder if there is a more generic way to achieve this in javascript? I was reading at the option proposed by pablo above and it seems to address this issue, but I have no clue on how to work it out in javascript on my own.
The second issue is the fact that if somebody makes a mistake in one field and then corrects it, the form just keeps adding! without correcting, so you could have an incredibly big result for the sum, just because someone make several mistakes while selecting the results from the fields!! can this be sorted?
I dont think you understand the solution I proposed properly. No matter how many rows you have you will always need two functions only, 1st function OnChange(node) for calculating the total of each rows, and 2nd function OnChangeFinal() for calculating the sum in the final textBox. Even if you have 12 rows there will only be 2 functions, with minor changes in the function OnChange(node). About the bug yes, thanks for poitning out, I will make changes in the source.
I have updated my source, now it works fine, note that there can be many changes made to the source to improve it , for example you can assign each select tag a unique id instead of Name. You can call the OnChangeFinal() function from within the OnChange(node) function and remove the event mousemove etc etc. Hope I have shown you a way and you are free to explore more :)
Hi Mustafa, thank you very much for all your help. I think I'm starting to get the grasp of how your solution works now. I will keep exploring it only for me to have a full understanding of it, your help has been truly appreciated!
0

The function OnChange is using the global variable row to know which row is being modified. Your problems are:

  • You have several rows and row is always 1.
  • You have only a global variable (sum), but you'll need one for each row.

I suggest you to add a second paratemer to the function OnChange to let it know which the row is (just remove the global variable and add it as a parameter) and avoid the variable sum, using the current value of the fields when adding any amount:

function OnChange(value, row) {
    var sum= document.getElementById('total_row_'+ row).value + new Number(value);
    document.getElementById('total_row_'+ row).value = sum;
}

NOTE: Notice that this logic works when you set the value for the first time, but if there was a previous value, it won't be subtracted before the sum.

Then you can create a loop to calculate the sum of all previous rows, but I'd add an id to that text field to access it easily.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.