document.createElement not working on IE 8 and below - javascript

I have this for that lets users upload pictures. I wanted to limit the number of pictures to 4. At first it shows only one input field, then if a user wants to add more they can click on Button-Add-icon.png and another input field appears. When they reach four inputs and they decide to remove one they click on Button-Delete-icon.png.
This whole thing works fine on Firefox, Chrome, Seamonkey and IE9. But it doesn't work on IE8, IE7 and before.
Could someone give a hint on how to get it fixed?
Thanks
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org
/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Document sans titre</title>
<script type="text/javascript">
var totalItems = 0;
function addItems()
{
if(totalItems < 3)
{
var table1 = document.getElementById('tab1');
var newrow = document.createElement("tr");
var newcol = document.createElement("td");
var input = document.createElement("input");
input.type="file";
input.name="image[]";
newcol.appendChild(input);
newrow.appendChild(newcol);
table1.appendChild(newrow);
totalItems++;
} else {
//Display your message here..
}
}
function remItems()
{
var table1 = document.getElementById('tab1');
var lastRow = table1.rows.length;
if(lastRow>=2)
{
table1.deleteRow(lastRow-1);
totalItems--;
}
}
</script>
</head>
<body>
<table align="center" border="0" id="tab1" >
<tr>
<td width="218" align="center"><input type="file" name="image[]" /></td>
<td width="54" align="center"><img src="images/Button-Add-icon.png"
style="cursor:pointer" onclick="addItems()" />
</td>
<td><img src="images/Button-Delete-icon.png" style="cursor:pointer"
onclick="remItems()" />
</td>
</tr>
</table>
<table align="center" border="0" id="tab2">
</table>
</body>
</html>

You are adding the row as a child to the wrong element.
An HTML table always has a tbody element as a child element, all tr elements go inside this. If you write a piece of HTML including a table with no tbody element it will be created automatically, but when altering the table later on you have to take the tbody element into account.
An easy fix is to write the tbody element explicitly, give it an id, and insert new rows in the tbody element instead of in the table element.
<table>
<tbody id="tb1">
<tr><td></td></tr>
</tbody>
</table>

Related

Show and hide table based on checkbox selection not working

I have a test code block through which I am trying to display a table based on a checkbox selection. The action is working and the table is being displayed. The only problem is - there are no borders. Could you please give me suggestions on what I am doing wrong here?
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<table border="1">
<tr>
<td style=min-width:50px></td>
<td style=min-width:50px>Retrofit</td>
<td style=min-width:50px><input style=min-width:50px id="retrofit" name="retrofit" type="checkbox" value="1" onchange="javascript:toggleOtherTextboxVisible()" /></td>
</tr>
</table>
<table style="display:none" name="table" id ='table' border="1"/>
<th>new</th>
<th>newer</th>
</table>
</body>
<script type="text/javascript">
function toggleOtherTextboxVisible()
{
var check = document.getElementById('retrofit');
if (check.checked) {
document.getElementById('table').style.display. = 'block';
}
else
{
document.getElementById('table').style.display = 'none';
}
}
</script>
</html>
The first error I can see is that a table doesn't have a display value of "block" but "table".
Therefore, simply change this line :
document.getElementById('table').style.display. = 'block';
To :
document.getElementById('table').style.display. = 'table';

Element in div gets removed as a child but can't be used again

I am trying to display a hidden table in a div then hide it again with display: none/block toggle. It works. But, I can't get it to appear again once I toggle to display: none to hide it.
HTML:
The HTML has an empty div with id = tableContainer.
Next to it, I have a table with the names of animal families in each cell, along with a button. When the button is clicked, it takes the name of the animal family from that particular cell, finds the table of animal species with that name and switches from display: none to display:block and display it /inside the div. Then, if I click the button again, it toggles the display back to display: none.
When I click a button in another cell, it clears the div and displays the new table.
All good.
But, if I click a button that was previously used, the table that has now gone is no longer available.
I have gone through all sorts of hoops playing with removeChild and all that but no luck. I am currently using innerHTML to clear the div, but I'm missing something with the class name.
Console error says: tabletest2.html:523 Uncaught TypeError: Cannot read property 'classList' of null
at toggle (tabletest2.html:523)
at HTMLButtonElement.onclick (tabletest2.html:72)
So, it seems to me that it can't toggle any more because the table now no longer exists, or I may be wrong with that as I didn't delete the child element (I think).
<body>
<table>
<tbody>
<tr>
<td>Genus</td>
<td>Benthobatis
<button onclick="toggle(this, parentNode.firstChild)">Click me</button></td>
</tr>
<tr>
<td>Genus</td>
<td>Diplobatis
<button onclick="toggle(this, parentNode.firstChild)">Click me</button></td>
</tr>
</tbody>
</table>
<!-- <======== div display container here ================>-->
<div id="tableContainer"></div>
<table id="Benthobatis" class="hide">
<tbody>
<tr>
<th>Genus</th>
<th>Benthobatis</th>
</tr>
<tr>
<td>Benthobatis kreffti</td>
<td>Brazilian Blind Electric Ray</td>
</tr>
</tbody>
</table>
<!-- <==================================-->
<table id="Diplobatis" class="hide">
<tbody>
<tr>
<th>Genus</th>
<th> Diplobatis </th>
</tr>
<tr>
<td>Diplobatis colombiensis</td>
<td>Colombian electric ray</td>
</tr>
</tbody>
</table>
</body>
<script>
function toggle(ele, tableName) {
var myTableDisplayDiv = document.getElementById("tableContainer").childNodes;
if (myTableDisplayDiv.length != 0) {
document.getElementById("tableContainer").innerHTML = "";
}
var myTableName = tableName.textContent;
var myTable = document.getElementById(myTableName);
myTable.classList.toggle("hide");
document.getElementById("tableContainer").appendChild(
document.getElementById(myTableName)
);
}
</script>
<style>
.hide {
display: none;
}
Explanations
"Why are my tables deleted if I'm only changing display option, not removing the child node?".
This destroys everything within:
document.getElementById("tableContainer").innerHTML = "";
This moves the chosen table to #tableContainer:
document.getElementById("tableContainer").appendChild(
document.getElementById(myTableName)
So in three clicks there's nothing left. Of course this is if the table can be identified correctly which it wasn't. The .textContent of .parentNode.firstChild reference was lost because this refers to a global context not the button. This is why on-event attributes (among other various reasons) are discouraged. Although not a critical issue as the ones previously mentioned, you should seriously have some variations to the names:
tableName
myTableName
myTable
myTableDisplayDiv
tableContainer
I'm pretty sure this naming scheme did not facilitate debugging.
Solutions
Before you place a table into #tableContainer where it gets destroyed, make a copy with .cloneNode().
Remove the onclick attributes and either use onclick property (like in the demo) or .addEventListener().
Register an ancestor element of both buttons (i.e. tbody), from there both buttons can be clicked and easily isolated and referenced by using event.target.
Now the reference to the clicked button (event.target) can now be referenced:
var tableName = event.target.parentNode.firstChild.textContent
And then the table can finally be referenced:
var table = document.getElementById(tableName)
Demo
document.querySelector('tbody').onclick = toggle;
function toggle(event) {
var clicked = event.target;
if (clicked.tagName === 'BUTTON') {
var genus = clicked.parentNode.firstChild.textContent;
var table = document.querySelector('#' + genus);
var display = document.getElementById("display");
display.innerHTML = "";
var clone = table.cloneNode(true);
display.appendChild(clone);
clone.classList.toggle('hide');
}
}
.hide {
display: none;
}
<table>
<tbody>
<tr>
<td>Genus</td>
<td>Benthobatis
<button>Click me</button></td>
</tr>
<tr>
<td>Genus</td>
<td>Diplobatis
<button>Click me</button></td>
</tr>
</tbody>
</table>
<!-- <======== div display container here ================>-->
<div id="display"></div>
<table id="Benthobatis" class="hide">
<tbody>
<tr>
<th>Genus</th>
<th>Benthobatis</th>
</tr>
<tr>
<td>Benthobatis kreffti</td>
<td>Brazilian Blind Electric Ray</td>
</tr>
</tbody>
</table>
<!-- <==================================-->
<table id="Diplobatis" class="hide">
<tbody>
<tr>
<th>Genus</th>
<th> Diplobatis </th>
</tr>
<tr>
<td>Diplobatis colombiensis</td>
<td>Colombian electric ray</td>
</tr>
</tbody>
</table>
Your code is kind of complex to understand but if you just want to toggle the table, I think this is the best way.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.hide {
display: none;
}
</style>
</head>
<body>
<div class="table-container">
<button class="toggle-btn">Click me</button>
<table>
<tr>
<td>Genus</td>
<td>Benthobatis</td>
</tr>
<tr>
<td>Genus</td>
<td>Diplobatis</td>
</tr>
</table>
</div>
<script>
const table = document.querySelector('table'),
btn = document.querySelector('.toggle-btn');
btn.addEventListener("click", () => {
table.classList.toggle("hide")
})
</script>
</body>
</html>

delete a row in html table using a hidden type and javascript

I have a table with HTML constructed using my servlet class.
When trying to delete a row in this table using a javascript function I must first of all put different id to separate elements.and i resolove it with hidden type like that:
retour.append("<td>");
retour.append("<input type=\"hidden\" id=\"id_"+nomTab+"_"+compteur+"\" value=\""+object.getIdDailyTimeSheet()+"\"/>");
retour.append("<button id=\"del\" name=\"del\" type=\"button\" onClick=DeleteARow('+id_"+nomTab+"_"+compteur+"')>");
retour.append("<img src=icon_delete.gif />");
retour.append("</button>");
retour.append("</td>");
As you can see each element has a delete button. What i want to know how can i delete one row.
thinks.
function deleteRow(r)
{
var i = r.parentNode.parentNode.rowIndex;
document.getElementById('myTable').deleteRow(i);
}
You should check out this dom page:
http://www.w3schools.com/js/js_ex_dom.asp
hope this helps.
I don't understand why you're using the <input type="hidden" />. Instead you should use some DOM scripting. (or jQuery)
Here's an example using DOM scripting:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Delete a Row Example</title>
<script type="text/javascript">
//<![CDATA[
window.onload = function() {
var table = document.getElementById("the-table");
var buttons = table.getElementsByTagName("input"); // all the <input /> elements which were in the table
for(var i=0; i<buttons.length; i++) { // loop all over the <input /> elements in the table
if(buttons[i].name=="delete-this-row") { // if they are marked as "delete this row" inputs...
buttons[i].onclick = function() { // give them onclick even handlers
var buttonCell = this.parentNode; // now buttonCell is the <td> which contains the <input />
var deleteThisRow = buttonCell.parentNode; // now deleteThisRow is the row we want to delete
deleteThisRow.parentNode.removeChild(deleteThisRow);
}
}
}
}
//]]>
</script>
</head>
<body>
<table id="the-table">
<tbody>
<tr>
<td>0,0</td>
<td>1,0</td>
<td>2,0</td>
<td><input type="button" name="delete-this-row" value="Delete This Row" /></td>
</tr>
<tr>
<td>0,1</td>
<td>1,1</td>
<td>2,1</td>
<td><input type="button" name="delete-this-row" value="Delete This Row" /></td>
</tr>
<tr>
<td>0,2</td>
<td>1,2</td>
<td>2,2</td>
<td><input type="button" name="delete-this-row" value="Delete This Row" /></td>
</tr>
</tbody>
</table>
</body>
</html>
The idea I'm using here is not to use an identifier on the row; instead use the position of the button to determine which row to delete. You delete the row its in.
Since I define the onclick event handler in my javascript (not in an onclick attribute) the function I used can access the clicked element, using the this keyword. From there, I can start climbing up this.parendNodes all the way to my <tr> element.
You should be able to do the same thing I've done with <input type="button" /> elements with a <button> element.
Alternately you could also use deleteRow(...).
The DeleteRow javascript method should have code to loop through the Table element, identify the row you want to delete and then invoke the delete method of the document object.
function DeleteARow(id) {
var row = document.getElementById(id);
if ( row ) {
row.parentNode.removeChild(row);
}
}

how to identify the radio button in javascript

I am creating a dynamic table in which each row has a group of radio buttons placed in different columns.
I want to change the cell background color when a radio button is clicked.I am constructing the table using the code snippet below. How to identify the radio button in javascript, so that I can set the cell with an appropriate background color.
<table>
<c:forEach>
<tr>
<c:forEach>
<td><input type="radio" value="" /></td>
</c:forEach>
</tr>
</c:forEach>
</table>
Use dojo or jQuery to select the radioButton node, then use CSS filter expressions to set the td tag (parentNode dom node) to whatever color you want.
Example using dojo :
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Dojo selectors example</title>
<script type="text/javascript">
var djConfig = {
parseOnLoad: true,
isDebug: true,
locale: 'en-us'
};
</script>
<script type="text/javascript" src="http://o.aolcdn.com/dojo/1.4.1/dojo/dojo.xd.js"></script>
<script type="text/javascript">
dojo.addOnLoad(function() {
// Get all the radioButtons that are inside a <td> tag
dojo.query("td > input").forEach(function(node, index, array){
var td = node.parentNode;
dojo.addClass(td, "red");
dojo.connect(td, "onclick", function(){dojo.toggleClass(td, "white");});
});
});
</script>
<style type="text/css">
.red { background-color : red; }
.white { background-color : white; }
</style>
</head>
<body>
<form id="form1">
<table>
<tr>
<td><input type="radio" value="" /></td>
</tr>
<tr>
<td><input type="radio" value="" /></td>
</tr>
<tr>
<td><input type="radio" value="" /></td>
</tr>
</table>
</form>
</body>
</html>
I'll leave it up to you to correct the radiobutton's behaviour...
you should try and set a unique id for the input field when creating it (e.g. id="theradiobutton")
Then you can reference it easily using DOM methods!
You need to set the id or use a fake class name.
Later I should use jquery for accessing and changing them.
http://www.google.es/search?rlz=1C1GGLS_esES361ES361&sourceid=chrome&ie=UTF-8&q=radio+button+jquery
var myform = document.forms['myform'];
for ( var i=0; i < myform.elements; i++ )
if ( myform.elements[i].type == 'radio' ) ...do your stuff
Hope it helps.
It's simple with jQuery. Here's an SSCCE, copy'n'paste'n'run it.
<!doctype html>
<html lang="en">
<head>
<title>Test</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function() {
$('#tableId input[name=row]').click(function() {
$('#tableId tr').removeClass('selected'); // Reset.
$(this).parents('tr').addClass('selected');
});
});
</script>
<style>
tr.selected {
background: #ffc;
}
</style>
</head>
<body>
<table id="tableId">
<tr><td><input type="radio" name="row" value="row1">row1</td></tr>
<tr><td><input type="radio" name="row" value="row2">row2</td></tr>
<tr><td><input type="radio" name="row" value="row3">row3</td></tr>
</table>
</body>
</html>
Just translate the table back into the dynamic flavor you've had with JSP/JSTL.
Without getting too fussy about it, this is really pretty simple. You don't need to identify the radio button, just call an event handler and pass the instance of the button with it:
<td><input type="radio" value="" onclick="colorMyCell(this)" /></td>
and the handler:
function colorMyCell(inp) {
// get reference to the row
var tr = inp.parentNode.parentNode;
// put the TD children of the row into an array
var cells = tr.getElementsByTagName("TD");
// bgcolor all the other cells in that row white
for (var i=0; i<cells.length; i++) {
cells[i].style.backgroundColor = "#ffffff";
}
// now bgcolor the selected cell differently
inp.parentNode.style.backgroundColor = "#ffffcc";
}
Note that this is just a quick and dirty example of how to do this. You would want to take more care with it (make sure inp.parentNode.parentNode really is a TR, if not find a better way to work your way up the tree to find the actual first-ancestor TR), as well as using CSS classNames instead of directly setting background colors, and so on.

