Title: JavaScript to remove latest child element by ID has limited effect
P粉914731066
P粉914731066 2024-01-16 18:06:37
0
2
529

I'm making a dynamic list where the user can click a button to remove an input. When a new input is created, I assign an ID to the child element using a counter that is incremented by 1 each time a new input is generated. However, when I try to delete an input by ID, it seems that only the most recently created input is deletable.

I noticed that if you generate 5 new inputs and then click the delete button on input:2, the 5th input and button are deleted. So even though I set the input and button ID earlier in the process, clicking the delete button only relies on the current value of the row counter.

Can someone give me some pointers on how to point to the old ID? Or do I need to rewrite it in a completely different way? I'm very new to JS so I apologize if this is a horrible JS script!

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" />

P粉914731066
P粉914731066

reply all(2)
P粉311464935

The value of

row changes on each iteration, and your click function only considers its last value. You can scope it using let, bind it, or just pass the element to your removal function, which will also skip the lookup.

//REM: Can remove the row with this solution, just left to show you the issue.
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";
  
  //REM: Binding the elements
  //REM: Alternatively you can bind the current value of row.
  button.onclick = function(buttonElement, inputElement, currentRow){
    console.log('This is the value row would have: ', row);
    console.log('This is the value row had at time of binding: ', currentRow);
    
    //REM: Passing the elements to skip any lookup
    remove_field(buttonElement, inputElement)
  }.bind(button, button, input, row);
  
  container.appendChild(button);
}

//REM: Removes a button-input pair
function remove_field(buttonElement, inputElement){
  buttonElement?.remove();
  inputElement?.remove()
}
<input type="text" id="goal" name="goal">
<button type="button" onclick="addFields()">+</button><br>
<div class="container" id="container" />
P粉605233764

Every time a new element is added, the value of row will be updated, so do not use row directly to get the id. Direct access to button.id and input.id.

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.id, input.id);
  }
  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" />
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template