Javascript always add 1 to total rows - javascript

I am confused about this Javascript code which I used to get total rows in a table. It will always output an excess of 1. Example: it will print 5 instead of 4!
<script>
(function() {
var div = document.getElementById('divID11');
div.innerHTML = document.getElementById('tableId11').rows.length;
})();
</script>
<div id =divID11></div>
and table structure is shown below
<table id="tableId11>
<thead>
<tr>
<th>
</th>
</tr>
</thead>
<tbody>
<tr>
<td><?php echo $data ?></td>
</tr>
</tbody>
What I am lacking here?
Outputs 3 for the name column when in fact there only 2.

If you want count only TBODY rows, use this JavaScript code:
(function() {
var div = document.getElementById('divID11');
div.innerHTML = document.getElementById('tableId11').getElementsByTagName("tbody")[0].rows.length;
})();
Your JavaScript code counting all rows in table (thead and tbody). If you want count only tbody rows, you must specify the element (so you must modify your code to specify, with which part of your table you wanna work).
JSFiddle here

Try this :
var div = document.getElementById('divID11');
div.innerHTML = document.getElementById('tableId1').getElementsByTagName('tbody')[0].rows.length;

Related

Create row in html table which does not have id and class

I would like to create one additional row in HTML Table which is very common and can be done if we have id or class available of that table.
But in my case I have one page which contains many forms and tables.
But in all those I have one form which contains only one element i.e table and I would like to create one more row and move few columns from 1st row to newly created row.
For this I have created simple HTML page.Please find below code and help me to achieve my output.
<h:form id="myForm">
<table>
<tr>
<td id="col1">Item Info</td>
<td id="col2">Description</td>
<td id="col3">Product</td>
<td id="col4">Keywords</td>
<td id="col5">Documents</td>
<td id="col6">Image</td>
<td id="col7">Video</td>
</tr>
</table>
</h:form>
Here Ia m getting output like
Item Info Description Product Keywords Documents Image Video
But I want to achieve something like below:
Item Info Description Product Keywords
NEW CELL1 Documents Image Video
means I would like to remove few columns from existing row and I would like to add it in newly created row.
For this I have written Javascript like:
<script type="text/javascript">
window.onload = function() {
split();
};
function split() {
var form = document.getElementById("myForm");
var table = form.elements[0];
var tr = document.createElement("tr");
tr.id="row2";
table.appendChild(tr);
var cell = tr.insertCell(0);
cell.innerHTML = "NEW CELL1";
var col5 = document.getElementById("col5");
tr.appendChild(col5);
var col6 = document.getElementById("col6");
tr.appendChild(col6);
var col7 = document.getElementById("col7");
tr.appendChild(col7);
}
</script>
Here, My problem is this entire form will be generated automatically so I can't give the Id for the table and with this script it is not identifying my table when I am giving form.elemets[0];
I want to find table element so that I can create row in that table.
You can find the table by doing this:
Get one of the elements in a table row, and get the parent node until you've got the table. In this case you could do document.getElementById('col1').parentNode.parentNode
And just to ease things,
You can insert this string '</tr><tr>' in a row, after a table cell, to easily create a new row.
This should be better than document.getElementsByTagName('table'), because if you have lots of tables which are far away, it will take more time to find your table's index in that array.
Use getElementsByTagName to get the table from within your form, which has an ID
window.onload = function() {
split();
};
function split() {
var form = document.getElementById("myForm");
var table = form.getElementsByTagName("table")[0];
var tr = document.createElement("tr");
tr.id = "row2";
table.appendChild(tr);
var cell = tr.insertCell(0);
cell.innerHTML = "NEW CELL1";
/*Your original code produces duplicate IDs which is a BAD thing*/
var col5 = document.getElementById("col5");
/*Update new Id*/
col5.id += "_new";
tr.appendChild(col5);
var col6 = document.getElementById("col6");
/*Update new Id*/
col6.id += "_new";
tr.appendChild(col6);
var col7 = document.getElementById("col7");
/*Update new Id*/
col7.id += "_new";
tr.appendChild(col7);
}
<form id="myForm">
<table>
<tr>
<td id="col1">Item Info</td>
<td id="col2">Description</td>
<td id="col3">Product</td>
<td id="col4">Keywords</td>
<td id="col5">Documents</td>
<td id="col6">Image</td>
<td id="col7">Video</td>
</tr>
</table>
</form>
You also have a mismatch of column numbers, with the code provided you originally have 7 columns and only insert 4, this will produce inconsistent results, make sure to use the colspan attribute as needed.
You should be able to use JavaScript's querySelector method to select the table data you want to remove from the document.
Something like var rowToDeleteOrAddTo = document.querySelector("#myForm > table > tr > td"); should help you get there. You'll need to lookup CSS Selectors to get the specific selectors you need. You may need to use the textContent property once you have a node to make sure you are deleting the right one.

Table footer with sum for numbers and average for percentages

I have html table that looks like this:
| H1 |
H1 |-----------------|
| H2 | H2 |
------------------------|
Text |Number|Percentage|
------------------------|
Text |Number|Percentage|
------------------------|
...
Is there a way to add "Total" footer that will look like this:
| H1 |
H1 |-----------------|
| H2 | H2 |
------------------------|
Text |Number|Percentage|
------------------------|
Text |Number|Percentage|
------------------------|
...
------------------------|
Total:|Sum |Avg prcntg|
------------------------|
using JS, that will take into account class of a cell (percentage, number) and calculate total for columns accordingly?
There is a few somewhat similar solutions, but I'm new to JS (and HTML for that matter) and can't modify them myself. I would aslo greatly appreciate if you throw in some comments along the solution, so I could actually learn something :)
<table border="1">
<thead>
<th rowspan="2">Header</th>
<th colspan="2">Header</th>
<tr>
<th>Numbers</th>
<th>Percentages</th>
</tr>
</thead>
<tbody>
<tr>
<td>Text</td>
<td class="number">1</td>
<td class="percentage">30</td>
</tr>
<tr>
<td>Text</td>
<td class="number">2</td>
<td class="percentage">40</td>
</tr>
</tbody>
<tfoot>
<td>Total:</td>
<td class="result"></td>
<td class="result"></td>
</tfoot>
</table>
EDIT
Okay, I fiddled around with other solutions a bit more and here what I made:
var totals = [0, 0, 0, 0, 0];
var tbodyrows = $('#myTable tbody').find('tr').length;
$(document).ready(function() {
var $dataRows = $("#myTable tbody tr");
$dataRows.each(function() {
$(this).find('.number').each(function(i) {
totals[i] += parseInt($(this).text());
});
});
$("#myTable tfoot td:not(:first-child)").each(function(i) {
if ($(this).hasClass("result")) {
$(this).text(totals[i]);
}
if ($(this).hasClass("perresult")) {
$(this).text(totals[i] / tbodyrows);
}
});
});
JSFIDDLE
That works, but what if I want it to make footer, instead of populating premade one?
If you want to add the totals to the table yourself, you are likely looking for something like jQuery's .append function. This will let you add on new table rows to the end of the table, once you've calculated the totals. Link to docs: http://api.jquery.com/append/
// JavaScript: (comments below each line start with //)
var tableHtml = '';
// new empty string variable to put your table html in
tableHtml += '';
// this starts a new table row (tr), += adds more to the existing value
tableHtml += 'Text';
// this is the text column (cell)
tableHtml += ''+numberTotal+'';
// the js number variable in a new cell
tableHtml += ''+percentTotal+'';
// the js percent variable in a new cell
tableHtml += '';
// the end of a new table row
$( "table" ).append(tableHtml);
// appends this html as a child of "table" or "tbody" if that works better
You may need to use some of the other comments above to get the totals, but my answer shows how to add it to the table after the page is loaded in real time.
Yes it can be done.You can get the elements using jquery and run a loop to find the total and average percentage as follows:
var numbers=$('.number')
var percentage=$('.percentage')
var avg=0;
var total=0;
for(var i=0;i<numbers.length;i++){
total=total+parseInt(numbers.eq(i).text())
avg=avg+parseInt(percentage.eq(i).text())
}
$('.result').eq(0).text(total)
$('.result').eq(1).text(percentage/numbers.length)

how to convert/transform an HTML table tbody (with rowspans) TO json?

I have an HTML table with combined row td's, or how to say, I don't know how to express myself (I am not so good at English), so I show it! This is my table:
<table border="1">
<thead>
<tr>
<th>line</th>
<th>value1</th>
<th>value2</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="2">1</td>
<td>1.1</td>
<td>1.2</td>
</tr>
<tr>
<td>1.3</td>
<td>1.4</td>
</tr>
<tr>
<td rowspan="2">2</td>
<td>2.1</td>
<td>2.2</td>
</tr>
<tr>
<td>2.3</td>
<td>2.4</td>
</tr>
</tbody>
</table>
(you can check it here)
I want to convert this table to a JSON variable by jquery or javascript.
How should it look like, and how should I do it? Thank you, if you can help me!
if you want to convert only text use this one :
var array = [];
$('table').find('thead tr').each(function(){
$(this).children('th').each(function(){
array.push($(this).text());
})
}).end().find('tbody tr').each(function(){
$(this).children('td').each(function(){
array.push($(this).text());
})
})
var json = JSON.stringify(array);
To make a somehow representation of your table made no problem to me, but the problem is how to parse it back to HTML! Here a JSON with the first 6 tags:
{"table":{"border":1,"thead":{"th":{"textContent":"line","tr":"textContent":"value1",...}}}}}...
OR for better understanding:
{"tag":"table","border":1,"child":{"tag":"thead","child":{"tag":"th","textContent":"line",
"child":{"tag":"tr","textContent":"value1","child":...}}}}...
Closing tags are included.
For further explanations I need to know whether your table is a string or part of the DOM.
I belive this is what you want:
var jsonTable = {};
// add a new array property named: "columns"
$('table').find('thead tr').each(function() {
jsonTable.columns = $(this).find('th').text();
};
// now add a new array property which contains your rows: "rows"
$('table').find('tbody tr').each(function() {
var row = {};
// add data by colum names derived from "tbody"
for(var i = 0; i < jsonTable.columnsl.length; i++) {
row[ col ] = $(this).find('td').eq( i ).text();
}
// push it all to the results..
jsonTable.rows.push( row );
};
alert(JSON.stringify(jsonTable));
I think there should be some corrections, but this is it I think.

table mapping by th and first td in row to populate from json object

using php to echo json array inline i want js/jquery to populate table according to these data.
HTML table
<table>
<thead>
<tr>
<th>Time</th>
<th data-day='2013-03-15'>15-3</th>
<th data-day='2013-03-16'>16-3</th>
<th data-day='2013-03-17'>17-3</th>
</tr>
</thead>
<tbody>
<tr data-time='09'>
<td>9am</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<script>
var arr=[
{"date":"2013-03-15","id":"4","time_booked":"09:00:00"},
{"date":"2013-03-15","id":"1","time_booked":"09:10:00"},
{"date":"2013-03-17","id":"5","time_booked":"09:30:00"}
];
$.each(arr,function(){
console.log('id:'+this.id+'inside:'+this.date+'|'+this.time_booked);
});
</script>
i want to loop thro arr and according to its date and time_booked write id inside td.
for example first row will go to td with date-day='2013-03-15' and data-time='09'
so how can i do this using javascript ?
im thinking should i include data-day,data-time inside each td in tbody ? or is there a better way to do it ?
current approach:
include data-day inside each tr so html of tbody is
<tr data-time='09'>
<td data-day='2013-03-15'></td>
<td data-day='2013-03-16'></td>
etc..
</tr>
then use js
$.each(arr,function(){
var rday=this.date;
var rtime=this.time_booked;
var sel='tr[data-hr="'+rtime.substr(0,2)+'"]';
var dom=$(sel).find('td[data-day="'+rday+'"]').first();
if(dom.length)dom.append(this.id);
});
but i have a feeling its stupid ! there must be a way to map table using x,y (table head,row head) or there is none ?
I think the jQuery index function is what you're looking for. In the code sample below, I've used it to fetch the colIndex for the date. In this case, it fetches all of the th cells within the table, and uses .index(..) with a selector seeking the required date. This gives the column index of the date you're seeking, and from there it's all pretty straight-forward.
var arr=[
{"date":"2013-03-15","id":"4","time_booked":"0900"},
{"date":"2013-03-15","id":"1","time_booked":"0910"},
{"date":"2013-03-17","id":"5","time_booked":"0930"}
];
$.each(arr,function(){
var cell = GetCellByDateAndTime(this.date, this.time_booked);
$(cell).text(this.id);
});
function GetCellByDateAndTime(date, time) {
var colIndex = $("#BookingsTable th").index($("[data-day='" + date + "']"));
var row = $("#BookingsTable tr[data-time='" + time + "']")
var cell = $(row).children($("td"))[colIndex];
return cell;
}
And a Fiddle.

Delete all rows in an HTML table

How can I delete all rows of an HTML table except the <th>'s using Javascript, and without looping through all the rows in the table? I have a very huge table and I don't want to freeze the UI while I'm looping through the rows to delete them
this will remove all the rows:
$("#table_of_items tr").remove();
Keep the <th> row in a <thead> and the other rows in a <tbody> then replace the <tbody> with a new, empty one.
i.e.
var new_tbody = document.createElement('tbody');
populate_with_new_rows(new_tbody);
old_tbody.parentNode.replaceChild(new_tbody, old_tbody)
Very crude, but this also works:
var Table = document.getElementById("mytable");
Table.innerHTML = "";
Points to note, on the Watch out for common mistakes:
If your start index is 0 (or some index from begin), then, the correct code is:
var tableHeaderRowCount = 1;
var table = document.getElementById('WRITE_YOUR_HTML_TABLE_NAME_HERE');
var rowCount = table.rows.length;
for (var i = tableHeaderRowCount; i < rowCount; i++) {
table.deleteRow(tableHeaderRowCount);
}
NOTES
1. the argument for deleteRow is fixed
this is required since as we delete a row, the number of rows decrease.
i.e; by the time i reaches (rows.length - 1), or even before that row is already deleted, so you will have some error/exception (or a silent one).
2. the rowCount is taken before the for loop starts
since as we delete the "table.rows.length" will keep on changing, so again you have some issue, that only odd or even rows only gets deleted.
Hope that helps.
This is an old question, however I recently had a similar issue.
I wrote this code to solve it:
var elmtTable = document.getElementById('TABLE_ID_HERE');
var tableRows = elmtTable.getElementsByTagName('tr');
var rowCount = tableRows.length;
for (var x=rowCount-1; x>0; x--) {
elmtTable.removeChild(tableRows[x]);
}
That will remove all rows, except the first.
Cheers!
If you can declare an ID for tbody you can simply run this function:
var node = document.getElementById("tablebody");
while (node.hasChildNodes()) {
node.removeChild(node.lastChild);
}
Assuming you have just one table so you can reference it with just the type.
If you don't want to delete the headers:
$("tbody").children().remove()
otherwise:
$("table").children().remove()
hope it helps!
I needed to delete all rows except the first and solution posted by #strat but that resulted in uncaught exception (referencing Node in context where it does not exist). The following worked for me.
var myTable = document.getElementById("myTable");
var rowCount = myTable.rows.length;
for (var x=rowCount-1; x>0; x--) {
myTable.deleteRow(x);
}
the give below code works great.
It removes all rows except header row. So this code really t
$("#Your_Table tr>td").remove();
this would work iteration deletetion in HTML table in native
document.querySelectorAll("table tbody tr").forEach(function(e){e.remove()})
Assing some id to tbody tag. i.e. . After this, the following line should retain the table header/footer and remove all the rows.
document.getElementById("yourID").innerHTML="";
And, if you want the entire table (header/rows/footer) to wipe out, then set the id at table level i.e.
How about this:
When the page first loads, do this:
var myTable = document.getElementById("myTable");
myTable.oldHTML=myTable.innerHTML;
Then when you want to clear the table:
myTable.innerHTML=myTable.oldHTML;
The result will be your header row(s) if that's all you started with, the performance is dramatically faster than looping.
If you do not want to remove th and just want to remove the rows inside, this is working perfectly.
var tb = document.getElementById('tableId');
while(tb.rows.length > 1) {
tb.deleteRow(1);
}
Pure javascript, no loops and preserving headers:
function restartTable(){
const tbody = document.getElementById("tblDetail").getElementsByTagName('tbody')[0];
tbody.innerHTML = "";
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"/>
<table id="tblDetail" class="table table-bordered table-hover table-ligth table-sm table-striped">
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 2</th>
<th>Header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>
a
</td>
<td>
b
</td>
<td>
c
</td>
<td>
d
</td>
</tr>
<tr>
<td>
1
</td>
<td>
2
</td>
<td>
3
</td>
<td>
4
</td>
<tr>
<td>
e
</td>
<td>
f
</td>
<td>
g
</td>
<td>
h
</td>
</tr>
</tr>
</tbody>
</table>
<button type="button" onclick="restartTable()">restart table</button>
If you have far fewer <th> rows than non-<th> rows, you could collect all the <th> rows into a string, remove the entire table, and then write <table>thstring</table> where the table used to be.
EDIT: Where, obviously, "thstring" is the html for all of the rows of <th>s.
This works in IE without even having to declare a var for the table and will delete all rows:
for(var i = 0; i < resultsTable.rows.length;)
{
resultsTable.deleteRow(i);
}
this is a simple code I just wrote to solve this, without removing the header row (first one).
var Tbl = document.getElementById('tblId');
while(Tbl.childNodes.length>2){Tbl.removeChild(Tbl.lastChild);}
Hope it works for you!!.
Assign an id or a class for your tbody.
document.querySelector("#tbodyId").remove();
document.querySelectorAll(".tbodyClass").remove();
You can name your id or class how you want, not necessarily #tbodyId or .tbodyClass.
#lkan's answer worked for me, however to leave the first row, change
from
for (var x=rowCount-1; x>0; x--)
to
for (var x=rowCount-1; x>1; x--)
Full code:
var myTable = document.getElementById("myTable");
var rowCount = myTable.rows.length;
for (var x=rowCount-1; x>1; x--) {
myTable.deleteRow(x);
}
This will remove all of the rows except the <th>:
document.querySelectorAll("td").forEach(function (data) {
data.parentNode.remove();
});
Same thing I faced. So I come up with the solution by which you don't have to Unset the heading of table only remove the data..
<script>
var tablebody =document.getElementById('myTableBody');
tablebody.innerHTML = "";
</script>
<table>
<thead>
</thead>
<tbody id='myTableBody'>
</tbody>
</table>
Try this out will work properly...
Assuming the <table> element is accessible (e.g. by id), you can select the table body child node and then remove each child until no more remain. If you have structured your HTML table properly, namely with table headers in the <thead> element, this will only remove the table rows.
We use lastElementChild to preserve all non-element (namely #text nodes and ) children of the parent (but not their descendants). See this SO answer for a more general example, as well as an analysis of various methods to remove all of an element's children.
const tableEl = document.getElementById('my-table');
const tableBodyEl = tableEl.querySelector('tbody');
// or, directly get the <tbody> element if its id is known
// const tableBodyEl = document.getElementById('table-rows');
while (tableBodyEl.lastElementChild) {
tableBodyEl.removeChild(tableBodyEl.lastElementChild);
}
<table id="my-table">
<thead>
<tr>
<th>Name</th>
<th>Color</th>
</tr>
</thead>
<tbody id="table-rows">
<tr>
<td>Apple</td>
<td>Red</td>
</tr>
<!-- comment child preserved -->
text child preserved
<tr>
<td>Banana</td>
<td>Yellow</td>
</tr>
<tr>
<td>Plum</td>
<td>Purple</td>
</tr>
</tbody>
</table>
Just Clear the table body.
$("#tblbody").html("");
const table = document.querySelector('table');
table.innerHTML === ' ' ? null : table.innerHTML = ' ';
The above code worked fine for me. It checks to see if the table contains any data and then clears everything including the header.

Categories