JS: Sum column values and updating result on change

I have a table where, for each row, I must show the sum of two columns and present it in a third one. The sum must be calculated everytime any of the inputs change.

This is the structure of the table with sample data:

<tbody>
    <tr>
        <td>Element Name ABC</td>
        <td>
            <div class="form-group">
            <div><input id="SM-J3D-01-1" onkeyup="calc(this);" onchange="calc(this);" type="number" min="0" step="1" name="Validos" class="form-control" value="0" />
                 <span class="text-danger field-validation-valid" data-valmsg-for="Validos" data-valmsg-replace="true"></span>
            </div>
            </div>
        <td>
            <div class="form-group">
            <div><input id="SM-J3D-01-1" onkeyup="calc(this);" onchange="calc(this);" type="number" min="0" step="1" name="Cortesia" class="form-control" value="0" />
                 <span class="text-danger field-validation-valid" data-valmsg-for="Cortesia" data-valmsg-replace="true"></span>
             </div>
             </div>
         </td>
        <td>
            <div class="form-group">
            <div><input id="SM-J3D-01-1" type="number" readonly name="Total" class="form-control" value="0" />
            <span class="text-danger field-validation-valid" data-valmsg-for="Total" data-valmsg-replace="true"></span>
            </div>
            </div>
        </td>
    //Begining second row    
    <tr>
        <td>Element Name XYZ</td>
        <td>
            <div class="form-group">
            <div><input id="SM-J3D-01-2" onkeyup="calc(this);" onchange="calc(this);" type="number" min="0" step="1" name="Validos" class="form-control" value="0" />
                 <span class="text-danger field-validation-valid" data-valmsg-for="Validos" data-valmsg-replace="true"></span>
             </div>
             </div>
         </td>
         <td>
             <div class="form-group">
             <div><input id="SM-J3D-01-2" onkeyup="calc(this);" onchange="calc(this);" type="number" min="0" step="1" name="Cortesia" class="form-control" value="0" />
                  <span class="text-danger field-validation-valid" data-valmsg-for="Cortesia" data-valmsg-replace="true"></span>
              </div>
              </div>
          </td>
          <td>
              <div class="form-group">
              <div><input id="SM-J3D-01-2" type="number" readonly name="Total" class="form-control" value="0" />
                   <span class="text-danger field-validation-valid" data-valmsg-for="Total" data-valmsg-replace="true"></span>
               </div>
               </div>
           </td>

I'm starting to study Javascript but this goes beyond I know at the moment. So far I tried something I saw online but no luck. If you have a better proposal feel free to post it. I'll try to understand it and put it in practice.

JS:

    $(function calc(id) {
        var row = id.parentNode.parentNode;
        var validos = row.cells[6].getElementsByTagName('input')[0].value;
        var cortesia = row.cells[7].getElementsByTagName('input')[0].value;

        resultado = parseFloat(validos) + parseFloat(cortesia);

        row.cells[10].getElementsByTagName('input')[0].value = resultado;
    });

Thanks in advance for any suggestion.

Upvotes: 0

Views: 110

Answers (1)

Dabbas
Dabbas

Reputation: 3230

You can use this code. Add for each input (which the value gonna be taken from) this class for example: toBeCalced, and for each input which the total will be showed in, this class for example total.
In JS we gonna use JQuery to listen to change event, and do these steps:

  • go to parent row.
  • iterate over each children with class toBeCalced and add its value to total variable.
  • Get the total input by class name total and set the total value.

We get this result:

$(document).ready(function() {
    $('.toBeCalced').change(function() {
      var row = $(this).closest('tr');
      var valuesToSum = row.find('.toBeCalced');
      var total = 0;
      $.each(valuesToSum, function(index, item) {
        total += parseInt($(item).val());
      });

      var totalInput = row.find('.total')[0];
      $(totalInput).val(total);
    });
  });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
  <tr>
      <td>Element Name ABC</td>
      <td>
          <div class="form-group">
          <div><input id="SM-J3D-01-1" type="number" min="0" step="1" name="Validos" class="toBeCalced form-control" value="0" />
               <span class="text-danger field-validation-valid" data-valmsg-for="Validos" data-valmsg-replace="true"></span>
          </div>
          </div>
      </td>
      <td>
          <div class="form-group">
          <div><input id="SM-J3D-01-1" type="number" min="0" step="1" name="Cortesia" class="toBeCalced form-control" value="0" />
               <span class="text-danger field-validation-valid" data-valmsg-for="Cortesia" data-valmsg-replace="true"></span>
           </div>
           </div>
       </td>
      <td>
          <div class="form-group">
          <div><input id="SM-J3D-01-1" type="number" readonly name="Total" class="total form-control" value="0" />
          <span class="text-danger field-validation-valid" data-valmsg-for="Total" data-valmsg-replace="true"></span>
          </div>
          </div>
      </td>
  </tr>
  //Begining second row    
  <tr>
      <td>Element Name XYZ</td>
      <td>
          <div class="form-group">
          <div><input id="SM-J3D-01-2" type="number" min="0" step="1" name="Validos" class="toBeCalced form-control" value="0" />
               <span class="text-danger field-validation-valid" data-valmsg-for="Validos" data-valmsg-replace="true"></span>
           </div>
           </div>
       </td>
       <td>
           <div class="form-group">
           <div><input id="SM-J3D-01-2" type="number" min="0" step="1" name="Cortesia" class="toBeCalced form-control" value="0" />
                <span class="text-danger field-validation-valid" data-valmsg-for="Cortesia" data-valmsg-replace="true"></span>
            </div>
            </div>
        </td>
        <td>
            <div class="form-group">
            <div><input id="SM-J3D-01-2" type="number" readonly name="Total" class="total form-control" value="0" />
                 <span class="text-danger field-validation-valid" data-valmsg-for="Total" data-valmsg-replace="true"></span>
             </div>
             </div>
         </td>
      </tr>
    </tbody>
  </table>

Upvotes: 1

Related Questions