Home>

We create a matrix that users like Excel can type in with javascript.
I wanted to have a function such as generating a row with the add button at the right end in the first row and deleting its own row in the rightmost cell of each row, but I made the following program, but the addition works, but the first works Only lines are allowed.
The idea is that compound lines are not working well because they cannot be deleted, but I don't know the solution. Nice to meet you.

(html)







































1 2 3 4 5 6 7 8 9 10





(javascript)

'use strict'

let add = document.getElementById ("add");

add.addEventListener ("click", function () {

let tbody = document.getElementById ("addlist");

let tr = tbody.firstElementChild.cloneNode ("true");

tbody.insertBefore (tr, tbody.lastChild)
})

let remove = document.getElementById ("remove");

remove.addEventListener ("click", function () {

let tbody = document.getElementById ("addlist");

let tr = remove.parentNode.parentNode;

tbody.removeChild (tr);
})

  • Answer # 1

    There is no delete event handler set for the Delete button on the duplicated line.
    You can set a handler each time you add, but in such a case, you should go back to the ancestor direction and set an event on an immovable element (tbody, table, body, etc.) that is not added or deleted . (Event delegation)

    Specifically the following part ...

    let remove = document.getElementById ("remove");
    remove.addEventListener ("click", function () {
      let tbody = document.getElementById ("addlist");
      let tr = remove.parentNode.parentNode;
      tbody.removeChild (tr);
    });


    It works by rewriting the following code.

    addlist.addEventListener ("click", function () {
      if (event.target.id === 'remove') {
        let tr = event.target.parentNode.parentNode;
        this.removeChild (tr);
      }
    });


    Since it is not good for multiple elements to have the same id, it is better to review them in the future.

  • Answer # 2

    Hello

    There are two points to be noted when modifying the code listed in the question to the one that works as intended:

      

    Note
      When you duplicate a node, all the attributes and values ​​for that node are copied. In other words, it includes HTML attribute events. Anything that uses addEventListener () or is assigned to an element property (eg node.onclick = fn;) will not be replicated.

    and

      

    Note: Using cloneNode () can result in duplicate element ids in the document.

    . The following two points will be corrected along these lines.

    (1) Fix for processing when clicking the delete button in the new line. This can be one of the following two.

    A: Set up a click handler for the delete button contained in a new row each time a row is added.

    B: Set a click handler to the upper layer element that is not affected by the addition or deletion of a row, and delete the row when event.target is a delete button.

    (2) Currently,"remove"is changed to the class that the id of the delete button is changed

    The following code example reflects the above corrections. In the following, for (1) above, A is adopted, and the click handler set for the delete button is a separate function.

    document.addEventListener ('DOMContentLoaded', function () {
      let addCount = 0;// Additional line counter
      function removeRow (event) {
        const tr = event.target.parentNode.parentNode;
        const tbody = document.getElementById ("addlist");
        tbody.removeChild (tr);
      }
      const add = document.getElementById ("add");
      add.addEventListener ("click", function () {
        const tbody = document.getElementById ("addlist");
        const tr = tbody.firstElementChild.cloneNode (true);tbody.insertBefore (tr, tbody.lastChild);
        const remove = tr.querySelector (". remove");
        remove.addEventListener ("click", removeRow);
        // Put the additional line number in the leftmost td of the added line.
        tr.querySelector ("td"). textContent = ++ addCount;
      })
      const remove = document.querySelector (". remove");
      remove.addEventListener ("click", removeRow);
    });

    CodePen for operation check:https://codepen.io/jun68ykt/pen/pooBOWv?editors=1010

    In the above, the following two points have been corrected and added as supplements.

    Variables that do not need to be

    letare set toconst.

    Enter the additional line number inat the left end of the added line. (* This is so that when the delete button is clicked, you can visually confirm that the line containing the button is deleted.)

    Thank you for your reference.

    Remarks

    The correction (1)

    written in the above answer

    B: Set a click handler to the upper layer element that is not affected by the addition or deletion of a row, and delete the row when event.target is a delete button.

    Regarding

    , shinji709 has written an easy-to-understand answer, so please refer to it.