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);
Related
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.
I am using the find selector in jQuery by Id. It is behaving differently in case of a div vs tbody. This is a bigger problem - for the sake of clarity here is the reduced version of my original issue
HTML
<div id='iamdiv'>HELLO</div>
<table>
<tbody id='iamtbody'>
<tr><td>HELLO TOO</td></tr>
</tbody>
</table>
<input type='text' id='div'/>
<input type='text' id='tbody'/>
JS
$(document).ready(function() {
var allcontent = $($('body').html()); // I am deliberately doing this to input a HTML String.
var $divcontent = allcontent.find('#iamdiv');
$('#div').val($divcontent.html());
var $tbodycontent = allcontent.find('#iamtbody');
$('#tbody').val($tbodycontent.html());
});
Fiddle: https://jsfiddle.net/bragboy/Lt8nua10/1/
I want to display the raw html in the input text boxes, however only the tbody one is getting displayed and not the div. If I use a filter method instead of find - it works for div but not the tbody.
My objective is to have one consistent way of fetching for both tbody and div.
Two issues:
find looks for descendant elements, but #iamdiv is a top-level entry in your allcontents jQuery object.
You're duplicating the elements in the
var allcontent = $($('body').html());
line, which I'm fairly sure isn't what you want to do. (You've said that's on purpose, to simulate parsing HTML from elsewhere.)
You've said your goal is to use find in both use case (rather than using filter in one and find in the other). To do that, you need to have something else as the root of your allcontent.
You've also said that for some reason you can't change the
var allcontent = $($('body').html());
line, even just to
var allcontent = $("<body>").append($('body').html());
That's okay, you can still add a new root element by adding a line after it, like this:
allcontent = $("<body>").append(allcontent);
Live example:
$(document).ready(function() {
var allcontent = $($("body").html()); // You've said we can't change this
// The added line:
allcontent = $("<body>").append(allcontent);
var $divcontent = allcontent.find('#iamdiv');
$('#div').val($divcontent.html());
var $tbodycontent = allcontent.find('#iamtbody');
$('#tbody').val($tbodycontent.html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='iamdiv'>HELLO</div>
<table>
<tbody id='iamtbody'>
<tr><td>HELLO TOO</td></tr>
</tbody>
</table>
<input type='text' id='div'/>
<input type='text' id='tbody'/>
Use var allcontent = $('body'); instead of var allcontent = $($('body').html());
$(document).ready(function() {
var allcontent = $('body');
var $divcontent = allcontent.find('#iamdiv');
$('#div').val($divcontent.html());
var $tbodycontent = allcontent.find('#iamtbody');
$('#tbody').val($tbodycontent.html());
});
input {
width: 100%; /* just to show the whole content */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='iamdiv' class='somthing1'>
HELLO
</div>
<table>
<tbody id='iamtbody' class='somthing2'>
<tr>
<td>HELLO TOO</td>
</tr>
</tbody>
</table>
<input type='text' id='div' />
<br/>
<input type='text' id='tbody' />
After update in question :
You can use .closest() to achieve this. Because the cose that you picked when using $($(body).html()) has the div as on its node.
$(document).ready(function() {
var allcontent = $($('body').html());
var $divcontent = allcontent.closest('#iamdiv');
$('#div').val($divcontent.html());
var $tbodycontent = allcontent.find('#iamtbody');
$('#tbody').val($tbodycontent.html());
});
input {
width: 100%; /* just to show the whole content */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='iamdiv' class='somthing1'>
HELLO
</div>
<table>
<tbody id='iamtbody' class='somthing2'>
<tr>
<td>HELLO TOO</td>
</tr>
</tbody>
</table>
<input type='text' id='div' />
<br/>
<input type='text' id='tbody' />
I would like to make a javascript code that can unhide (reveal) some unhidden objects of a website.
Let me explain you more deeply.
There is one box with some items inside.
Lets say all the items that are being load to this box are 2000 but the website hide the 800.
Could i do something to reveal them?
The code that the website use (as i can see in the "inspect element" of chrome) is the following
<div class="_3hqu" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532">
<table class="_2x_v uiGrid _51mz" cols="3" cellspacing="0" cellpadding="0" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0">
<tbody data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0">
<tr class="_51mx" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2">
<td class="_51m- vMid" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$image">
<div class="_4b2j" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$image.0">
<img class="_2x_w img" src=" IMAGE LINK" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$image.0.0">
</div>
</td>
<td class="_2x_x _51m- vMid" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$text">
<div class="_2x_y" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$text.0">NAME</div>
<div class="_2x_z" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$text.1"></div>
<div class="_2x_z" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$text.2"></div>
</td>
<td class="_51mw _51m- vMid" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$widget">
<a aria-checked="true" aria-labelledby="100000533954532-name" aria-describedby="100000533954532-subtitle" class="_3hqy _3hqz" href="#" role="checkbox" tabindex="0" data-reactid=".ih.0.0.1.1.0.1.0.0.0.0.0.1:$100000533954532.0.0.$2.$widget.0">
</a>
</td>
</tr>
</tbody>
</table>
</div>
So this is the code for only one element.
the $100000533954532 is the value of this element (without the $ )
and after 1200 of this elements with same code but different values
there is this code that "hides" the other 800 elements.
<input type="hidden" name="at_limit" value="false" data-reactid=".ih.1">
<input type="hidden" name="session_id" value="1326941442" data-reactid=".ih.2">
<input type="hidden" name="profileChooserItems" value="{ "000001":1, "000002":1, etc...
data-reactid=".ih.3">
Is it possible with javascript code to reveal the hidden values (elements) of this table???
what you need is remove property from collection of DOM elements
try this:
document.querySelector('input[type="hidden"]').removeAttribute("type");
Example on JsFiddle
Similar question on StackOverflow
Here's a simple example of grabbing an input element and using the attributes and values contained therein to dynamically create a more complex set of HTML nodes:
JSFiddle it here.
<input type="hidden" name="at_limit" value="false" data-reactid=".ih.1">
<script>
var at_limit = document.querySelector('input[name="at_limit"]');
var reactid = at_limit.getAttribute('data-reactid');
var toggle = (at_limit.value === "true");
var div = document.createElement("DIV");
var tbl = document.createElement("TABLE");
var tbdy = document.createElement("TBODY");
var tr = document.createElement("TR");
var td = document.createElement("TD");
var anc = document.createElement("A");
anc.href = "page.html?reactid=" + reactid;
anc.className = ( toggle )? 'yes': 'no';
var txt = document.createTextNode(reactid);
anc.appendChild(txt);
td.appendChild(anc);
tr.appendChild(td);
tbdy.appendChild(tr);
tbl.appendChild(tbdy);
div.appendChild(tbl);
document.body.appendChild(div);
</script>
<style>
.no { color: red; }
.yes { color: green; }
table { border: solid blue 1px; }
</style>
That's the concept, now it's a matter of mapping the input elements to the targeted div/table structure.
I need to dynamically create tables one beside the other. So I have created a table(outer) and am trying to generate columns dynamically on button click. In each of these columns I will create the actual tables(inner) I need, so that in the end they appear side by side.
But I'm stuck at creating columns for the bigger table. Take a look at the code and it will be clear.
Any solution in JS is appreciated. Thanks in advance
<html>
<head>
<script type="text/javascript">
function add() {
var table = document.getElementById('foo');
var rowCount = table.rows.length;
var row =document.getElementById('rowl');
var max=table.rows[0].cells.length;
var cnum;
if(max==0){
cnum=0;
}else{
cnum=max+1;
}
var cell1 = row.insertCell(cnum);
cell1.innerHTML = "<table id='tabl'"+
cnum+
"' border=2 bordercolor='RED'><tr><th>Material "+
(cnum+1)+
"</th></tr><tr><td>bdfgher</td></tr><tr><td>fdgerh</td></tr></table>";
}
</script>
</head>
<body>
<button type="button" onclick="add()">Add cell</button>
<table id="foo" border=1 bordercolor="BLUE">
<tr id="rowl"></tr>
</table>
</body>
</html>
var cell = document.createElement("td");
document.getElementById("rowl").appendChild(cell);
Of course, you should add your other elements (inner table) in the cell element.
It may help you a little :)
<html>
<head>
<script>
var c=-1;
function displayResult()
{
var firstRow=document.getElementById("tr_1");
//var x=firstRow.insertCell(-1);
//x.innerHTML="New cell"
var cell1 = firstRow.insertCell(c++);
cell1.innerHTML = "<table id='tabl'"+
cnum+
"' border=2 bordercolor='RED'><tr><th>Material "+
(cnum+1)+
"</th></tr><tr><td>bdfgher</td></tr><tr><td>fdgerh</td></tr></table>";
}
</script>
</head>
<body>
<table id="myTable" border="1">
<tr id='tr_1'></tr>
</table>
<br>
<button type="button" onclick="displayResult()">Insert cell</button>
</body>
</html>
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.