Separate rows and columns while creating 2d dynamic table - javascript

I can't separate row and column td's as I create a 2d table with jquery..
How do I create 10 rows 10 columns 2d table:
what I have done so far:
$(document).ready(function () {
for (var i = 1; i <= 10; i++) {
$('.box').append('<td/>' + '</p>');
for (var j = 1; j <= 10; j++); {
$('.box').append('<td/>');
}
}
});
http://jsfiddle.net/VS37n/
thnx in advance!

You want a table that has 10 columns and 10 rows.
var rows = 10;
var cols = 10;
In an HTML table structure, rows come first in the hierarchy, so, create those first:
$(document).ready(function() {
var rows = 10;
var cols = 10;
var box = $('.box');
for (var r = 0; r < rows; r++) {
var tr = $('<tr>');
//Here we will append the columns to the row before appending it to the box.
box.append(tr);
}
});
The above code only makes 10 rows for us. Now we need to add 10 columns to each row:
$(document).ready(function() {
var rows = 10;
var cols = 10;
var box = $('.box');
for (var r = 0; r < rows; r++) {
var tr = $('<tr>');
for (var c = 0; c < cols; c++) {
tr.append($('<td><p></p></td>')); //Create the table cell, with a p element as in your example, and append it to the row.
}
box.append(tr);
}
});
See this FIDDLE
UPDATE
I just noticed that the jQuery selector from your post selects the <div> element with class .box. You want to add these rows and columns, however, to a <table> element, which doesn't exist. I'd suggest you add a <table> element into your HTML, or, add it with Javascript before adding the rows.
If you can add a <table> element inside of your .box div, then you would just change the following line:
var box = $('.box');
to:
var box = $('.box table:first');
If you can't change the HTML for some reason, then you can dynamically create the table before the rows and columns:
var box = $('<table>').appendTo('.box');

Is this what you're trying to do?
$(document).ready(function () {
var tdHtml = "":
var trHtml = "";
var tableHtml = "";
for(var i=1;i<=10;i++)
{
tdHtml += "<td></td>";
}
for(var j=1;j<=10;j++);
{
trHtml += ("<tr>" + tdHtml + "</tr>");
}
tableHtml = ("<table>" + trHtml + "</table>");
$('.box').innerHtml(tableHtml);
});

You had a ; after your for loop :
for (var j = 1; j <= 10; j++); {
$('.box').append('<td/>');
}
Furthermore, you are not adding <tr> elements.
See the updated fiddle

Related

Submit multiple rows jquery datatables

Im trying to do something similar to this answer: How to add multiple rows to a jQuery DataTable from a html string
The only difference is:
I need to add multiple values that i will get from a text area. The first part works perfectly.
function Gen(){
var data = require('../../cases/config.json');
var tableHeaders;
var cantidad = 0;
$.each(data.Ge[0].Data, function(i, val){
cantidad += 1
tableHeaders += "<th>" + val + "</th>";
});
// Header
$("#tabGen").empty();
$("#tabGen").append('<thead><tr>' + tableHeaders + '</tr></thead>');
var t = $('#tabGen').DataTable({
"scrollY": 200,
"scrollX": true,
rowReorder: true,
autoFill: true,
select:true,
stateSave: true
});
This second part when doing the t.row.add($(info)).draw(); it doesn't appear all the data that i need to show. So when I check out the other answer I saw that I can add a single row from an html string. So I don't know how can I add multiple values inside of the table.
$('#excel').on( 'click', function () {
var inf = $('textarea[name=excel_data]').val();
var rows = inf.split("\n");
for(var y = 0; y < rows.length; y++) {
var cells = rows[y].split("\t");
for(var x in cells) {
var info = '<td><input type="text" id="inputTextAg'+x+'" name="inputTextAg'+x+'" value="'+cells[x]+'" draggable="true" "></td>'
t.rows.add($(info)).draw();
}
}
});
}
Thanks!
Try this:
$('#excel').on( 'click', function () {
var inf = $('textarea[name=excel_data]').val();
var rows = inf.split("\n");
for(var y = 0; y < rows.length; y++) {
var cells = rows[y].split("\t");
var info = '<tr>';
for(var x in cells) {
info += '<td><input type="text" id="inputTextAg'+x+'" name="inputTextAg'+x+'" value="'+cells[x]+'" draggable="true" "></td>';
}
info += '</tr>';
t.rows.add($(info)).draw();
}
});
}

