Reputation: 25
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
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
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
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