Dynamically Adding Table Row - javascript

I wonder whether someone could help me please,
From a tutorial I found online which I've been able to adapt, I've put together the code below, which allows the user to dynamically add additional rows into a table following the insertion of data in the row above.
The problem I'm having is that I can only insert one more row, giving a total of two and I just can't find out why. I've been back to the original here to see check that my coding is the same and except for the changes in the field name, table name and the exclusion of the 'Add' button I can't see any differences to cause this problem.
I just wondered whether someone could perhaps take a look at my code please and let me know where I'm going wrong.
Javascript
<script type="text/javascript" language="javascript">
function addRow()
{
//add a row to the rows collection and get a reference to the newly added row
var newRow = document.all("addimage").insertRow();
var oCell = newRow.insertCell();
oCell.innerHTML = "<input type='radio' name='select'>";
oCell = newRow.insertCell();
oCell.innerHTML = "<input type='text' name='title'>";
oCell = newRow.insertCell();
oCell.innerHTML = "<input type='file' name='image'>";
}
//deletes the specified row from the table
function removeRow(src)
{
/* src refers to the input button that was clicked.
to get a reference to the containing <tr> element,
get the parent of the parent (in this case <tr>)
*/
var oRow = src.parentElement.parentElement;
//once the row reference is obtained, delete it passing in its rowIndex
document.all("addimage").deleteRow(oRow.rowIndex);
}
</script>
Table Layout
<table id="addimage" style="table-layout:auto">
<tr>
<td width="20"><input name="select" type="radio" id="select"/></td>
<td width="144"><input name="title" type="text" id="title"/></td>
<td width="304"><input name="image" type="file" id="image" onchange="addRow();"/></td>
</tr>
</table>

The new row that you are adding do not have the onchange property set, it should be:
oCell.innerHTML = "<input type='text' name='image' onchange='addRow();'>";
Also, document.all("addimage") is (as far as i know) bad practice because it is not supported by all browsers. For compatibility you should also add index to insert the row in (-1 for last) and the index for the new cells. The parameter is required in Firefox and Opera, but optional in Internet Explorer, Chrome and Safari. I suggest that you change your code to something like the following:
function addRow()
{
//add a row to the rows collection and get a reference to the newly added row
var newRow = document.getElementById("addimage").insertRow(-1);
var oCell = newRow.insertCell(0);
oCell.innerHTML = "<input type='radio' name='select'>";
oCell = newRow.insertCell(1);
oCell.innerHTML = "<input type='text' name='title'>";
oCell = newRow.insertCell(2);
oCell.innerHTML = "<input type='text' name='image' onchange='addRow();'>";
}

Seen the actual code. In that there is a button, when clicked, adds row to the table. In your case you are using onchange event. Instead of that use onclick event, as I mentioned in the comment.
Secondly, if you add onclick on every image, you will end up adding extra row on any image click. I hope it's okay for you.
Suggestion
Instead of using onclick on image use anchor tag which contains your image or use single button as shown in the demo. It will look something like this
<table id="addimage" style="table-layout:auto">
<tr>
<td width="20"><input name="select" type="radio" id="select"/></td>
<td width="144"><input name="title" type="text" id="title"/></td>
<td width="304">
<a href='#' onclick='addRow();'>
<input name="image" type="file" id="image"/>
</a>
</td>
</tr>
</table>
JavaScript
function addRow()
{
//add a row to the rows collection and get a reference to the newly added row
var newRow = document.all("addimage").insertRow();
var oCell = newRow.insertCell();
oCell.innerHTML = "<input type='radio' name='select'>";
oCell = newRow.insertCell();
oCell.innerHTML = "<input type='text' name='title'>";
oCell = newRow.insertCell();
oCell.innerHTML = "<a href='#' onclick='addRow();><input type='file' name='image'>'</a>";
}
If you want to disable the anchor tag after row is added you can disable it using javascript.
Hope this works.

Related

JavaScript won't include tr- and td-tags in string

