Tables are stacking instead of replacing - javascript

I find it hard to create a title to this question but what I really want to know is how to make my code (that creates tables derived from the value of an input) stop from stacking up tables every time an event is made. like when I input "2" it creates 2 tables but when I input "3" it adds 3 tables thus, 5 tables are made instead of just 3.
I want want my code to create tables derived from the input box rather than stacking it up. How can I achieve this?
<html>
<body>
<input type="text" onblur="myfunction()" onchange="myfunction" id="dino">
<br>
<table id="mytable">
<script>
function myfunction() {
var value = document.getElementById("dino").value;
for (var i = 0; i < value; i++){
var tr = document.createElement('tr');
var td1 = document.createElement('td');
var td2 = document.createElement('td');
var td3 = document.createElement('td');
var var_input_days = document.createElement("INPUT");
var_input_days.setAttribute("type", "text");
var_input_days.setAttribute("id", "ID_DAYS_" + [i]);
var_input_days.setAttribute("value","DAYS_" + [i]);
var_input_days.setAttribute("name", "DAYS_" + [i]);
var var_input_name = document.createElement("INPUT");
var_input_name.setAttribute("type", "text");
var_input_name.setAttribute("id", "ID_NAME_" + [i]);
var_input_name.setAttribute("value","NAME_" + [i]);
var_input_name.setAttribute("name", "NAME_" + [i]);
var var_input_data_ca = document.createElement("INPUT");
var_input_data_ca.setAttribute("type", "text");
var_input_data_ca.setAttribute("id", "ID_DATA_CA_" + [i]);
var_input_data_ca.setAttribute("value","ID_DATA_CA_" + [i]);
var_input_data_ca.setAttribute("name", "DATA_" + [i]);
td1.appendChild(var_input_name);
td2.appendChild(var_input_days);
td3.appendChild(var_input_data_ca);
tr.appendChild(td1);
tr.appendChild(td2);
tr.appendChild(td3);
document.getElementById("mytable").appendChild(tr);
}
document.body.appendChild(table);
}
</script>
</table>
</body>
</html>

What you are doing is adding more elements to the added ones.
What you need to do first is clear the contents of table and recreate it.
You can achieve this by adding just one line at the beginning of myfunction()
document.getElementById("mytable").innerHTML="";
This will clear all contents of mytable before recreating it.

Remove the existing rows in the table first in the myfunction() and then append the rows you are creating.
answer by ramicious works, but you can find the best way to remove existing rows in a table in the following post Delete all rows in an HTML table.

Related

Get select values from different textareas and insert into a table