Runtime creation of tables in Javascript?

I my application "When a button is clicked it should create a new text field in the table". So i have done like this and its not working as well. So what could be the problem in the following snippet.
<html>
<script type="text/javascript" language="javascript">
var newtr=document.createElement("tr");
var newtd=document.createElement("td");
var output="<input type=\"textfield\"";
newtd.innerHtml=output;
newtr.appendChild(newtd);
function create_row()
{
document.getElementById("table1").appendChild(newtr);
}
</script>
<body>
<table id="table1">
<tr>
<td>
<input type-"textfield" name="tfield">
</td>
</tr>
<tr>
<td> <input type="button" name="button" value="new row" onclick="create_row();">
</tr>
</table>
</body>
</html>
I am using IE7.
In order to make this work in IE you should create a TBODY first then append the TRs in TBODY. If you don't do this IE cannot render the table content, HTML part will be created succesffully but it will not be seen on the page.
So you should modify your script to append TRs into the TBODY
Few remarks about your code:
You need to properly close tags: var output="<input type=\"textfield\"" is not valid
There's no input type="textfield" defined
The property to set the html of a given DOM element is called innerHTML and not innerHtml
You need to create a new tr element every time the button is clicked, so this should be inside the create_row function
You have a typo in your HTML: <input type-"textfield" name="tfield">. This should be changed to <input type="text" name="tfield" />
You are missing a head section in your document
I've tried cleaning your code a bit:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Test</title>
<script type="text/javascript">
function create_row()
{
var newtr = document.createElement('tr');
var newtd = document.createElement('td');
var output = '<input type="text" name="test" />';
newtd.innerHTML = output;
newtr.appendChild(newtd);
document.getElementById('table1').appendChild(newtr);
}
</script>
</head>
<body>
<table id="table1">
<tr>
<td>
<input type="textfield" name="tfield" />
</td>
</tr>
<tr>
<td>
<input type="button" name="button" value="new row" onclick="create_row();" />
</td>
</tr>
</table>
</body>
</html>
UPDATE:
As pointed out by Guffa and Serkan answers in IE7 a tbody section needs to be used:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Test</title>
<script type="text/javascript">
function create_row()
{
var newtr = document.createElement('tr');
var newtd = document.createElement('td');
var output = '<input type="text" name="test" />';
newtd.innerHTML = output;
newtr.appendChild(newtd);
document.getElementById('tablebody').appendChild(newtr);
}
</script>
</head>
<body>
<table id="table1">
<tbody id="tablebody">
<tr>
<td>
<input type="textfield" name="tfield" />
</td>
</tr>
<tr>
<td>
<input type="button" name="button" value="new row" onclick="create_row();" />
</td>
</tr>
</tbody>
</table>
</body>
</html>
You are missing a head tag.
The script should be in the head tag.
The html code for the input element is missing a closing bracket.
The type "textfield" does not exist.
The code only works once as you create the elements outside the function.
The method is innerHTML, not innerHtml.
You have to add the row to the tbody element, not the table itself.
I have tested this in Firefox 3 and IE 8 and it works:
<html>
<head>
<script type="text/javascript">
function create_row() {
var newtr=document.createElement("tr");
var newtd=document.createElement("td");
var output="<input type=\"text\">";
newtd.innerHTML=output;
newtr.appendChild(newtd);
document.getElementById("table1body").appendChild(newtr);
}
</script>
</head>
<body>
<table>
<tbody id="table1body">
<tr>
<td>
<input type-"textfield" name="tfield">
</td>
</tr>
<tr>
<td> <input type="button" name="button" value="new row" onclick="create_row();">
</tr>
</tbody>
</table>
</body>
</html>

Categories