简体   繁体   中英

Can't properly delete rows from a dynamically generated table using a button

I have the following code which is supposed to generate rows in a table where each row has its own content and 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 press, it deletes the last row. I tried using console.log(this.parentNode.parentNode) to see if it returns the right <tr> object, and it indeed does. But for some reason, the attribute rowIndex is -1 no matter what button is pressed; hence only the last row is deleted. Does it mean that each dynamically generated <tr> doesn't know its row index?

You can use HTMLTableElement.insertRow() function instead.

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

Here is a working fiddle

Update

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

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

There are numerous way to achieve what you require. Here is another such example that is based on the code that you posted. Hopefully it will give you some further 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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM