1

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

3
  • You're only removing one element. Are you creating the new div's with the same ID? Commented May 12, 2016 at 12:08
  • No I think its just creating the elements, possible in a span, this was originally code from a tutorial which i have adapted to suite but there still much to learn about JS lol so not overly sure is the honest answer Commented May 12, 2016 at 12:11
  • When a new row of 4 inputs is added it assigns an id ie; name_1 name_2 etc Commented May 12, 2016 at 12:32

3 Answers 3

1

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]);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1

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>

1 Comment

no problem! we can enhance this code so much more, but I don't know exactly your needs... :)
0

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>

1 Comment

Thats amazing!! worked perfectly first time! and the great thing is I actually learned something here, I didnt realise it could be acheived so simply, Many thanks that was really appreciated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.