Unable to properly delete rows from dynamically created table using button

I have the following code that is supposed to generate rows in a table where each row has its own content and a delete button.

<!DOCTYPE html>
<html>
    <head>
        <title>table</title>
    </head>
    <body>
        <input id="inputText">
        <button onclick = "addRow()">Add text</button>

        <table id = "table">
        </table>
        <script>
            function addRow(){

                var newRow = document.createElement("tr");
                var col1 = document.createElement("td");
                var col2 = document.createElement("td");
                newRow.appendChild(col1);
                newRow.appendChild(col2);

                var button = document.createElement("button");
                button.innerHTML = "delete";

                button.onclick = function () {
                    var index = this.parentNode.parentNode.rowIndex;
                    document.getElementById("table").deleteRow(index);
                }
                col1.appendChild(button);


                var enteredText = document.getElementById("inputText").value;
                col2.innerHTML = enteredText;

                document.getElementById("table").appendChild(newRow);

            }
        </script>
    </body>
</html>

      

The problem is that no matter which delete button I click, it deletes the last line. I tried using console.log(this.parentNode.parentNode)

to see if it returns the right object <tr>

and it does. But for some reason the attribute rowIndex

is -1 no matter which button is pressed; so only the last line is removed. Does this mean that each dynamically generated one <tr>

doesn't know its row index?

+3


source to share


2 answers


You can use instead HTMLTableElement.insertRow()

.

var newRow = document.getElementById("table").insertRow();
// newRow.rowIndex will return you the proper index

      

Here is a working violin



Update

It was a bug in the Webkit layout engine (which was also moving to the forked Blink engine). This is why it works well in Firefox, but not in earlier versions of Chrome (Blink) or Safari (Webkit).

The bug report is here , now it's fixed.

+2


source


There are many ways to get what you want. Here's another example based on the code you posted. Hope this gives you some more ideas.



(function() {
  // create references to static elements, no need to search for them each time
  var inputText = document.getElementById("inputText"),
      butAdd = document.getElementById("butAdd"),
      table = document.getElementById("table");

  // a generic function for finding the first parent node, starting at the given node and
  // of a given tag type. Retuns document if not found.
  function findParent(startNode, tagName) {
    var currentNode,
        searchTag;

    // check we were provided with a node otherwise set the return to document
    if (startNode && startNode.nodeType) {
      currentNode = startNode;
    } else {
      currentNode = document;
    }

    // check we were provided with a string to compare against the tagName of the nodes
    if (typeof tagName === 'string') {
      searchTag = tagName.toLowerCase();
    } else {
      currentNode = document;
    }

    // Keep searching until we find a parent with a mathing tagName or until we get to document
    while (currentNode !== document && currentNode.tagName.toLowerCase() !== searchTag) {
      currentNode = currentNode.parentNode;
    }

    // return the match or document
    return currentNode;
  }

  // for deleting the current row in which delete was clicked
  function deleteRow(e) {
    // find the parent with the matching tagName
    var parentTr = findParent(e.target, 'tr');

    // did we find it?
    if (parentTr !== document) {
      // remove it
      parentTr.parentNode.removeChild(parentTr);
    }
  }

  // for adding a row to the end of the table
  function addRow() {
    // create the required elements
    var newRow = document.createElement("tr"),
        col1 = document.createElement("td"),
        col2 = document.createElement("td"),
        button = document.createElement("button");

    // add some text to the new button
    button.appendChild(document.createTextNode("delete"));
    // add a click event listener to the delete button
    button.addEventListener('click', deleteRow, false);

    // append all the required elements
    col1.appendChild(button);
    col2.appendChild(document.createTextNode(inputText.value));
    newRow.appendChild(col1);
    newRow.appendChild(col2);

    // finally append all the elements to the document
    table.appendChild(newRow);
  }

  // add click event listener to the static Add text button
  butAdd.addEventListener('click', addRow, false);
}());
      

<input id="inputText">
<button id="butAdd">Add text</button>
<table id="table"></table>
      

Run code


+1


source







All Articles