I'm currently learning JS and working on creating a HTML invoice. I want to take values from three textareas that are entered and then add them to the end of my table (The total is calculated automatically whose function is working fine). Currently I've added blank fields using
$("#addrow").click(function(){
$(".item-row:last").after('<tr class="item-row"><td class="item-name"><div class="delete-wpr"><textarea>Item Name</textarea><a class="delete" href="javascript:;" title="Remove row">X</a></div></td><td><textarea class="cost">0</textarea></td><td><textarea class="qty">0</textarea></td><td><span class="price">0</span></td></tr>');
But I do not know how to get the three values I enter getting added to the table when I click on add
Image of table with empty fields added
You need to get the value from the inputs and then concatenate them in your append.
Try this:
$("#addrow").click(function(){
var itemName = $('#add-description').val();
var itemHours = $('#add-hours').val();
var itemRate = $('#add-rate').val();
$(".item-row:last").after('<tr class="item-row"><td class="item-name"><div class="delete-wpr"><textarea id="new-description">'+itemName+'</textarea><a class="delete" href="javascript:;" title="Remove row">X</a></div></td><td><textarea class="cost">'+itemHours+'</textarea></td><td><textarea class="qty">'+itemRate+'</textarea></td><td><span class="price">0</span></td></tr>');
if ($(".delete").length > 0) $(".delete").show();
bind();});
Example: CodePen
You can use below code to get the text from text area. Get all three text from text boxes and append into the td of the table
Text area :
var bla = $('textarea:input[name=txt_area]').val();
Text Box :
var bla = $('#txt_name').val();
You can use this code for your requirement
**var taskdescription = document.getElementById('taskdescription').value;
var hours = document.getElementById('hours').value;
var rate = document.getElementById('rate').value;
var amount = document.getElementById('amount').value;
var table = document.getElementById('table');
var tr = document.createElement("tr");
var td = document.createElement("td");
var txt = document.createTextNode(taskdescription);
td.appendChild(txt);
var td1 = document.createElement("td");
var txt1 = document.createTextNode(hours);
td1.appendChild(txt1);
var td2 = document.createElement("td");
var txt2 = document.createTextNode(rate);
td2.appendChild(txt2);
var td3 = document.createElement("td");
var txt3 = document.createTextNode(amount);
td3.appendChild(txt3);
tr.appendChild(td);
tr.appendChild(td1);
tr.appendChild(td2);
tr.appendChild(td3);
table.appendChild(tr);**
this will automaticlly append your data into table

Error "Cannot read property 'appendChild' of null at generateTable"

Can someone please shine some light on my this error is tossed? outputTable is properly referenced, and my JS file with the array countries is properly formatted.
I reckon I am appending erroneously, but I have tried all that I can.
PS if youre going to downvote, at least please tell me how to improve my questions in the future. I couldnt find a different question that exists already that matches my issue.
window.onload = generateTable();
function generateTable() {
// get the reference for the body
var outputTable = document.getElementById('outputTable');
// revoke existing Body element
if (outputTable) {
outputTable.removeChild(outputTable);
}
// creates a <tbody> element
var tableBody = document.createElement('tbody');
// creating all table rows
for (var i = 0; i < countries.length; i++) {
// creates a table row
var row = document.createElement('tr');
// create table column for flag
var colFlag = document.createElement('td');
//create image element in flag column
var flag = document.createElement('img');
flag.src = 'flags/' + countries[i].Code.toLowerCase() + '.png';
flag.alt = countries[i].Code;
row.appendChild(colFlag);
//append flag to flag column
colFlag.appendChild(flag);
// create table column for Code
var colCode = document.createElement('td');
//append code to code column
colCode.appendChild(document.createTextNode(countries[i].Code));
row.appendChild(colCode);
// create table column for country //**ENGLISH */
var colCountry = document.createElement('td');
colCountry.appendChild(document.createTextNode(countries[i].Name.English));
row.appendChild(colCountry);
// create table column for continent
var colCont = document.createElement('td');
colCont.appendChild(document.createTextNode(countries[i].Continent));
row.appendChild(colCont);
// create table column for area
var colArea = document.createElement('td');
colArea.appendChild(document.createTextNode(countries[i].AreaInKm2));
row.appendChild(colArea);
// create table column for population
var colPop = document.createElement('td');
colPop.appendChild(document.createTextNode(countries[i].Population));
row.appendChild(colPop);
// create table column for capital of country
var colCap = document.createElement('td');
colCap.appendChild(document.createTextNode(countries[i].Capital));
row.appendChild(colCap);
// attach columns to row
tableBody.appendChild(row);
outputTable.appendChild(tableBody);
}
// add the row to the end of the table body
document.body.appendChild(outputTable);
}

Setting .innerHTML on a newly created TD element blank when content is returned from a function

In short, why does the following function work where the latter function does not?
Working Code
function createRawRowElementViaInnnerHTML(){
var row = document.createElement("tr");
row.innerHTML = '<td>'+createDropDownHTML()+'</td>'+
'<td>'+createTxtAreaDownHTML()+'</td>';
return row;
}
Non-Working Code
function createRowElement(){
var row = document.createElement("tr");
var td1 = document.createElement("td");
td1.innerHTML="Col 1 innerHTML -- should be overwritten";
td1.innerHMTL=createDropDownHTML();
var td2 = document.createElement("td");
td2.innerHTML="Col 2 innerHTML -- should be overwritten";
td2.innerHMTL=createTxtAreaDownHTML();
row.appendChild(td1);
row.appendChild(td2);
return row;
}
I'd expect that creating the <td> elements and setting their .innerHTML would work the same as hard coding the table cell's inner html like such '<td>'+createDropDownHTML()+'</td>'. The "non-working code" produces the <tr> element with two <td> elements, but those <td> elements content are blank (for demo purposes I set their innerHTML to show they were created correctly). Behavior is observed on both FF32 and Chrome37.
Please see this fiddle for the remaining code (such as the function calls). Also, I attempted to use the new stack overflow code-snippet, this is the same code that can be found on the fiddle.
for(var i =0; i<5;i++){
var r = createRowElement();
document.getElementById("myTable").appendChild(r);
var r2 = createRawRowElementViaInnnerHTML();
document.getElementById("myTable").appendChild(r2);
}
function createRawRowElementViaInnnerHTML(){
var row = document.createElement("tr");
row.innerHTML = '<td>'+createDropDownHTML()+'</td>'+
'<td>'+createTxtAreaDownHTML()+'</td>';
return row;
}
function createRowElement(){
var row = document.createElement("tr");
var td1 = document.createElement("td");
td1.innerHTML="Col 1 innerHTML -- should be overwritten";
td1.innerHMTL=createDropDownHTML();
var td2 = document.createElement("td");
td2.innerHTML="Col 2 innerHTML -- should be overwritten";
td2.innerHMTL=createTxtAreaDownHTML();
row.appendChild(td1);
row.appendChild(td2);
return row;
}
function createDropDownHTML(){
return '<select><option>1</option><option>2</option><option>3</option></select>';
}
function createTxtAreaDownHTML(){
return '<textarea></textarea>';
}
<table id="myTable"></table>
Any Ideas? Most posts that came up from googling had to do with the dom not being ready, which isn't the case here. Also read a post about some form of potential html validation/clean-up, but I do not understand why it'd work one way and not the other since in both functions I am using .innerHTML on some level. Looking for an answer with documentation/resources as to why the latter function doesn't work. Thank you for your time.
function createRowElement(){
var row = document.createElement("tr");
var td1 = document.createElement("td");
td1.innerHTML="Col 1 innerHTML -- should be overwritten";
td1.innerHMTL=createDropDownHTML(); // should be HTML instead of HMTL
var td2 = document.createElement("td");
td2.innerHTML="Col 2 innerHTML -- should be overwritten";
td2.innerHMTL=createTxtAreaDownHTML(); // should be HTML instead of HMTL
row.appendChild(td1);
row.appendChild(td2);
return row;
}
As seen in the above comments, you should change those lines to:
// ...
td1.innerHTML = createDropDownHTML();
// ...
td2.innerHTML = createTxtAreaDownHTML();
In these cases usually its a problem of spellings and cases. All you need to do is have a sharp eye. The M and the T in the HTML are switched in your code.

Questions about dynamically creating divtags

I'm trying to dynamically create divtags for each cell of my table so that I can later fill them in with other stuff. However, when I tried doing this:
newhtml+="<div id ='" + (j) +"'><td class = 'unselected'>&nbsp?&nbsp</td></div>"
and later using it it acted as if it never created it.
So after browsing stackoverflow I found out that you should use this line of code to dynamically create a div tag:
var divtag = document.createElement('div');
But my question is how do I implement it into my js code?
Here is the section of code that is supposed to create divtags for later referencing:
newhtml+="<tr>";
for (var j = 0; j < $tblcols; j++){
newhtml+="<div id ='" + (j) +"'><td class = 'unselected'>&nbsp?&nbsp</td></div>";
And here is the section that uses it:
divtag = document.getElementById("'" + (++$counter2) + "'");
newhtml +="<td class = 'solved'><img src ='sc2units/" + $counter2 + ".jpg'></td>";
divtag.innerHTML = newhtml;
each section is a nested for loop that goes through the entire array of data that needs outputted.
EDIT: If there is an easier way to fill cells with data in an array I would be happy to know.
I'm not sure on your table, or setup, or exact needs.... But I believe you want to give content to certain table cells after you've already created the cells. You're on to the right idea with naming them, but you can't wrap <td>s in <div>s so your next best option is to simply name the <td>s themselves.
You could also add the content right inside the second loop, but we'll run with this.
HTML
<table id="myTable">
<tr>
<td>[ content ]</td>
</tr>
<tr>
<td>[ content ]</td>
<td>[ content ]</td>
</tr>
[ etc ]
</table>
JavaScript
var tbl = document.getElementById("myTable"),
rows = tbl.getElementsByTagName("tr");
// loop all rows
for (var r = 0; r < rows.length; r++){
// loop all cols within the row
var cols = rows[r].getElementsByTagName("td");
for (var c = 0; c < cols.length; c++){
cols[c].id = "row-" + r + "_col-" + c;
}
}
// usage
document.getElementById("row-1_col-1").innerHTML = "JS POWER";
http://jsfiddle.net/daCrosby/tJYNM/
You can create the elements separately then organize them later, inserting one inside the other. Something like:
var mydiv = document.createElement("DIV");
var mytd = document.createElement("TD");
mytd.innerHTML = "some basic text";
mydiv.appendChild(mytd); // insert the TD inside the DIV
document.body.appendChild(mydiv); // insert the DIV in the document's body
I just don't know what's about putting TD's inside DIV's...

what's the easiest method to append a TR to a table by javascript?

If the table id is known – so the table can be obtained with docoument.getElementById(table_id) – how can I append a TR element to that table in the easiest way?
The TR is as follows:
<tr><td><span>something here..</span></td></tr>
The first uses DOM methods, and the second uses the non-standard but widely supprted innerHTML
var tr = document.createElement("tr");
var td = document.createElement("td");
var span = document.createElement("span");
var text = document.createTextNode("something here..");
span.appendChild(text);
td.appendChild(span);
tr.appendChild(td);
tbody.appendChild(tr);
OR
tbody.innerHTML += "<tr><td><span>something here..</span></td></tr>"
The most straightforward, standards compliant and library-independent method to insert a table row is using the insertRow method of the table object.
var tableRef = document.getElementById(tableID);
// Insert a row in the table at row index 0
var newRow = tableRef.insertRow(0);
P.S. Works in IE6 too, though it may have some quirks at times.
Using jQuery:
$('#table_id > tbody').append('<tr><td><span>something here..</span></td></tr>');
I know some may cringe at the mention of jQuery. Including a framework to do just this one thing is probably overkill. but I rarely find that I only need to do "just one thing" with javascript. The hand-coded solution is to create each of the elements required, then add them in the proper sequence (from inner to outer) to the other elements, then finally add the new row to the table.
If you're not opposed to using jQuery, you can use either of the following where "tblId" is the id of your table and "_html" is a string representation of your table row:
$(_html).insertAfter("#tblId tr:last");
or
$("#tblId tr:last").after(_html);
i use this function to append a bunch of rows into a table. its about 100% faster then jquery for large chunks of data. the only downside is that if your rows have script tags inside of them, the scripts wont be executed on load in IE
function appendRows(node, html){
var temp = document.createElement("div");
var tbody = node.parentNode;
var nextSib = node.nextSibling;
temp.innerHTML = "<table><tbody>"+html;
var rows = temp.firstChild.firstChild.childNodes;
while(rows.length){
tbody.insertBefore(rows[0], nextSib);
}
}
where node is the row to append after, and html is the rows to append
Really simple example:
<html>
<table id = 'test'>
<tr><td>Thanks tvanfosson!</td></tr>
</table>
</html>
<script type="text/javascript" charset="utf-8">
var table = document.getElementById('test');
table.innerHTML += '<tr><td><span>something here..</span></td></tr>';
</script>
I use this, works softly:
var changeInnerHTMLOfMyCuteTbodyById = function (id_tbody, inner_html)
{
//preparing
var my_tbody = document.getElementById (id_tbody);
var my_table = my_tbody.parentNode;
my_table.removeChild (my_tbody);
//creating dom tree
var html = '<table style=\'display:none;\'><tbody id='+ id_tbody+'>' +
inner_html + '</tbody></table>';
var tmp_div = document.createElement ('div');
tmp_div.innerHTML = html;
document.body.appendChild (tmp_div);
//moving the tbody
my_table.appendChild (document.getElementById (id_tbody));
}
You can do this:
changeInnerHTMLOfMyCuteTbodyById('id_tbody', document.getElementById ('id_tbody').innerHTML + '<tr> ... </tr>');

Categories