Home > Software engineering >  delete multiply HTML rows based on checkbox
delete multiply HTML rows based on checkbox

Time:01-25

The table below initially creates 5 rows, now I want to delete all rows where the checkbox is selected. To do so I insert a checkbox in cell[0]. The delete button iterates through all rows and should delete all rows with a checked checkbox.

It does work, if only one checkbox is selected but seems buggy if multiply rows are checked. I assume the issue appears because the index changes as soon as the first checked row was deleted. Nethertheless how could I achieve a similar behavour without the need to create single delete buttons for each row?

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>

<style>
    table, th, td {
        border: 1px solid black;
    }
</style>

<body>
    <div id="wrapper">
        <button id="deleteRow">-</button>
        <table id="table">
            <tbody>
                <!-- filled by script -->
            </tbody>
        </table>
    </div>

    <script>

        // add initial rows
        var table = document.getElementById("table")

        for (var i = 0; i < 5 ; i  ) {
            var row = table.insertRow(i)
            var cell0 = row.insertCell(0);
            var cell1 = row.insertCell(1);
            var cell2 = row.insertCell(2);

            cell0.contentEditable = false;
            cell1.contentEditable = true;
            cell2.contentEditable = true;

            cell0.innerHTML = '<input type="checkbox">';
            cell1.innerHTML = 'Property: '   i;
            cell2.innerHTML = 'Value';
        }

        // BUTTON: delete row
        document.getElementById("deleteRow").addEventListener("mouseup", function() {
            var table = document.getElementById("table");
            var row = table.rows;
            
            for (var i = 0; i < row.length; i  ) {
                if (row[i].cells[0].firstElementChild.checked) {
                    table.deleteRow(i);
                }
            }
        })
    </script>
</body>
</html>

CodePudding user response:

I would not iterate over the rows, instead use a querySelectorAll for all checked checkboxes and remove the parent tr element. Like this:

document.getElementById("deleteRow").addEventListener("click", function() {
  const checkboxes = document.querySelectorAll('input:checked');
  checkboxes.forEach(checkbox => checkbox.parentElement.parentElement.remove());
})

Here's the full example:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>

<style>
  table,
  th,
  td {
    border: 1px solid black;
  }
</style>

<body>
  <div id="wrapper">
    <button id="deleteRow">-</button>
    <table id="table">
      <tbody>
        <!-- filled by script -->
      </tbody>
    </table>
  </div>

  <script>
    // add initial rows
    var table = document.getElementById("table")

    for (var i = 0; i < 5; i  ) {
      var row = table.insertRow(i)
      var cell0 = row.insertCell(0);
      var cell1 = row.insertCell(1);
      var cell2 = row.insertCell(2);

      cell0.contentEditable = false;
      cell1.contentEditable = true;
      cell2.contentEditable = true;

      cell0.innerHTML = '<input type="checkbox">';
      cell1.innerHTML = 'Property: '   i;
      cell2.innerHTML = 'Value';
    }

    // BUTTON: delete row
    document.getElementById("deleteRow").addEventListener("click", function() {
      const checkboxes = document.querySelectorAll('input:checked');
      checkboxes.forEach(checkbox => checkbox.parentElement.parentElement.remove());
    })
  </script>
</body>

</html>

CodePudding user response:

When 0th and 1st row should be removed, the indices changes after table.deleteRow(i).

Consider deleting them at once or backward.

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>

<style>
    table, th, td {
        border: 1px solid black;
    }
</style>

<body>
    <div id="wrapper">
        <button id="deleteRow">-</button>
        <table id="table">
            <tbody>
                <!-- filled by script -->
            </tbody>
        </table>
    </div>

    <script>

        // add initial rows
        var table = document.getElementById("table")

        for (var i = 0; i < 5 ; i  ) {
            var row = table.insertRow(i)
            var cell0 = row.insertCell(0);
            var cell1 = row.insertCell(1);
            var cell2 = row.insertCell(2);

            cell0.contentEditable = false;
            cell1.contentEditable = true;
            cell2.contentEditable = true;

            cell0.innerHTML = '<input type="checkbox">';
            cell1.innerHTML = 'Property: '   i;
            cell2.innerHTML = 'Value';
        }

        // BUTTON: delete row
        document.getElementById("deleteRow").addEventListener("mouseup", function() {
            var table = document.getElementById("table");
            var row = table.rows;
            
            for (var i = row.length-1; i >= 0; i--) {
                if (row[i].cells[0].firstElementChild.checked) {
                    table.deleteRow(i);
                }
            }
        })
    </script>
</body>
</html>

CodePudding user response:

how about just the button?

<button onclick="document.querySelectorAll('#table input:checked').forEach( el => el.parentNode.parentNode.remove() )" >
  Delete rows 
</button>
  •  Tags:  
  • Related