How to create rows cell loop in js

I am trying to sum a table column total.
Here is an example of only two column for test purposes. I want to calculate table column's item total using a javascript loop.
How to create the loop if we don't know how many rows and columns are inside in table? I hope you understand what I mean and also hope for your kindly suggestion.
<p><b>Student at Stanford University 2013-2014</b></p>
<table><tr><th>Faculty (Subject)</th><th>Student 2013</th><th>Student 2014</th></tr></table>
<table id="sdtable">
<tr><th>Business</th><td>12922</td><td>11420</td></tr>
<tr><th>Earth Sciences</th><td>4320</td><td>4611</td></tr>
<tr><th>Education</th><td>14560</td><td>13490</td></tr>
<tr><th>Engineering</th><td>8750</td><td>9863</td></tr>
<tr><th>Humanities & Sciences</th><td>7819</td><td>7219</td></tr>
<tr><th>Medicine</th><td>5219</td><td>4200</td></tr>
</table>
<button onclick="Calculate()">Calculate</button>
<div id="Studentf" class="Studentf"></div>
<div id="Students" class="Students"></div>
<div id="Studentt" class="Studentt"></div>
and
var ftable = document.getElementById("sdtable");
var i= 0;
var sumFirst=0;
var sumSecond=0;
var sumTotal=0;
function Calculate(){
for (i=0;i<ftable.rows.length; i++){
sumFirst=sumFirst+parseInt(ftable.rows[i].cells[1].innerHTML);
sumSecond=sumSecond+parseInt(ftable.rows[i].cells[2].innerHTML);
}
sumTotal=sumFirst+sumSecond;
document.getElementById("Studentf").innerHTML +="<b>Student in 2013 = </b>" +sumFirst;
document.getElementById("Students").innerHTML +="<b>Student in 2014 = </b>" +sumSecond;
document.getElementById("Studentt").innerHTML +="<b>Total Student = </b>" +sumTotal;
}
The key here is that you need to use cells collection to get number of columns that can change when you add new years to the table. You will also have to dynamically create elements for summary information per year.
Here is an example:
var ftable = document.getElementById("sdtable");
var i = 0;
var sumFirst = 0;
var sumSecond = 0;
var sumTotal = 0;
function Calculate() {
var rows = ftable.tBodies[0].rows,
header = ftable.tHead.rows[0],
cells = ftable.tBodies[0].rows[0].cells,
years = [];
for (var i = 0; i < rows.length; i++) {
for (var j = 1; j < cells.length; j++) {
if (!years[j]) years[j] = 0;
years[j] += parseInt(rows[i].cells[j].innerHTML);
}
}
sumTotal = years.reduce(function(prev, curr) {
return prev + curr;
}, 0);
var sum = document.getElementById("sum");
sum.innerHTML = '';
for (var j = 1; j < cells.length; j++) {
console.log(header.cells[j])
sum.insertAdjacentHTML('afterbegin', '<p><b>' + header.cells[j].innerHTML + '</b> = ' + years[j] + '</p>');
}
sum.insertAdjacentHTML('beforeend', "<b>Total Student = </b>" + sumTotal);
}
Demo: http://jsfiddle.net/x2sscpxL/1/
The table should probably look more like:
<table>
<thead>
<tr><th>Faculty (Subject)</th><th>Student 2013</th><th>Student 2014</th></tr>
</thead>
<tbody id="sdtable">
<tr><th>Business</th><td>12922</td><td>11420</td></tr>
<tr><th>Earth Sciences</th><td>4320</td><td>4611</td></tr>
<tr><th>Education</th><td>14560</td><td>13490</td></tr>
...
</tbody>
<tfoot>
<tr><th>Totals:</th><th></th><th></th></tr>
</table>
to split the header, body and footer into separate table sections. The function should then be like:
function calculate(){
// Get a reference to the tBody
var tBody = document.getElementById('sdtable');
if (!tBody) return;
var row, rows = tBody.rows;
var cell, cells;
var cellTotals = {};
// For each row in the body
for (i=0, iLen=rows.length; i<iLen; i++) {
row = rows[i];
cells = row.cells;
// Add the cells in each column, starting on the second column
// i.e. starting with cell index 1
for (var j=1, jLen=cells.length; j<jLen; j++) {
cell = cells[j];
if (j in cellTotals) {
cellTotals[j] += Number(cell.textContent || cell.innerText);
} else {
cellTotals[j] = Number(cell.innerHTML);
}
}
}
// Write the totals into the footer
var tFoot = tBody.parentNode.tFoot;
row = tFoot.rows[0];
for (var k=1; k<jLen; k++) {
row.cells[k].innerHTML = cellTotals[k];
}
}
Note that by convention, variables with a name starting with a capital letter are reserved for constructors (though constants usually are all caps).
Here is calculation of table witn n rows and n columns
Note: header cells wrapped in thead section
var ftable = document.getElementById("sdtable");
var tbody = ftable.getElementsByTagName("tbody")[0]
var columnsCount = ftable.rows[0].cells.length;
var sumTotal = [];
for(i=0; i<columnsCount;i++)
sumTotal.push(0); //here initialize with zero
function Calculate(){
for (i=0;i<tbody.rows.length; i++){
for (j=0; j<columnsCount; j++)
if (tbody.rows[i].cells[j] && tbody.rows[i].cells[j].innerHTML)
sumTotal[j] += parseInt(tbody.rows[i].cells[j].innerHTML);
}
return sumTotal;
}
sumTotal = Calculate();
tfootrow = ftable.tFoot.rows[0];
console.log(tfootrow)
for(i=0; i<sumTotal.length; i++){
tfootrow.insertCell(i).innerHTML = sumTotal[i];
}
<table id="sdtable">
<thead>
<tr>
<th>Business</th>
<th>Earth Sciences</th>
<th>Education</th>
<th>Engineering</th>
<th>Humanities & Sciences</th>
<th>Medicine</th>
</tr>
</thead>
<tbody>
<tr><td>12922</td><td>11420</td></tr>
<tr><td>4320</td><td>4611</td></tr>
<tr><td>14560</td><td>13490</td></tr>
<tr><td>8750</td><td>9863</td></tr>
<tr><td>7819</td><td>7219</td></tr>
<tr><td>5219</td><td>4200</td></tr>
<tr><td></td><td>1</td><td>2</td></tr>
</tbody>
<tfoot>
<tr></tr>
</tfoot>
</table>

