Create Array from table using jQuery - javascript

I am looking to create an array using jQuery from a table with a <thead> and a <tbody>
The result I am looking for is
[[20th Jan, 33], [21st Jan, 44], [22nd Jan, 5],[23rd Jan, 17]]
My Table is as follows
<table class="" id="bookedTable" border="1">
<thead>
<tr>
<th>Date</th>
<th>20th jan</th>
<th>21st jan</th>
<th>22nd jan</th>
<th>23rd Jan</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name</td>
<td>33</td>
<td>44</td>
<td>5</td>
<td>17</td>
</tr>
</tbody>
My JS is as follows
$(function() {
var $table = $("#bookedTable"),
$headerCells = $table.find("thead th"),
$rowCells = $table.find("tbody tr td");
var headers = [],
rows = [];
$headerCells.each(function(k,v) {
headers[headers.length] = $(this).text();
});
$rowCells.each(function(k,v) {
rows[rows.length] = $(this).text();
});
console.log(headers);
console.log(rows);
});
I can only figure out how to console log the header and rows sepeartely and not combine them in 1 array per my desired result above. Looking for some help to resolve.
MY DEMO HERE

var combined = [];
for(var i = 1; i < $headerCells.length; i++) {
combined.push([$($headerCells[i]).text(), $($rowCells[i]).text()]);
}
See it here:
http://jsfiddle.net/kp7zK/2/

var arr = $.map($('#bookedTable th:not(:first)'), function(el,i) {
return [[$(el).text(), $('#bookedTable td:eq('+i+')').text()]];
});
FIDDLE

You don't have to separately pick the headers (this replaces the whole code) :
var $table = $("#bookedTable"), l = [];
$table.find('thead th').each(function(i){
l.push([$(this).text(), $('table tbody td').eq(i).text()])
});
l = l.slice(1);
Demonstration

var myArr = [];
$("table thead tr th").each(function(i){
if(i != 0){
var colValue = $("table tbody tr td").eq(i).text();
myArr.push([this.innerHTML, colValue]);
}
});
JS Fiddle: http://jsfiddle.net/FtK4b/1/

Try this
$(function() {
var rows = [];
$('tbody tr td').each(function(k,v) {
if(k>0)
rows.push([ $('thead th:eq('+k+')').text(),$(this).text()]);
});
alert(rows.toSource());
});
Here is the working Fiddle

Related

For loop inside for loop not working properly repeating same values multiple times Javascript

I'm wanting every <tbody> tag will be gone as object index like first <tbody>->1 and second <tbody>-> 2 then inside the <tbody> every <tr> will be another object and that will be store into the <tbody> object and last the last part every <td> should have object key ("eiin", "name") inside the <tr> object
I'm trying using for loop multiple times but the console.log showing me okay but first object repeated 2 times.
Html
<section class="institute_list">
<table class="table" border="1">
<thead>
<tr>
<th scope="col">EIIN</th>
<th scope="col">Institute</th>
</tr>
</thead>
<tbody>
<tr>
<td>000000</td>
<td>Name</td>
</tr>
</tbody>
<tbody>
<tr>
<td>111111</td>
<td>Name 2</td>
</tr>
</tbody>
</table>
</section>
Javascript & jQuery
<script>
var rows = '', the_row='', the_xrow={}, tr_values={}, xtd_obj={};
tbodys = ($(".institute_list .table tbody").length);
for( var x=0; tbodys > x; x++) {
rows = $('.institute_list .table tbody:nth-child('+(x+1)+') tr').length;
the_row = '.institute_list .table tbody:nth-child('+(x+1)+') tr:nth-child(';
for( var i=1; rows >= i; i++ ){
tr_values = {
'eiin' : $(the_row+i+') td:first-child').text(),
'name' : $(the_row+i+') td:nth-child(2)').text()
};
the_xrow[i] = tr_values;
}
xtd_obj[x] = the_xrow;
}
console.log(xtd_obj);
</script>
and i'm getting this output in console
here
You may try the code below. You can separate every <tbody>,<tr>,<td> tag as a loop then make them a array.
var target = $(".institute_list > table");
var output = [];
$(target).find("tbody").each(function(i){
output[i] = {};
$(this).children().each(function(j){
output[i][j] = {};
$(this).children().each(function(k, td){
if ( k == 0 ) {
output[i][j]["eiin"] = $(td).text();
} else if ( k == 1 ) {
output[i][j]["name"] = $(td).text();
} else {
output[i][j][k] = $(td).text();
}
});
});
});
console.log(output);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="institute_list">
<table class="table" border="1">
<thead>
<tr>
<th scope="col">EIIN</th>
<th scope="col">Institute</th>
</tr>
</thead>
<tbody>
<tr>
<td>000000</td>
<td>Name</td>
</tr>
</tbody>
<tbody>
<tr>
<td>111111</td>
<td>Name 2</td>
</tr>
</tbody>
</table>
</section>
First, you need a closing </tbody> tag around the first element. Second I think you might be running into a scoping problem. You are defining the_xrow and tr_values outside of the for loops instead of inside of the for loops.
<script>
var xtd_obj={};
var tbodys = ($(".institute_list .table tbody").length);
for( var x=1; tbodys >= x; x++) {
var current_row = '.institute_list .table tbody:nth-child('+x+') tr';
var rows = $(current_row).length;
var the_row = current_row + ':nth-child(';
var the_xrow = {};
for( var i=1; rows >= i; i++ ){
the_xrow[i] = {
'eiin' : $(the_row+i+') td:first-child').text(),
'name' : $(the_row+i+') td:nth-child(2)').text()
};
}
xtd_obj[x] = the_xrow;
}
console.log(xtd_obj);
</script>
It's working for me
<script>
var rows = '', the_row='', xtd_obj={};
var tbodys = ($(".institute_list .table tbody").length)+1;
for( var x=1; tbodys > x; x++) {
rows = $('.institute_list .table tbody:nth-child('+(x+1)+') tr').length;
the_row = '.institute_list .table tbody:nth-child('+(x+1)+') tr:nth-child(';
var the_xrow = {};
for( var i=0; rows > i; i++ ){
var tr_values = {
'eiin' : $(the_row+i+1+') td:first-child').text(),
'name' : $(the_row+i+1+') td:nth-child(2)').text()
};
the_xrow[i] = tr_values;
}
xtd_obj[x] = the_xrow;
}
console.log(xtd_obj);
</script>
Here's the screenshot

Compare participants in one column of the table and make sum from other column, js

