carl
carl

Reputation: 25

Small Javascript Issue with removing multiple elements from dynamic form

Can anyone shed any light on to what I'm doing wrong here if possible?

We have a basic form on a php page with javascript that creates 4 form fields when a button is clicked.

If the button is clicked multiple times then it will keep creating rows of 4 columns. The problem is trying to remove the row (4 elements) if someone clicks the button, I can only ever get it to delete one element where I need it to remove all 4 elements (inputs) in that row,

JAVASCRIPT

var i = 0; /* Set Global Variable i */
function increment() {
    i += 1; /* Function for automatic increment of field's "Name" attribute. */
}

//Function to Remove Form Elements Dynamically
function removeElement(parentDiv, childDiv) {
    if (childDiv == parentDiv) {
        alert("The parent div cannot be removed.");
    } else if (document.getElementById(childDiv)) {
        var child = document.getElementById(childDiv);
        var parent = document.getElementById(parentDiv);
        parent.removeChild(child);
    } else {
        alert("Child div has already been removed or does not exist.");
        return false;
    }
}

//Functions that will be called upon, when user click on the Name text field.
function nameFunction() {
    var r = document.createElement('span');
    var y = document.createElement("INPUT");
    y.setAttribute("type", "text");
    y.setAttribute("placeholder", "Name");
    var g = document.createElement("IMG");
    g.setAttribute("src", "img/delete.png");
    increment();
    y.setAttribute("Name", "quantityordered_" + i);
    r.appendChild(y);
    g.setAttribute("onclick", "removeElement('myForm','id_" + i + "')");
    r.appendChild(g);
    r.setAttribute("id", "id_" + i);
    document.getElementById("myForm").appendChild(r);


    var r = document.createElement('span');
    var y = document.createElement("INPUT");
    y.setAttribute("type", "text");
    y.setAttribute("placeholder", "QTY Delivered");
    var g = document.createElement("IMG");
    g.setAttribute("src", "img/delete.png");
    increment();
    y.setAttribute("Name", "quantitydelivered_" + i);
    r.appendChild(y);
    g.setAttribute("onclick", "removeElement('myForm','id_" + i + "')");
    r.appendChild(g);
    r.setAttribute("id", "id_" + i);
    document.getElementById("myForm").appendChild(r);

    var r = document.createElement('span');
    var y = document.createElement("INPUT");
    y.setAttribute("type", "text");
    y.setAttribute("placeholder", "Description");
    var g = document.createElement("IMG");
    g.setAttribute("src", "img/delete.png");
    increment();
    y.setAttribute("Name", "description_" + i);
    r.appendChild(y);
    g.setAttribute("onclick", "removeElement('myForm','id_" + i + "')");
    r.appendChild(g);
    r.setAttribute("id", "id_" + i);
    document.getElementById("myForm").appendChild(r);

    var r = document.createElement('span');
    var y = document.createElement("INPUT");
    y.setAttribute("type", "text");
    y.setAttribute("placeholder", "Price ie; £15.00");
    var g = document.createElement("IMG");
    g.setAttribute("src", "img/delete.png");
    increment();
    y.setAttribute("Name", "price_" + i);
    r.appendChild(y);
    g.setAttribute("onclick", "removeElement('myForm','id_" + i + "')");
    r.appendChild(g);
    r.setAttribute("id", "id_" + i);
    document.getElementById("myForm").appendChild(r);
}

//Functions that will be called upon, when user click on the Reset Button.
function resetElements() {
    document.getElementById('myForm').innerHTML = '';
}

HTML

<div class="col-md-12" style="margin-top:20px; padding-left:30px;">
    <button type="button" onclick="nameFunction()" class="btn btn-info">
      <i class="fa fa-plus"></i> 
      Add another Item
    </button>
</div>

I hope this helps? Please note Iam new to JS and thought this would be a great project to dive into etc.

Many thanks in advance for any advice anyone can give

Upvotes: 1

Views: 68

Answers (3)

Patrick Ferreira
Patrick Ferreira

Reputation: 2053

My response is similare to @user3153664 one, but i simplifiend the "create element" phase into one function and tryed to clean the code...

var i = 0; /* Set Global Variable i */
function increment() {
  i += 1; /* Function for automatic increment of field's "Name" attribute. */
}

//Function to Remove Form Elements Dynamically
function removeElement(parentDiv, childDiv) {
  if (childDiv == parentDiv) {
    alert("The parent div cannot be removed.");
  } else if (document.getElementById(childDiv)) {
    var child = document.getElementById(childDiv);
    var parent = document.getElementById(parentDiv);
    parent.removeChild(child);
  } else {
    alert("Child div has already been removed or does not exist.");
    return false;
  }
}

function createInputElement(row, placeholder, name) {
  var y = document.createElement("INPUT");
  y.setAttribute("type", "text");
  y.setAttribute("placeholder", placeholder);
  
  var g = document.createElement("IMG");
  g.setAttribute("src", "img/delete.png");
  g.setAttribute("alt", "X");
  y.setAttribute("Name", name);
  
  var r = document.createElement('span');
  r.appendChild(y);
  g.onclick = function() { removeElement('myForm', row.getAttribute('id')) };
  r.appendChild(g);
  
  return r;
}