i am trying to insert a <tr> and a <td> into a table using javascript.
I have a fairly simple javascript-code that prints a string every time I click a button. It's being printed into a <table>, but javascript ignores the <tr> and <td>tags.
How do I make Javascript include <tr> and <td> tags?
I gave already tried escaping the string in various ways.
code used:
<script>
function MoreCameras() {
document.getElementById("AddCamera").innerHTML += "<tr><td><input type='text' name='SSIDSetup[]' class='form-control' placeholder='Camera SSID'></td><td><input type='text' name='NameSetup[]' class='form-control' placeholder='Camera Name'></td><td><input type='password' name='PasswordSetup[]' class='form-control' placeholder='Camera Password'></td><td><input type='checkbox' name='EnabledSetup[]'/></td></tr>";
}
</script>
<button onclick="MoreCameras()">Try it</button>
<table>
<div id="AddCamera">
</div>
</table>
screenshot for clarification
It's generally not a good idea to use inline event handlers.
You can't add table rows to a div. Here's a snippet using event delegation and adding the innerHTML to the table. It may be more approriate to create a row using DOM-scripting, cf MDN. Added a function for that to the snippet.
It is not uncommon to see innerHTML used to insert text into a web
page. There is potential for this to become an attack vector on a
site, creating a potential security risk.
document.addEventListener("click", MoreCameras);
function MoreCameras(evt) {
if (evt.target.id === "ih") {
document.querySelector("#AddCamera").innerHTML += getRowHtml();
}
if (evt.target.id === "ds") {
document.querySelector("#AddCamera").appendChild(createRow());
}
}
function createRow() {
const row = document.createElement("tr");
const cells = [...Array(4)].map(td => document.createElement("td"));
const inputs = [...Array(4)].map(input => document.createElement("input"));
inputs[0].type = "text";
inputs[0].name = "SSIDSetup[]";
inputs[0].classList.add("form-control");
inputs[0].setAttribute("placeholder", "Camera SSID");
inputs[1].type = "text";
inputs[1].name = "NameSetup[]";
inputs[1].classList.add("form-control");
inputs[1].setAttribute("placeholder", "Camera Name");
inputs[2].type = "password";
inputs[2].name = "PasswordSetup[]";
inputs[2].classList.add("form-control");
inputs[2].setAttribute("placeholder", "Camera Password");
inputs[3].type = "checkbox";
inputs[3].name = "EnabledSetup[]";
cells.forEach((cell, i) => {
cell.appendChild(inputs[i]);
row.appendChild(cell);
});
return row;
}
function getRowHtml() {
return `
<tr>
<td>
<input
type="text"
name="SSIDSetup[]"
class="form-control"
placeholder="Camera SSID">
</td>
<td>
<input
type="text"
name="NameSetup[]
class="form-control"
placeholder="Camera Name">
</td>
<td>
<input
type="password"
name="PasswordSetup[]"
class="form-control"
placeholder="Camera Password">
</td>
<td>
<input
type="checkbox"
name="EnabledSetup[]">
</td>
</tr>`;
}
<button id="ih">Try it (innerHTML)</button>
<button id="ds">Try it (DOM scripting)</button>
<table>
<tbody id="AddCamera"></tbody>
</tabe>
You are inserting cell based elements into a div, this is not valid html.
add a tbody thead and add the id you insert into to the tbody
Just remove div and put id="AddCamera" on table. You where inserting td tr in wrong way.
EDIT:
actually add tbody with that id, that will give you right HTML syntax
<tbody id="AddCamera">
<script>
function MoreCameras() {
document.getElementById("AddCamera").innerHTML += "<tr><td><input type='text' name='SSIDSetup[]' class='form-control' placeholder='Camera SSID'></td><td><input type='text' name='NameSetup[]' class='form-control' placeholder='Camera Name'></td><td><input type='password' name='PasswordSetup[]' class='form-control' placeholder='Camera Password'></td><td><input type='checkbox' name='EnabledSetup[]'/></td></tr>";
}
</script>
<button onclick="MoreCameras()">Try it</button>
<table>
<tbody id="AddCamera">
</tbody>
</table>

Using JavaScript to create a new row into a table, innerHTML to set a input variable but the user entered value won't post when submitted