I have a table. I'd like to compare participants. If participant have several result points in the table, the script has to return sum of all participant's results. And so on for every participant.
The table is generated from database (".$row["pnt"]."".$row["station"]."".$row["res"]."):
Participant Station Points
aa Some1 1
dd Some1 2
aa sm2 3
dd sm2 4
bb sm3 5
ee sm3 6
For example I've to recieve such a new table:
aa - 4,
dd - 6,
bb - 5,
ee - 6
I've tried to do so:
$(document).ready(function () {
$("body").click(function () {
var rows = $("tbody tr");
var jo = [];
for (var i = 0; i < rows.length; i++) {
for (var j = 1; j <= rows.length; j++) {
var pnt1 = $(rows[i]).find(".pnt").html();
var stations1 = $(rows[i]).find(".station").html();
var pntR1 = $(rows[i]).find(".res").html();
if (pnt1 == $(rows[j]).find(".pnt").html()) {
pntR1 = parseInt(pntR1);
pntR2 = parseInt($(rows[j]).find(".res").html());
jo.push(pnt1, pntR1, pntR2);
break;
}
}
}
console.log(jo);
});
});
But I understood that I'm on a wrong way. Please, help me. I really appreicate if some one could help me on this issue.
Updated after comments:
<table id="pntsRes">
<thead>
<tr>
<th>Участники</th>
<th>Баллы</th>
</tr>
</thead>
<tbody>
<tr><td class="pnt">aa</td><td class="station">AES</td><td class="res">1</td></tr><tr><td class="pnt">dd</td><td class="station">AES</td><td class="res">2</td></tr>
<tr><td class="pnt">aa</td><td class="station">Science</td><td class="res">3</td></tr>
<tr><td class="pnt">dd</td><td class="station">Science</td><td class="res">4</td></tr><tr><td class="pnt">bb</td><td class="station">Аэродром</td><td class="res">5</td></tr>
<tr><td class="pnt">ee</td><td class="station">aeroport</td><td class="res">6</td></tr></tbody>
</table>
First, I would consider breaking your solution into three functions - one to extract the data from the HTML (which is a questionable practice in itself), one to transform the data, and one to output the new table. This way, your code is much more maintainable.
function getData() {
var rows = $("tbody tr");
var data = [];
rows.each(function(idx, row){
var pnt = row.find('.pnt').html(),
station = row.find('.station').html()),
res = parseInt(row.find('.res').html());
data.push(pnt, station, res);
});
}
Then I would consider something like this for the second method
// Pass the output from getData() into processData()
function processData(data){
var groupedKeys = {};
var groupedData = data.map(function(datum){
var name = datum[0];
var value = datum[2];
groupedKeys[name] = (groupedKeys[name] || 0) + (value || 0);
});
var transformedData = [];
Object.keys(groupedKeys).forEach(function(key){
transformedData.push([key, groupedKeys[key]]);
});
return transformedData;
}
The last method of course would need to be implemented by yourself, there's a ton that could be improved here, but it could be a good start.
I used an associative array (which is just an object in JavaScript) shown below:
http://jsfiddle.net/a5k6w300/
Changes I made:
var jo = [];
changed to an object instead of an array
var jo = {};
I also added the if(isNaN(object[key]) inside the inner loop in order to make sure that these didn't show as NaN as I continued adding them together.
$(document).ready(function () {
$("body").click(function () {
var rows = $("tbody tr");
var jo = {};
console.log(rows);
for (var i = 0; i < rows.length; i++) {
for (var j = 1; j <= rows.length; j++) {
var pnt1 = $(rows[i]).find(".pnt").html();
var stations1 = $(rows[i]).find(".station").html();
var pntR1 = $(rows[i]).find(".res").html();
if (pnt1 == $(rows[j]).find(".pnt").html()) {
pntR1 = parseInt(pntR1);
pntR2 = parseInt($(rows[j]).find(".res").html());
if(isNaN(jo[pnt1])){
jo[pnt1] = 0;
}
jo[pnt1] += pntR1;
break;
}
}
}
console.log(jo);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="pntsRes">
<thead>
<tr>
<th>Участники</th>
<th>Баллы</th>
</tr>
</thead>
<tbody>
<tr>
<td class="pnt">aa</td>
<td class="station">AES</td>
<td class="res">1</td>
</tr>
<tr>
<td class="pnt">dd</td>
<td class="station">AES</td>
<td class="res">2</td>
</tr>
<tr>
<td class="pnt">aa</td>
<td class="station">Science</td>
<td class="res">3</td>
</tr>
<tr>
<td class="pnt">dd</td>
<td class="station">Science</td>
<td class="res">4</td>
</tr>
<tr>
<td class="pnt">bb</td>
<td class="station">Аэродром</td>
<td class="res">5</td>
</tr>
<tr>
<td class="pnt">ee</td>
<td class="station">aeroport</td>
<td class="res">6</td>
</tr>
</tbody>
</table>

jQuery add dynamically cell to a static cell into table

I want to create static/dynamic table. All cell <th> and the first two columns <td> of row are static. Content others cells I want to create dynamically using jQuery script.
I do not know how I start. Data to cell I have saved at JSON format (array) as:
{
"EX1":[["1","8","16","24"]],
"EX2":[["0","100200","109f","ffffffff"]]
}
HTML:
<table id="personDataTable" style="border: 1px #e3ffg3 solid; text-align: center;">
<tr class="bg02">
<th colspan="2">Name</th>
<th width="100px">Sensor 1</th>
<th width="100px">Sensor 2</th>
<th width="100px">Sensor 3</th>
<th width="100px">Sensor 4</th>
</tr>
<tr id="row1">
<td class="bg02">A</td>
<td class="bg02">Out64H</td>
<td>element[index]</td>
<td>element[index+1]</td>
<td>element[index+2]</td>
<td>element[index+3]</td>
</tr>
<tr id="row2">
<td class="bg02">R</td>
<td class="bg02">In128Birh</td>
<td>element[index]</td>
<td>element[index+1]</td>
<td>element[index+2]</td>
<td>element[index+3]</td>
</tr>
</table>
Static text in the every <tr> is necassary because text is not in json file.
Can ask for help with create javascript script?
Thanks very much
See this jsfiddle: http://jsfiddle.net/9zr6z70g/3/
The jQuery code is this way:
var data = {
"EX1":[["1","8","16","24"]],
"EX2":[["0","100200","109f","ffffffff"]]
};
var data1 = data.EX1[0];
var data2 = data.EX2[0];
$(document).ready(function(){
var row1cells = $("#row1 td");
var row2cells = $("#row2 td");
for (var index=0; index<4; index++) {
$(row1cells[index+2]).html(data1[index]);
$(row2cells[index+2]).html(data2[index]);
}
});
For multiple EX data, do it this way:
var exCount = 2;
var data = {
"EX1":[["1","8","16","24"]],
"EX2":[["0","100200","109f","ffffffff"]]
};
$(document).ready(function(){
for (var index=1; index<=exCount; index++) {
var cells = $("#row"+index+" td");
var values = data["EX"+index][0];
for (var jndex=0; jndex<4; jndex++) {
$(cells[jndex+2]).html(values[jndex]);
$(cells[jndex+2]).html(values[jndex]);
}
}
});
More details for multiple EX, see jsfiddle: http://jsfiddle.net/9zr6z70g/7/
This code is suitable for me, but variable EX are more than one hundred.
var data = {
"EX1":[["1","8","16","24"]],
"EX2":[["0","100200","109f","ffffffff"]]
};
var data1 = data.EX1[0];
var data2 = data.EX2[0];
$(document).ready(function(){
var row1cells = $("#row1 td");
var row2cells = $("#row2 td");
for (var index=0; index<4; index++) {
$(row1cells[index+2]).html(data1[index]);
$(row2cells[index+2]).html(data2[index]);
}
});
I tried modify the code using for loop following. This solution do not work correctly.
var data = {
"EX1":[["1","8","16","24"]],
"EX2":[["0","100200","109f","ffffffff"]]
};
var data1 = data.EX1[0];
var data2 = data.EX2[0];
$(document).ready(function(){
for (j=1; j<4; j++) {
var pom = "row"+[j]+"cells";
var pom2 = "#row"+[j]+" td";
var pom3 = "$"+'("'+pom2+'")';
for (var index=0; index<4; index++) {
$(pom3+[index+2]).html(data[j][index]);
}
}
});
Can ask for help with modify? Thanks

How to delete two tr elements?

I have a html table like this:
<table>
<tr id='first'>
<td>text</td>
</tr>
<tr>
<td>text</td>
</tr>
<tr>
<td>text</td>
</tr>
</table>
I want to remove 2 tr elements at once something like this:
<script>
var tr = document.getElementById('first'),
table = document.getElementsByTagName('table')[0],
i=0;
do {
tr = table.tbody.removeChild(tr);
} while ((tr = tr.nextSibling(tr)) && i++<2);
</script>
But after first iteration table.removeChild(tr) returns null, so I can't get tr.nextSibling(tr).
Please help me.
You should temporary save a reference to the next row, as shwn below. Also, to select the tbody, you have to use tBodies[0].
var nextrow = document.getElementById('first'),
table = document.getElementsByTagName('table')[0],
i=0, tr;
while (nextrow && i++<2) {
tr = nextrow;
nextrow = tr.nextSibling;
table.tbodies[0].removeChild(tr);
}
An alternative, universal solution:
var nextrow = document.getElementById('first'),
i=0, tr;
while (nextrow && i++<2) {
tr = nextrow;
nextrow = tr.nextSibling;
tr.parentNode.removeChild(tr);
}
Maybe you should define the next tr to remove before removing the current tr.
this works as well:
var trs = document.getElementsByTagName("tr");
for(var i = 1; i < trs.length; i++){
trs[i].parentNode.removeChild(trs[i]);
i--;
}

Convert Table to an Array

I have seen many posts about how to turn an array into a table, but not nearly as many going the other way. I'm looking to take a table like this:
<table id="dataTable">
<tr>
<th>Functional Category</th>
<th>Brand Name</th>
<th>When Obtained</th>
<th>How Obtained</th>
<th>How Often Worn</th>
<th>Where Made</th>
<th>Has a Graphic</th>
</tr>
<tr>
<td>T-Shirt</td>
<td>threadless</td>
<td>Last 3 Months</td>
<td>Purchased</td>
<td>Monthly</td>
<td>India</td>
<td>Yes</td>
</tr>
<tr>
<td>T-Shirt</td>
<td>RVCA</td>
<td>2 Years Ago</td>
<td>Purchased</td>
<td>Bi-Monthly</td>
<td>Mexico</td>
<td>Yes</td>
</tr>
</table>
Into an array like this:
var tableData = [
{
category: "T-shirt",
brandName: "threadless",
whenObtained: "Last 3 Months",
howObtained: "Purchased",
howOftenWorn: "Monthly",
whereMade: "India",
hasGraphic: "Yes"
},
{
category: "T-shirt",
brandName: "RVCA",
whenObtained: "2 Years Ago",
howObtained: "Purchased",
howOftenWorn: "Bi-Monthly",
whereMade: "Mexico",
hasGraphic: "Yes"
}
]
I am looking to use jQuery for this and was wondering what the best way to go about this is.
The following should do it!
var array = [];
var headers = [];
$('#dataTable th').each(function(index, item) {
headers[index] = $(item).html();
});
$('#dataTable tr').has('td').each(function() {
var arrayItem = {};
$('td', $(this)).each(function(index, item) {
arrayItem[headers[index]] = $(item).html();
});
array.push(arrayItem);
});
See here for jsFiddle
var table = document.getElementById( "dataTable" );
var tableArr = [];
for ( var i = 1; i < table.rows.length; i++ ) {
tableArr.push({
category: table.rows[i].cells[0].innerHTML,
brandName: table.rows[i].cells[1].innerHTML,
whenObtained: table.rows[i].cells[2].innerHTML,
howObtained: table.rows[i].cells[3].innerHTML,
howOftenWorn: table.rows[i].cells[4].innerHTML,
whereMade: table.rows[i].cells[5].innerHTML,
hasGraphic: table.rows[i].cells[6].innerHTML
});
}
So what I did is select all the tr elements and iterate over them. Next i check to make sure I am not looking at th elements. Then i use the cols array to populate the objects. This could have been simpler (2d array) but I use cols since that is what you had as your output.
var i, items, item, dataItem, data = [];
var cols = [ "category", "brandName", "whenObtained", "howObtained", "howOftenWorn",
"whereMade", "hasGraphic" ];
$("#dataTable tr").each(function() {
items = $(this).children('td');
if(items.length === 0) { // return if this tr only contains th
return;
}
dataItem = {};
for(i = 0; i < cols.length; i+=1) {
item = items.eq(i);
if(item) {
dataItem[cols[i]] = item.html();
}
}
data.push(dataItem);
});
See here for an example. I've included the relevant code below:
$(function() {
var $rows= $("#tableName tbody tr");
var data = [];
$rows.each(function(row, v) {
$(this).find("td").each(function(cell, v) {
if (typeof data[cell] === 'undefined') {
data[cell] = [];
}
data[cell][row] = $(this).text();
});
});
console.log(data);
});
There's a good tool: $(table).map, but saldly, it always return flatten array, no matter how many nested .map() is inside (you need two: one for rows and one for cells).
So let's use jQuery.map for tables and tr's and object.map() for cells, having 2nd nesting level return an array
function t2a (tabble){
return $.map($(tabble),function(el,i) {
return $.map($(el).find('tr'),function(el,i) {
return [
$(el).find('td').map(function() {
return $(this).text();
}).get()
];
});
});
}

Categories