skip to Main Content

I want to sum each column with the next column that is in the same position in the next .row. For example:

All columns are created dynamically and have the same class. Can you help me to do it (with jQuery o Javascript)?

$(document).ready(function() {
  var sum = 0;

  $('.col-1').each(function(index) {
    sum += parseFloat($(this).text().replace(',', ''));
  });

  $('.total').html(sum);
});
<div class="row">
  <div class="col-1"><input type="number" /></div>
  <div class="col-1"><input type="number" /></div>
  <div class="col-1"><input type="number" /></div>
</div>
<div class="row">
  <div class="col-1"><input type="number" /></div>
  <div class="col-1"><input type="number" /></div>
  <div class="col-1"><input type="number" /></div>
</div>
<div class="row">
  <div class="col-1"><input type="number" /></div>
  <div class="col-1"><input type="number" /></div>
  <div class="col-1"><input type="number" /></div>
</div>

<div class="result">
  <div class="col-1"></div>
  <div class="col-1"></div>
  <div class="col-1"></div>
</div>

<div class="result">
  <div class="col-1">(( row1 col1(first-child) + row2 col1(first-child) + row3 col1(first-child) = 12 ))</div>
  <div class="col-1">(( row1 col2(second-child) + row2 col2(second-child) + row3 col2(second-child) = 8 ))</div>
  <div class="col-1">(( row1 col3(third-child) + row2 col3(third-child) + row3 col3(third-child) = 6 ))</div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>

2

Answers


  1. First find how many rows there are. If it’s constant, then use a constant number instead.

    Then just run through each .row except for results, and add-up to totals.

    Finally show results.

    $(document).ready(function () {
       var totalRows = $('.row').eq(0).find('.col-1').length;
       var totals = {};
       
       $('.row:not(.result)').each(function () {
           for (var i = 0; i < totalRows; i++) {
               if (totals[i] === undefined) {
                   totals[i] = 0;
               }
               
               totals[i] += parseInt($(this).find('.col-1').eq(i).text());
           }
       });
       
       console.table(totals);
       
       $.each(totals, function (index, total) {
           $('.row.result .col-1').eq(index).text(total);
       });
    });
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="row">
      <div class="col-1">3</div>
      <div class="col-1">2</div>
      <div class="col-1">1</div>
    </div>
    <div class="row">
      <div class="col-1">4</div>
      <div class="col-1">4</div>
      <div class="col-1">1</div>
    </div>
    <div class="row">
      <div class="col-1">5</div>
      <div class="col-1">2</div>
      <div class="col-1">4</div>
    </div>
    
    <div class="row result">
      <div class="col-1"></div>
      <div class="col-1"></div>
      <div class="col-1"></div>
    </div>
    Login or Signup to reply.
  2. Plain JavaScript Solution

    Using plain JavaScript you can sum the columns with one (long) line of code.
    This solution uses the nth-child(index) selector to get all the values in a column. The + prefix on innerText coerces the string to a number when doing the sum. See browser support for the :not selector before using.

    document.querySelectorAll('.result .col-1').forEach((result,index) => 
        document.querySelectorAll(`.row:not(.result) .col-1:nth-child(${index+1})`)
        .forEach(cell => result.innerText = +result.innerText + +cell.innerText)
    );
    

    Update

    In a follow up question, OP asks how to dynamically sum inputs in a column. This can be done by modifying the original code to select the inputs and sum their values. We also need to reset the column sum during each update. This is done using ternary operator that sets the previous sum to zero when the index is zero. The snippet contains additional code for the event handler and validation.

      document.querySelectorAll('.result .col-1 input').forEach((result, index) =>
        document.querySelectorAll(`.row:not(.result) .col-1:nth-child(${index+1}) input`)
        .forEach((cell,i) => result.value = +cell.value + (i ? +result.value : 0))
      );
    

    Snippet

    Open and run the snippet to understand how it works.

    function update(event) {
      document.querySelectorAll('.result .col-1 input').forEach((result, index) =>
        document.querySelectorAll(`.row:not(.result) .col-1:nth-child(${index+1}) input`)
        .forEach((cell,i) => result.value = +cell.value + (i ? +result.value : 0))
      );
      
      // optional - browser displays message when input invalid
      if (event) event.target.reportValidity(); 
      
    }
    
    document.addEventListener("DOMContentLoaded", function() {
    
      // update once on page load
      update();
    
      // update after when there is a change
      document.querySelector('#showsum').addEventListener('change', update);
    
    })
    
    
    /* original solution 
    document.querySelectorAll('.result .col-1').forEach((result, index) =>
      document.querySelectorAll(`.row:not(.result) .col-1:nth-child(${index+1})`)
      .forEach(cell => result.innerText = +result.innerText + +cell.innerText)
    );
    */
    .col-1 {
      min-width: 5rem;
    }
    <div id="showsum" class="container p-2">
      <strong>Column Sum</strong>
      <div class="row">
        <div class="col-1 p-1">
          <input type="number" class="form-control text-end" required value="3">
        </div>
        <div class="col-1 p-1">
          <input type="number" class="form-control text-end" required value="2">
        </div>
        <div class="col-1 p-1">
          <input type="number" class="form-control text-end" required value="1">
        </div>
      </div>
      <div class="row">
        <div class="col-1 p-1">
          <input type="number" class="form-control text-end" required value="4">
        </div>
        <div class="col-1 p-1">
          <input type="number" class="form-control text-end" required value="4">
        </div>
        <div class="col-1 p-1">
          <input type="number" class="form-control text-end" required value="1">
        </div>
      </div>
      <div class="row">
        <div class="col-1 p-1">
          <input type="number" class="form-control text-end" required value="5" />
        </div>
        <div class="col-1 p-1">
          <input type="number" class="form-control text-end" required value="2" />
        </div>
        <div class="col-1 p-1">
          <input type="number" class="form-control text-end" required value="4" />
        </div>
      </div>
    
      <div class="row result">
        <div class="col-1 p-1">
          <input type="number" class="form-control text-end text-primary" readonly value="0">
        </div>
        <div class="col-1 p-1">
          <input type="number" class="form-control text-end text-primary" readonly value="0">
        </div>
        <div class="col-1 p-1">
          <input type="number" class="form-control text-end text-primary" readonly value="0">
        </div>
      </div>
    </div>
    
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search