I have a table created that looks like this:
<form role="form" method="post" action="" enctype="multipart/form-data">
<table class="table table-striped" id='billables'>
<input type='hidden' name='products' id='products' value='0'>
<thead>
<tr>
<th>Description</th>
<th>Quantity (#)</th>
<th>Rate ($)</th>
<th>Amount ($)</th>
</tr>
</thead>
<tbody >
//The ROW gets inserted properly here, and each row gets
assigned a "input variable" properly
</tbody>
</table>
</form>
and I am using a javascript function that when a button is clicked will add a new row to the table with input fields.
function addRow() {
var products = document.getElementById("products").value;
products = parseFloat(products)
products = products + 1;
document.getElementById("products").value = products;
var table = document.getElementById("billables");
var row = table.insertRow(products);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
var cell4 = row.insertCell(3);
cell1.innerHTML = '<input class="form-control" id="'+products+'desc" type="text" name="'+products+'desc" required placeholder="Item Desc..." >';
cell2.innerHTML = "<input class='form-control' id='"+products+"quant' type='number' name='"+products+"quant' required placeholder='Quantity...' >";
cell3.innerHTML = "<input class='form-control' id='"+products+"rate' type='number' name='"+products+"rate' required step='0.01' placeholder='Ex: 23.99' onkeyup='calc()'>";
cell4.innerHTML = "<input class='form-control' id='"+products+"amm' type='number' name='"+products+"amm' readonly >";
}
The "name" and "id" field get dynamically named based on how many rows exist in the table.
IE: 1desc for one row. 1desc,2desc for two rows etc...
The table populates properly, creates the new row, adds a input field for each cell and according to the google debugger/inspect the input fields are named properly.
My issue is that when the form is submitted that values of those elements generated using the innerHTML function do not post properly. Though all the other variables within the form are posted properly.
Any ideas?
edited for clarification - the missing ' was lost when making the post. and the form tag was place much earlier in the code added it to show what it looks like.
Edit:
Pic displaying what the table looks like before the new row is added
Displaying what the table looks like after the new row is added
Google dev tools indicating what the input variable looks like once generated (all correct)
According to google dev tools, other variables are getting posted but not the ones generated by the innerHTML function
First there is no form tag.
The following line has error.
<input type='hidden' name='products id='products' value='0'>
Change it to-
<input type='hidden' name='products' id='products' value='0'>
Due to the above
var products = document.getElementById("products").value;
this line of code is not setting its value, and you are not able to post it.

Dynamically adding a row in the table onblur the last row in the table using javascript

I created a table, on referring "http://stackoverflow.com/questions/9045940/dynamically-adding-table-row" , whenever i came into the last row in the table i need to add another row into the table at the bottom dynamically, here is the code i tried:
<table id="myTable" style="table-layout:auto">
<tr>
<td><input type="text" onblur="addRow('myTable')" /></td>
<td><input type="text"/></td>
<td><input type="text"/></td>
</tr>
</table>
and the javascript is as follows:
<script>
function addRow()
{
//add a row to the rows collection and get a reference to the newly added row
var newRow = document.all("myTable").insertRow();
var oCell = newRow.insertCell();
oCell.innerHTML = "<input type='text' onblur='addRow();'>";
oCell = newRow.insertCell();
oCell.innerHTML = "<input type='text' name='title'>";
oCell = newRow.insertCell();
oCell.innerHTML = "<input type='text' name='title'>";
}
</script>
But, here a new row is added at the top of the table, what should i do?
change var newRow = document.all("myTable").insertRow();
to
var newRow = document.all("myTable").insertRow(-1);
Also, in your onblur event, why do you pass an argument to the addRow function when it doesn't take any?

Dynamic Form IE8 Error

I’m trying to create a dynamic form that adds elements in a certain table when a button is clicked. I do this by calling a javascript function that will, in this example, create a new text box that has a name and type of “item_3” with its remove link beside it. The webpage runs just fine in firefox and chrome possibly due to the fact that they doesn’t strictly use W3C like internet explorer. It will not run in IE8 and will give the error “Unknown Runtime Error”. I’m sure that problem has to do with DOM and how I am using my elements but I need a way to add an element dynamically in a specific table. Here is the head:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<script language="Javascript" type="text/javascript">
//Add more fields dynamically.
function addField(area,type)
{
if(!document.getElementById) return; //Prevent older browsers from getting any further.
var field_area = document.getElementById(area); //Select table to insert element
//Example, i want a textbox with id and name as item_3
var type = "item_";
var count = "3";
//Add html to insertiontable table
field_area.innerHTML += "<tr><td colspan='2'><input type='text' name='"+(type+count)+"' id='"+(type+count)+"'/><a style='cursor:pointer;color:blue;' onclick='this.parentNode.parentNode.removeChild(this.parentNode);'> Remove Box</a></td</tr>";
}
</script>
</head>
The body section contains my form. There are two tables, table1 and insertiontable. Table one contains a textbox along with a button to inserting a the new "item_3" element into insertiontable.
<body>
<form name="newbookform1" method="post" action ="">
<!--Table one-->
<table id="table1" align="left" border="0" cellspacing="0" cellpadding="3">
<tr><td><strong>What:</strong></td><td><input type="text" name="item_1" id="item_1" /></td><td><input type="button" value="Add New Item Type" onclick="addField('insertiontable','item_');" /></td></tr>
</table>
<!--Table two-->
<table id="insertiontable" align="left" border="0" cellspacing="0" cellpadding="3">
<tr><td colspan="2"><input type="text" name="item_2" id="item_2" /><a style="cursor:pointer;color:blue;" onclick="this.parentNode.parentNode.removeChild(this.parentNode);"> Remove Box</a></td></tr>
</table>
</form>
</body>
</html>
Cleaning this up is a headache for me, how can this work in IE8 with valid HTML? Your help is greatly appreciated.
Here's a similar question: Internet Explorer Javascript/ Dom Object add rows problem
I agree with either using jQuery to do dom manipulation or use the dom methods provided by javascript.
This should work:
replace:
//Add html to insertiontable table
field_area.innerHTML += "<tr><td colspan='2'><input type='text' name='"+(type+count)+"' id='"+(type+count)+"'/><a style='cursor:pointer;color:blue;' onclick='this.parentNode.parentNode.removeChild(this.parentNode);'> Remove Box</a></td</tr>";
with:
var row = document.createElement("tr");
var cell = document.createElement("td");
cell.innerHTML = "<input type='text' name='"+(type+count)+"' id='"+(type+count)+"'/><a style='cursor:pointer;color:blue;' onclick='this.parentNode.parentNode.removeChild(this.parentNode);'> Remove Box</a>";
row.appendChild(cell);
field_area.appendChild(row);
Simply put - innerHTML for tables is messed up. You'd have to put your HTML string into a cell and then append the cell to a row and the row to the table.
IE is real funny about modifying tables with javascript. You have to use document.createElement. This should work for you.
//Add html to insertiontable table
var tbody = document.createElement('tbody');
var tr = document.createElement('tr');
var td = document.createElement('td');
td.setAttribute('colspan', '2');
var inp = document.createElement('input');
inp.setAttribute('type', 'text');
inp.setAttribute('name', 'item_' + count);
inp.setAttribute('id', 'item_' + count);
var a = document.createElement('a');
a.setAttribute('style', 'cursor:pointer;color:blue;');
a.setAttribute('onclick', 'this.parentNode.parentNode.removeChild(this.parentNode);');
a.innerText = " Remove Box";
td.appendChild(inp);
td.appendChild(a);
tr.appendChild(td);
tbody.appendChild(tr);
field_area.appendChild(tbody);

Appending a cloned row of a table to a specified position on table

function CreateInterface(){
document.getElementById("welcome").innerHTML=
'<form action="?" method="get" onsubmit=" return validate(this)">' +
'<table id="dataTable" summary="" cellspacing="3" cellpadding="0" border="0">' +
'<tr id="tablerow">' + '<td><INPUT type="checkbox" name="chk"/></td> '+
'<th>Userid : </th>' + '<td ><input name="userid" type="text" class="text" value="" maxlength="10" /></td>' +
'</tr>' + '<tr><td colspan="2" align="center">'+
'<INPUT type="button" value="Add" onclick="addRow()" />' +
'<INPUT type="button" value="Delete" onclick="delRow()" />' +
'<input type="submit" value="submit" />'+'</td></tr>' +
'</table>' +
'</form>';
}
function addRow(){
var clnNode=document.getElementById("tablerow").cloneNode(true);
document.getElementById("dataTable").appendChild(clnNode);
}
This is my code , i want this cloned node to be inserted above the buttons. In fact this code is not working, i.e. node is not getting added to table. Please help me solve this
Do not use id="tablerow" as duplicate ids will cause malformed HTML.
Change <tr id="tablerow"> in your string to just <tr>
Script
function addRow() {
var referenceNodes = document.getElementById("dataTable").getElementsByTagName("tr");
//-2 because last row is button row
var referenceNode = referenceNodes[referenceNodes.length - 2];
var newNode = referenceNode.cloneNode(true);
newNode.getElementsByTagName("input")[0].checked = false;
newNode.getElementsByTagName("input")[1].value = "";
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
Demo: http://jsfiddle.net/naveen/wbFMm/
You need to use insertBefore and pass lastChild as second parameter to insert the cloned row just above buttons.
function addRow(){
var table=document.getElementById("dataTable")
var clnNode=document.getElementById("tablerow").cloneNode(true);
table.insertBefore(clnNode,table.lastChild);
}
Here is working example: http://jsfiddle.net/amantur/8KYum/10/
As for code is not working, you are not calling CreateInterface from anywhere. Set it up to run on onLoad and things will work.
Your problem is your using the same ID for several elements (tableRow). An id must be unique on an html page. As seen in here.
A better solution would be to have only one row with the ID and every time you clone the row simply remove the id from the clone.
try the below code. I've just tweaked your existing addRow function
function addRow(){
var clnNode=document.getElementById("tablerow").cloneNode(true);
tableObj = document.getElementById("dataTable");
tbodyObj = document.getElementById("dataTable").getElementsByTagName('tbody')[0]
tableObj.insertBefore(clnNode, tbodyObj)
}

Categories