Home > OS >  Total sum of a filtered table using vanilla JS
Total sum of a filtered table using vanilla JS

Time:04-23

The only consideration for this question is, at the moment, I'm not using jQuery. Here's the code:

//I think here is where the problem relies, in the function I'm using to calculate the sum of the values under 'Valor' column:
var t1 = document.getElementById("emp-table");
getSum();
function getSum() {
  var sumVal = 0;
  for(var i = 1; i < t1.rows.length; i  ){
    sumVal = sumVal   parseInt(t1.rows[i].cells[6].innerHTML);
    document.getElementById("sumV").innerHTML = "Sum Value = " sumVal;
  }
};

function getUniqueValuesFromColumn() {
    var unique_col_values_dict = {}
    allFilters = document.querySelectorAll(".table-filter")
    allFilters.forEach((filter_i) => {
        col_index = filter_i.parentElement.getAttribute("col-index");
        const rows = document.querySelectorAll("#emp-table > tbody > tr")
        rows.forEach((row) => {
            cell_value = row.querySelector("td:nth-child(" col_index ")").innerHTML;
            if (col_index in unique_col_values_dict) {
                if (unique_col_values_dict[col_index].includes(cell_value)) {
                    //console.log("already exists");
                } else {
                    unique_col_values_dict[col_index].push(cell_value)
                }
            } else {
                unique_col_values_dict[col_index] = new Array(cell_value)
            }
        }); 
    });
    updateSelectOptions(unique_col_values_dict)
};

function updateSelectOptions(unique_col_values_dict) {
    allFilters = document.querySelectorAll(".table-filter")
    allFilters.forEach((filter_i) => {
        col_index = filter_i.parentElement.getAttribute('col-index')
        unique_col_values_dict[col_index].forEach((i) => {
            filter_i.innerHTML = filter_i.innerHTML   `\n<option value="${i}">${i}</option>`
        });

    });
};

function filter_rows() {
    allFilters = document.querySelectorAll(".table-filter")
    var filter_value_dict = {}
    allFilters.forEach((filter_i) => {
        col_index = filter_i.parentElement.getAttribute('col-index')
        value = filter_i.value
        if (value != "all") {
            filter_value_dict[col_index] = value;
        }
    });
    var col_cell_value_dict = {};
    const rows = document.querySelectorAll("#emp-table tbody tr");
    rows.forEach((row) => {
        var display_row = true;
        allFilters.forEach((filter_i) => {
            col_index = filter_i.parentElement.getAttribute('col-index')
            col_cell_value_dict[col_index] = row.querySelector("td:nth-child("   col_index  ")").innerHTML
        })
        for (var col_i in filter_value_dict) {
            filter_value = filter_value_dict[col_i]
            row_cell_value = col_cell_value_dict[col_i]
            if (row_cell_value.indexOf(filter_value) == -1 && filter_value != "all") {
                display_row = false;
                break;
            }
        }
        if (display_row == true) {
            row.style.display = "table-row"
        } else {
            row.style.display = "none"
        }
    })
};

//And finally, the 'onload' part to update the content:
window.onload = () => {
    console.log(document.querySelector("#emp-table > tbody > tr:nth-child(1) > td:nth-child(2) ").innerHTML);
};
getUniqueValuesFromColumn()
<body>
    <div >
        <div >
            <div >
                Lista Pagos
            </div>
            <div >
                <table id="emp-table" >
                    <thead>
                        <tr>
                            <th>id</th>
                            <th col-index = 2>Persona
                            <select  onchange="filter_rows()">
                                <option value="all"></option>
                            </select>
                            </th>
                            <th col-index = 3>Servicio
                            <select  onchange="filter_rows()">
                                <option value="all"></option>
                            </select>
                            </th>
                            <th col-index = 4>Año
                            <select  onchange="filter_rows()">
                                <option value="all"></option>
                            </select>
                            </th>
                            <th col-index = 5>Mes
                            <select  onchange="filter_rows()">
                                <option value="all"></option>
                            </select>
                            </th>
                            <th>id Recibo</th>
                            <th>Valor</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td> 33 </td>
                            <td> David Camacho </td>
                            <td> Gas </td>
                            <td> 2022 </td>
                            <td> 4 </td>
                            <td> 7 </td>
                            <td> 10000 </td>
                        </tr>
                    
                        <tr>
                            <td> 32 </td>
                            <td> Héctor Camacho </td>
                            <td> Gas </td>
                            <td> 2022 </td>
                            <td> 4 </td>
                            <td> 7 </td>
                            <td> 15075 </td>
                        </tr>
                    
                        <tr>
                            <td> 30 </td>
                            <td> Héctor Camacho </td>
                            <td> Seguro exequial </td>
                            <td> 2022 </td>
                            <td> 4 </td>
                            <td> 6 </td>
                            <td> 11100 </td>
                        </tr>
                    
                        <tr>
                            <td> 29 </td>
                            <td> María Camacho </td>
                            <td> Seguro exequial </td>
                            <td> 2022 </td>
                            <td> 4 </td>
                            <td> 6 </td>
                            <td> 11100 </td>
                        </tr>
                    
                        <tr>
                            <td> 28 </td>
                            <td> Mateo León </td>
                            <td> Internet </td>
                            <td> 2022 </td>
                            <td> 4 </td>
                            <td> 1 </td>
                            <td> 20000 </td>
                        </tr>
                    
                        <tr>
                            <td> 27 </td>
                            <td> David Camacho </td>
                            <td> Internet </td>
                            <td> 2022 </td>
                            <td> 4 </td>
                            <td> 1 </td>
                            <td> 11600 </td>
                        </tr>
                    
                        <tr>
                            <td> 24 </td>
                            <td> Alba Camacho </td>
                            <td> Internet </td>
                            <td> 2022 </td>
                            <td> 4 </td>
                            <td> 1 </td>
                            <td> 11600 </td>
                        </tr>
                    
                        <tr>
                            <td> 23 </td>
                            <td> María Camacho </td>
                            <td> Internet </td>
                            <td> 2022 </td>
                            <td> 4 </td>
                            <td> 1 </td>
                            <td> 11600 </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>

        <p id="sumV"></p>
        <br/>
        <br/>
    </div>
</body>

So, at the moment, whenever I load the page, the <span> tag already has the total amount if we consider all rows. But, whenever I filter the table, the value there doesn't change. At first, I tried to do it with a button using onclick, but every time I clicked it, it changed from the total value to 'undefined'. That's why I removed that button, and I'm considering to update the content in the <span> tag with the onload segment of my code, but I've been unable to achieve it so far.

Any help is greatly appreciated, cheers!

CodePudding user response:

You could replace your getSum function with the following

function getSum() {
  const rows = [...document.querySelectorAll('#emp-table tr').values()];
  const visibleRows = rows.filter(row => {
    return row.style.display !== 'none';
  });

  let sumVal = 0;
  for (let visibleRow of visibleRows){
    sumVal  = parseInt(visibleRow.cells[6].innerHTML);
  }
  document.getElementById("sumV").innerHTML = "Sum Value = "   sumVal;
};

Basically you first filter the rows based on their display value to get just the visibleRows and then sum up the values.

  • Related