I’m making a dynamic list where users can click a button to remove inputs. When creating new inputs I’m assigning an ID to the child element with a counter that adds 1 every time a new input is generated. But when I try to remove inputs by their ID’s, only the latest created input seems to be removable.
I’ve noticed that if you generate say 5 new inputs, and then click the remove button on say input:2, then it removes the 5th input and button. So even though I’m setting the input and button ID’s earlier on in the process, clicking the remove button is relying on the row counter’s current value only.
Could anyone give me some pointers as to how to whether old IDs can be pointed to or if I would need to rewrite this in a totally different way? I’m very new to JS so apologies if this is horrendous JS scripting!
var row = 1;
function addFields() {
row++;
var container = document.getElementById("container");
var input = document.createElement("input");
input.id = "input_" + row
input.type = "text";
input.placeholder = "input:" + row;
container.appendChild(input);
var button = document.createElement("button");
button.id = "button_" + row;
button.type = "button";
button.innerText = "Remove";
button.onclick = function() {
remove_field("button_" + row, "input_" + row);
}
container.appendChild(button);
}
function remove_field(button_id, input_id) {
var elem = document.getElementById(button_id);
elem.remove();
var elem = document.getElementById(input_id);
elem.remove();
}
<input type="text" id="goal" name="goal">
<button type="button" onclick="addFields()">+</button><br>
<div class="container" id="container" />
3
Answers
The value of
row
updates each time you add a new element, so don’t directly userow
to get the id. Directly accessbutton.id
andinput.id
instead.Alternatively, get rid of the
remove_field
function entirely and just callremove
on the variablesinput
andbutton
.The value of
row
changes on each iteration and your click function merely regards the last value it had. You can either scope it usinglet
,bind
it or just pass the elements to your remove function, which also skips you the the lookups.The other answers explained the issue.
I strongly suggest you do not keep a counter.
Here is a delegation version using a div container per row and recommended eventListeners