How to get th when child td is clicked?

I trying to get the <th> content of the clicked <td> item.
here is the fiddle: http://jsfiddle.net/zrccq447/
the thing is, the <th> can have colspan 2 or 3, this is the point where I am stuck. this is my code
$('#table9').on('click', 'td:not(:nth-child(1))', function () {
var td = $(this);
var clicked_pos = td.index();
var x = $('#headerx9 th:nth-child(' + (clicked_pos) + ')').text();
var xy = td.text();
alert(x);
});
i want x to be the <th> of clicked td. the problem is now that if you click on some td that shares the th with other tds, i am getting the wrong th.
appreciate any help
I've updated your JsFiddle with the answer found here: Finding a colSpan Header for one of the cells or td's is Spans
JsFiddle: http://jsfiddle.net/zrccq447/4/
$('#table9').on('click', 'td:not(:nth-child(1))', function () {
var td = $(this);
var clicked_pos = td.index();
var x = $('#headerx9 th:nth-child(' + thLocator[clicked_pos] + ')').text();
var xy = td.text();
alert(x);
});
var thLocator = [], colCount = 1;
$('#table9').find('tr:first th').each(function () {
for (var i = 0; i < this.colSpan; i++) {
thLocator.push(colCount);
}
colCount++;
});
Following on from my comment you need to sum up the colspans (or default 1) for each TH until you get enough to match the column you desire:
http://jsfiddle.net/TrueBlueAussie/zrccq447/5/
$('#table9').on('click', 'td:not(:nth-child(1))', function () {
var td = $(this);
var clicked_pos = td.index();
var cols = 0;
var $table = td.closest('table');
var $ths = $table.find('tr th');
for (var i = 1; i < $ths.length; i++) {
var $th = $ths.eq(i);
cols += ~~$th.attr('colspan') || 1;
if (cols >= clicked_pos) {
var x = $th.text();
alert(x);
break;
}
}
});
I tried to keep it generic, so it finds the appropriate table and headers on the fly.
One approach is to get store a reference to each TH, in order, in an array and call the text from the array based on the location of the td.
var thholder = $('table th'),
th = [];
for(var i = 0; i < thholder.length; i++) {
var thi = $(thholder[i]);
for(var j = 0; j < (thi.attr('colspan') || 1); j++) {
th.push(thi);
}
}
$('#table9').on('click', 'td:not(:nth-child(1))', function () {
var td = $(this);
var clicked_pos = td.index();
alert(th[clicked_pos].text());
});
http://jsfiddle.net/zrccq447/3/
This code is not optimised, but shows the approach:
Loop through all the TH in the table.
If the TH does not have the attribute 'colspan', then set the attribute to a value of 1.
Create a loop for each value of colspan and save a reference to the current TH in the array.
When you click on a TD, get it's clicked position and retrieve the text of the TH at that position in the array and alert it :)

