0

I am currently having a problem upon addition of elements to a div. Upon clicking the links with class closeBtn, the output on the console.log() should be their ID. I am not quite sure what went wrong, since I checked i and it increments properly. Maybe I just overlooked something, although I can't figure it out.

What I want is for every delRow() to output the id that the current row it is on.

Here is the HTML file:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script type="text/javascript">
        function addRow() {
            var divRow = document.getElementsByClassName("row");
            var subRow = document.getElementsByClassName("subRow");
            var subLastElement = subRow[subRow.length-1].outerHTML;

            divRow[0].innerHTML += subLastElement;

            var closeArr = document.getElementsByClassName("closeBtn");

            // The problem here is that it adds the most recently made function for every close button.
            for(i = 1; i < closeArr.length; i++) {
                var idToStr = "x" + i.toString();
                closeArr[i].id = idToStr;
                closeArr[i].onclick = () => delRow(idToStr);
            }
        }
        function delRow(id) {
            console.log(id);
        }
    </script>
</head>
<body>
    <div class="row">
        <div class="subRow">
            <a href="#" class="addRow" onclick="addRow()">Add row</a>
            <span class="subSubRow">
                <a href="#" id="x1" class="closeBtn">&times;</a>
            </span>
        </div>
    </div>
</body>
</html>

Below are the outputs when I click × as of the moment:

Current output upon clicking x:
First row = No output
Second Row = x1

Upon adding another row:
First row = No output
Second Row = x2
Third Row = x2

This is the output I am expecting:

Expected output upon clicking x:
First row = x0
Second Row = x1

Upon adding another row:
First row = x0
Second Row = x1
Third Row = x2
VLAZ
  • 18,437
  • 8
  • 35
  • 54
Jsandesu
  • 95
  • 11
  • I found one thing I overlooked, I should've set `i = 0` in the loop. The main problem still remains though. – Jsandesu Mar 16 '21 at 15:49
  • 3
    1. you use `var` to declare all variables. Use `let` or `const`. 2. the loop index `i` is not declared. 3. See [Javascript infamous Loop issue?](https://stackoverflow.com/q/1451009) 4. Strongly consider not setting unique IDs programmatically. There are legitimate uses but in a lot of cases, it's a sign that something is wrong. – VLAZ Mar 16 '21 at 15:51
  • 1
    You overwrite all event listeners every time you add a row, and `idToStr` changes within the loop, so when a row is clicked, `idToStr` will have changed to the last ID already. Use `const` instead of `var`. – Sebastian Simon Mar 16 '21 at 15:51
  • 2
    Use [event delegation](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_delegation) instead of assigning multiple events — it’s more maintainable, and applies to dynamically added elements. E.g., use an [event argument](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#The_event_listener_callback)’s [`target`](https://developer.mozilla.org/en-US/docs/Web/API/Event/target). See [the tag info](https://stackoverflow.com/tags/event-delegation/info) and [What is DOM Event delegation?](https://stackoverflow.com/q/1687296/4642212). – Sebastian Simon Mar 16 '21 at 15:52
  • 2
    @SebastianSimon is correct. I didn't get a good look at the code the first time around. As I said, creating dynamic IDs *is* wrong in this case. You can just do `e => delRow(e.target)` which passes the entire original element. I'd also like to add a 5. to my list - don't use `el.onclick = /* some handler */` - use `el.addEventListener("click", /* some handler */)`. That is a more general advice, event delegation is the correct approach here. – VLAZ Mar 16 '21 at 15:55
  • Looks like me using outdated declarations was the problem all along. @SebastianSimon's first answer worked like a charm. As for the recommendations, I'll apply them soon. Those are nice insights. Thank you very much both of you. – Jsandesu Mar 16 '21 at 16:06

0 Answers0