Home > Software engineering >  Sum total values ​with footerCallback
Sum total values ​with footerCallback

Time:01-17

I have the following code that returns the values ​​for the tbody of the table.

In this table I want to have tfoot to add the value of the last column and I'm doing it this way:

var data = [
   {Id: "1", Quantidade:  "14", Preco: "3.10", },
   {Id: "2", Quantidade: "5", Preco: "1.80", },
   {Id: "3", Quantidade: "3", Preco: "0.45", },
   {Id: "4",  Quantidade: "4", Preco: "9.83",  },
   {Id: "5", Quantidade: "2", Preco: "15.30", },
   {Id: "6",  Quantidade: "3", Preco: "9.98",  },
];

$('.enc-per').on("click", function() {

  
  var linha = ``;
  
  Object.keys(data).forEach(b => {
  
    Id = data[b].Id;
    Qtd = data[b].Quantidade;
    Preco = data[b].Preco;
    Total = data[b].Quantidade * data[b].Preco;
    
    linha  = `<tr>
               <td > ${Id}</td>
               <td > ${Qtd}</td>
               <td > ${Preco}</td>
               <td > ${Total}</td>
             </tr>`;

 })
 $("#encofinal tbody").html(linha);
 
 $('.encofinal').DataTable({
   fixedHeader: {
      header: true,
      footer: true
   }, 
   footerCallback: function(){
      const sumProduct = this
        .api()
        .rows({search:'applied'})
        .data()
        .toArray()
        .reduce((res,row) => {
     const Quantidade = row[1];
     const Preco = row[2];
     return res  = Quantidade*Preco}, 0).toFixed(2);
        $('#sumproduct').text(sumProduct);
   }
 });
          
          
});
<link href="https://cdn.datatables.net/1.11.4/css/dataTables.bootstrap5.min.css" rel="stylesheet">
    <link href="https://cdn.datatables.net/buttons/2.2.2/css/buttons.bootstrap5.min.css" rel="stylesheet">

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.11.4/js/jquery.dataTables.min.js"></script>
    <script src="https://cdn.datatables.net/1.11.4/js/dataTables.bootstrap5.min.js"></script>
    <script src="https://cdn.datatables.net/buttons/2.2.2/js/dataTables.buttons.min.js"></script>
    <script src="https://cdn.datatables.net/buttons/2.2.2/js/buttons.bootstrap5.min.js"></script>

<button type="button"  style="float: right; margin-right: 5%; margin-top: 4%;"><i ></i> Consultar </button>


<table  id="encofinal">
  <thead>
    <tr>
      <th >Pedido</th>
      <th >Qtd</th>
      <th >Preço</th>
      <th >Valor</th>
    </tr>
  </thead>
  <tbody>
  </tbody>
  <tfoot>
    <tr>
      <td COLSPAN="2"></td>
      <td COLSPAN="3">Valor Total: <span id="sumproduct"></span>€</td>
    </tr>
  </tfoot>
</table>

But it returns the values ​​correctly, but the sum of tfoot returns error. I think the problem is sending the data to tfoot.

Can you help me solve the problem?

error console:

Uncaught TypeError: Cannot set properties of undefined (setting 'nTf')
    at Fb (jquery.dataTables.min.js:40:282)
    at Ba (jquery.dataTables.min.js:62:151)
    at f (jquery.dataTables.min.js:108:98)
    at HTMLTableElement.<anonymous> (jquery.dataTables.min.js:108:184)
    at Function.each (jquery-3.6.0.min.js:2:3003)
    at S.fn.init.each (jquery-3.6.0.min.js:2:1481)
    at S.fn.init.u [as dataTable] (jquery.dataTables.min.js:98:199)
    at HTMLButtonElement.<anonymous> (jsdashboard.js:21510:21)
    at HTMLButtonElement.dispatch (jquery-3.6.0.min.js:2:43064)
    at v.handle (jquery-3.6.0.min.js:2:41048)

CodePudding user response:

The error is being caused by the fact that your table has an inconsistent number of columns in each row. Most have 4 but your table footer spans 5 columns (2 3):

    <tr>
      <td COLSPAN="2"></td>
      <td COLSPAN="3">Valor Total: <span id="sumproduct"></span>€</td>
    </tr>

Corrected to span only 4 columns and it works:

var data = [
   {Id: "1", Quantidade:  "14", Preco: "3.10", },
   {Id: "2", Quantidade: "5", Preco: "1.80", },
   {Id: "3", Quantidade: "3", Preco: "0.45", },
   {Id: "4",  Quantidade: "4", Preco: "9.83",  },
   {Id: "5", Quantidade: "2", Preco: "15.30", },
   {Id: "6",  Quantidade: "3", Preco: "9.98",  },
];

$('.enc-per').on("click", function() {


  var linha = ``;

  Object.keys(data).forEach(b => {

    Id = data[b].Id;
    Qtd = data[b].Quantidade;
    Preco = data[b].Preco;
    Total = data[b].Quantidade * data[b].Preco;

    linha  = `<tr>
               <td > ${Id}</td>
               <td > ${Qtd}</td>
               <td > ${Preco}</td>
               <td > ${Total}</td>
             </tr>`;

  })
  $("#encofinal tbody").html(linha);

  $('.encofinal').DataTable({
    fixedHeader: {
      header: true,
      footer: true
    },
    footerCallback: function() {
      const sumProduct = this
        .api()
        .rows({
          search: 'applied'
        })
        .data()
        .toArray()
        .reduce((res, row) => {
          const Quantidade = row[1];
          const Preco = row[2];
          return res  = Quantidade * Preco
        }, 0).toFixed(2);
      $('#sumproduct').text(sumProduct);
    }
  });


});
<link href="https://cdn.datatables.net/1.11.4/css/dataTables.bootstrap5.min.css" rel="stylesheet">
<link href="https://cdn.datatables.net/buttons/2.2.2/css/buttons.bootstrap5.min.css" rel="stylesheet">

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.11.4/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.11.4/js/dataTables.bootstrap5.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.2.2/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/buttons/2.2.2/js/buttons.bootstrap5.min.js"></script>

<button type="button"  style="float: right; margin-right: 5%; margin-top: 4%;"><i ></i> Consultar </button>


<table  id="encofinal">
  <thead>
    <tr>
      <th >Pedido</th>
      <th >Qtd</th>
      <th >Preço</th>
      <th >Valor</th>
    </tr>
  </thead>
  <tbody>
  </tbody>
  <tfoot>
    <tr>
      <td COLSPAN="2"></td>
      <td COLSPAN="2">Valor Total: <span id="sumproduct"></span>€</td>
    </tr>
  </tfoot>
</table>

  • Related