Mobile Tables - Jquery, so close, stuck on the last part

I'm trying to make a script to make my applications tables more mobile friendly.
The tables are all very similar, but very in number of row and columns, since they will be dynamically created, I'll have little control over this, so i've come up with the script below, it almost works but one function is not be passed on to each table, it stops after the first.
I suggest looking at the js fiddle: http://jsfiddle.net/e4vC3/1/
Here is the piece of the script that is not working correctly:
// Create content for new headers in mobile table by copying from original table
var HeaderArray = [];
$("table thead tr th").each(function(){
var innerArray = [];
$(this).each(function () {
innerArray.push($(this).text());
});
HeaderArray.push(innerArray); // Put content for new headers in array
});
$("table.mobile_table tbody tr").each(function(index, elem){ // Place content of array where array position and row index are the same
$(this).find("td").first().text(HeaderArray[index]);
});
Again, if you check the fiddle, you will see that the first arry stops copying objects after the first table, i cant get it to run all the way thought.
If anyone could help me with them, i would really, realy appreciate it..... http://jsfiddle.net/e4vC3/1/
The problem is that there are multiple data rows while only 1 header row. So, you will have to use mod operator like this(index has been replaced with index % TableSize):
$("table.mobile_table tbody tr").each(function(index, elem){ // Place content of array where array position and row index are the same
$(this).find("td").first().text(HeaderArray[index % TableSize]);
});
Updated your code # http://jsfiddle.net/souviiik/e4vC3/4/, see if this is helpful. For the first mobile_table I was not able to put the TH values, I hope you can modify my code :)
var TableSize = $("#ContactsPhoneTable .tableHedaer").size(); // Get # of columns
var i = 1;
var TableRowCount = $(".no_edit").size(); // Get # of body rows
$(".tableHedaer").each(function () {
$(this).attr("id", i++); // Give headers incrementing ID
});
for (var CreateTables = 1; CreateTables < TableRowCount; CreateTables++) { // Create new table class="mobile_table" for each row
$("table").after("<table class='mobile_table'></table>");
}
for(var i = 0 ; i < TableSize ; i++)
{
var tableRow = $("<tr/>").appendTo(".mobile_table");
for(var j = 0 ; j < TableRowCount ; j++)
{
var cellValue = $("#ContactsPhoneTable").find("tr").eq(i).find("td").eq(j).text();
$("<td/>", {
text: cellValue
}).appendTo(tableRow);
}
}
Updated code is at http://jsfiddle.net/souviiik/b6QZT/2/, see if this is acceptable. The code is as below.
var columnCount = $("table thead tr th").not("table.mobile_table thead tr th").size(); // Get # of columns
var rowCount = $("table tbody tr").size(); // Get # of body rows
for (var CreateTables = 0; CreateTables < rowCount; CreateTables++) { // Create new table class="mobile_table" for each row
$("<table/>", {
"class": "mobile_table"
}).appendTo(".newTableContainer");
}
var tableHedaers = [];
for(var th = 0 ; th < columnCount ; th++)
{
tableHedaers.push($(".sortable th").eq(th).text());
}
$(".mobile_table").each(function(idx){
var thisTable = $(this);
for(var i = 0 ; i < columnCount ; i++)
{
var thisTableRow = $("<tr/>").appendTo(thisTable);
for(var j = 0 ; j < 2 ; j++)
{
if(j == 0)
{
$("<td/>", {
"text": tableHedaers[i],
"style": "font-weight: 700"
}).appendTo(thisTableRow);
}
else
{
var cellValue = $("#ContactsPhoneTable").find("tr").eq(idx+1).find("td").eq(i).text();
$("<td/>", {
"text": cellValue
}).appendTo(thisTableRow);
}
}
}
});

