Home > Blockchain >  calculate sum of each .col-* with same position on different row
calculate sum of each .col-* with same position on different row

Time:12-28

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 >
  <div ><input type="number" /></div>
  <div ><input type="number" /></div>
  <div ><input type="number" /></div>
</div>
<div >
  <div ><input type="number" /></div>
  <div ><input type="number" /></div>
  <div ><input type="number" /></div>
</div>
<div >
  <div ><input type="number" /></div>
  <div ><input type="number" /></div>
  <div ><input type="number" /></div>
</div>

<div >
  <div ></div>
  <div ></div>
  <div ></div>
</div>

<div >
  <div >(( row1 col1(first-child)   row2 col1(first-child)   row3 col1(first-child) = 12 ))</div>
  <div >(( row1 col2(second-child)   row2 col2(second-child)   row3 col2(second-child) = 8 ))</div>
  <div >(( 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>

CodePudding user response:

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" >
  <strong>Column Sum</strong>
  <div >
    <div >
      <input type="number"  required value="3">
    </div>
    <div >
      <input type="number"  required value="2">
    </div>
    <div >
      <input type="number"  required value="1">
    </div>
  </div>
  <div >
    <div >
      <input type="number"  required value="4">
    </div>
    <div >
      <input type="number"  required value="4">
    </div>
    <div >
      <input type="number"  required value="1">
    </div>
  </div>
  <div >
    <div >
      <input type="number"  required value="5" />
    </div>
    <div >
      <input type="number"  required value="2" />
    </div>
    <div >
      <input type="number"  required value="4" />
    </div>
  </div>

  <div >
    <div >
      <input type="number"  readonly value="0">
    </div>
    <div >
      <input type="number"  readonly value="0">
    </div>
    <div >
      <input type="number"  readonly value="0">
    </div>
  </div>
</div>

<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">

CodePudding user response:

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 >
  <div >3</div>
  <div >2</div>
  <div >1</div>
</div>
<div >
  <div >4</div>
  <div >4</div>
  <div >1</div>
</div>
<div >
  <div >5</div>
  <div >2</div>
  <div >4</div>
</div>

<div >
  <div ></div>
  <div ></div>
  <div ></div>
</div>

CodePudding user response:

ok, my answer is very short, can any one edit and add explain

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>

<script>
    $(function(){
    var result={};
    $('.row:has(.col-1):not(.result)').each(function(ir,r){
      $(r).children('.col-1').each(function(ic,c){
        //console.log(c,ic);
        if(!result.hasOwnProperty(ic))result[ic]=0;
        result[ic] =parseFloat($( c ).text().replace(',',''));
      });
    });
    for(var v in Object.keys(result)){
    $('.result').children()[v].innerText=result[v];
    }
    });
</script>
 <div >
        <div >3</div>
        <div >2</div>
        <div >1</div>
    </div>
    <div >
        <div >4</div>
        <div >4</div>
        <div >1</div>
    </div>
    <div >
        <div >5</div>
        <div >2</div>
        <div >4</div>
    </div>

    <div >
        <div ></div>
        <div ></div>
        <div ></div>
    </div>

  • Related