//Functions that will be called upon, when user click on the Name text field.
function nameFunction() {
  var row = document.createElement('P'); // a set of 4 elements to be delete together 
 
  increment();
  row.setAttribute("id", "id_" + i); // set the row id with the value of i
  row.appendChild(createInputElement(row, 'Name', 'quantityordered_'+i ));
  
  increment();
  row.appendChild(createInputElement(row, 'QTY Delivered', 'quantitydelivered_'+i ));
  
  increment();
  row.appendChild(createInputElement(row, 'Description', 'description_'+i ));
  
  increment();
  row.appendChild(createInputElement(row, 'Price ie; £15.00', 'price_'+i ));
    
  document.getElementById("myForm").appendChild(row);
}

//Functions that will be called upon, when user click on the Reset Button.
function resetElements() {
  document.getElementById('myForm').innerHTML = '';
}
<form id="myForm">

  <div class="col-md-12" style="margin-top:20px; padding-left:30px;">
    <button type="button" onclick="nameFunction()" class="btn btn-info">
      <i class="fa fa-plus"></i> Add another Item
    </button>
  </div>
</form>

Upvotes: 1

stas.yaranov
stas.yaranov

Reputation: 1797

I think the best way is to place all the four created elements into surrounding div, give it an id and the remove it by id.

But if you want to preserve the current structure you can remove them by a class name.

1) Create a function for generating class name from i (assuming that nameFunction creates 4 elements):

   function getClassName(i) {
        return "name_spans_" + ~~((i - 1)/4);
    }

2) Add a class to each generated span after each call to increment():

increment(); // after this line
r.className += getClassName(i);

3) Modify onclick handler to pass i of the last generated span:

g.setAttribute("onclick", "removeElement('myForm'," + i + ")");

4) Modify removeElement function to remove all elements with a class name corresponding to passed i:

function removeElement(parentDiv, i) {
    var parent = document.getElementById(parentDiv);
    var children = [].slice.call(document.getElementsByClassName(getClassName(i)));

    for (var c = 0; c < children.length; ++c) {
        parent.removeChild(children[c]);
    }
}

Upvotes: 1

Mykola Prymak
Mykola Prymak

Reputation: 447

Insert all 4 inputs into one "container" - and you can remove all of it by removing a container.

var i = 0; /* Set Global Variable i */
function increment() {
    i += 1; /* Function for automatic increment of field's "Name" attribute. */
}

//Function to Remove Form Elements Dynamically
function removeElement(childId) {
    // Simplify form - only need a childId
    if (document.getElementById(childId)) {
        var child = document.getElementById(childId);
        child.parentNode.removeChild(child);
    }
}

//Functions that will be called upon, when user click on the Name text field.
function nameFunction() {

    // Create a container for all 4 inputs
    var container = document.createElement('div');
    var containerId = 'id_' + i;
    container.id = containerId;
    increment();

    var r = document.createElement('span');
    var y = document.createElement("INPUT");
    y.setAttribute("type", "text");
    y.setAttribute("placeholder", "Name");
    var g = document.createElement("IMG");
    g.setAttribute("src", "img/delete.png");
    g.setAttribute("onclick", "removeElement('" + containerId + "')");
    y.setAttribute("Name", "quantityordered_" + i);
    r.appendChild(y);
    r.appendChild(g);
    container.appendChild(r);
    increment();


    var r = document.createElement('span');
    var y = document.createElement("INPUT");
    y.setAttribute("type", "text");
    y.setAttribute("placeholder", "QTY Delivered");
    var g = document.createElement("IMG");
    g.setAttribute("src", "img/delete.png");
    g.setAttribute("onclick", "removeElement('" + containerId + "')");
    y.setAttribute("Name", "quantitydelivered_" + i);
    r.appendChild(y);
    r.appendChild(g);
    container.appendChild(r);
    increment();

    var r = document.createElement('span');
    var y = document.createElement("INPUT");
    y.setAttribute("type", "text");
    y.setAttribute("placeholder", "Description");
    var g = document.createElement("IMG");
    g.setAttribute("src", "img/delete.png");
    g.setAttribute("onclick", "removeElement('" + containerId + "')");
    y.setAttribute("Name", "description_" + i);
    r.appendChild(y);
    r.appendChild(g);
    container.appendChild(r);
    increment();

    var r = document.createElement('span');
    var y = document.createElement("INPUT");
    y.setAttribute("type", "text");
    y.setAttribute("placeholder", "Price ie; £15.00");
    var g = document.createElement("IMG");
    g.setAttribute("src", "img/delete.png");
    g.setAttribute("onclick", "removeElement('" + containerId + "')");
    y.setAttribute("Name", "price_" + i);
    r.appendChild(y);
    r.appendChild(g);
    container.appendChild(r);
    increment();

    // Append container to form
    document.getElementById("myForm").appendChild(container);
}

//Functions that will be called upon, when user click on the Reset Button.
function resetElements() {
    document.getElementById('myForm').innerHTML = '';
}
<div id="myForm" class="col-md-12" style="margin-top:20px; padding-left:30px;">
    <button type="button" onclick="nameFunction()" class="btn btn-info">
      <i class="fa fa-plus"></i> 
      Add another Item
    </button>
</div>

Upvotes: 0

Related Questions