Combine HTML Table Rows with Javascript

Is there an easy way to combine rows in an HTML table where the first column is the same? I basically have a table set up like:
<table>
<tr><td>test</td><td>12345</td><td>12345</td><tr>
<tr><td>test</td><td>12345</td><td>12345</td><tr>
<tr><td>test2</td><td>12345</td><td>12345</td><tr>
<tr><td>test</td><td>12345</td><td>12345</td><tr>
<tr><td>test2</td><td>12345</td><td>12345</td><tr>
</table>
and I want it to generate:
<table>
<tr><td>test</td><td>37035</td><td>37035</td><tr>
<tr><td>test2</td><td>24690</td><td>24690</td><tr>
</table>
using jQuery:
var map = {};
$('table tr').each(function(){
var $tr = $(this),
cells = $tr.find('td'),
mapTxt = cells.eq(0).text();
if(!map[mapTxt]){
map[mapTxt] = cells;
} else {
for(var i=1, l=cells.length; i<l; i++){
var cell = map[mapTxt].eq(i);
cell.text(parseInt(cell.text()) + parseInt(cells[i].text()));
}
$tr.remove();
}
});
this is a "dumb" script -- no error handling for cases like different number of cells, fields being non-numeric, etc. Add those if necessary.
Also, depending on how it's generated, it's better to do this server-side.
Here's a plain JavaScript version.
window.onload = function() {
var table = document.getElementById('mytable');
var tr = table.getElementsByTagName('tr');
var combined = Array();
for (i = 0; i < tr.length; i++) {
var td = tr[i].getElementsByTagName('td');
var key = td[0].innerText;
if (!combined[key]) {//if not initialised
combined[key] = Array();
for (j = 0; j < td.length - 1; j++) combined[key][j] = 0;
}
for (j = 0; j < td.length - 1; j++)
combined[key][j] += parseInt(td[j + 1].innerText);
}
while (table.hasChildNodes()) table.removeChild(table.lastChild);
var tbody = document.createElement('tbody');//needed for IE
table.appendChild(tbody);
for (var i in combined) {
tr = document.createElement('tr');
tbody.appendChild(tr);
td = document.createElement('td');
td.innerText = i;
tr.appendChild(td);
for (j = 0; j < combined[i].length; j++) {
td = document.createElement('td');
td.innerText = combined[i][j];
tr.appendChild(td);
}
}
}
This will work on tables with any number of rows and any number of cells. I suppose you want to make the sum for every column, that's what this script does.
And as cwolves mentioned, it is more logical to do this serverside. Users that have JS disabled will see the not so clean uncombined table.

Categories