So I have this table, and when I click on a td I would like to know where is that(which row and cell) without any attributes on the elements.
<table>
<tbody>
<tr>
<td>1</td>
<td>2</td> // If I click on this I would like to know tr:1 & td:2
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
</tbody>
</table>
Javascript:
// Track onclicks on all td elements
var table = document.getElementsByTagName("table")[0];
var cells = table.getElementsByTagName("td"); //
for(var i = 1; i < cells.length; i++){
// Cell Object
var cell = cells[i];
// Track with onclick
cell.onclick = function(){
// Track my location;
// example: I'm in table row 1 and I'm the 2th cell of this row
}
}
In the handler, this is the table cell, so for the cell index do this:
var cellIndex = this.cellIndex + 1; // the + 1 is to give a 1 based index
and for the row index, do this:
var rowIndex = this.parentNode.rowIndex + 1;
Example: http://jsfiddle.net/fwZTc/1/
This script block will provide you the information you desire, by adding the information as properties to the cell and then accessing them in the onclick function:
// Track onclicks on all td elements
var table = document.getElementsByTagName("table")[0];
// Get all the rows in the table
var rows = table.getElementsByTagName("tr");
for (var i = 0; i < rows.length; i++) {
//Get the cells in the given row
var cells = rows[i].getElementsByTagName("td");
for (var j = 0; j < cells.length; j++) {
// Cell Object
var cell = cells[j];
cell.rowIndex = i;
cell.positionIndex = j;
cell.totalCells = cells.length;
cell.totalRows = rows.length;
// Track with onclick
console.log(cell);
cell.onclick = function () {
alert("I am in row " + this.rowIndex + " (out of " + this.totalRows + " rows) and I am position " + this.positionIndex + " (out of " + this.totalCells + " cells)");
};
}
}
Well, When you have rowspan/colspan you can have a lot more fun, however, if the grid is regular, you can just determine your position from the index by doing:
row = Math.floor(i / rows);
column = i % columns;
Using "this" on cells table
function myFunction(x) {
var tr = x.parentNode.rowIndex;
var td = x.cellIndex;
document.getElementById("tr").innerHTML = "Row index is: " + tr;
document.getElementById("td").innerHTML = "Column index is: " + td;
}
tr, th, td {
padding: 0.6rem;
border: 1px solid black
}
table:hover {
cursor: pointer;
}
<table>
<tbody>
<tr>
<td onclick="myFunction(this)">1</td>
<td onclick="myFunction(this)">2</td>
<td onclick="myFunction(this)">3</td>
</tr>
<tr>
<td onclick="myFunction(this)">4</td>
<td onclick="myFunction(this)">5</td>
<td onclick="myFunction(this)">6</td>
</tr>
<tr>
<td onclick="myFunction(this)">7</td>
<td onclick="myFunction(this)">8</td>
<td onclick="myFunction(this)">9</td>
</tr>
</tbody>
</table>
<p id="tr"></p>
<p id="td"></p>
Related
I have a table where the user is able to add customers and when a customer is added, a unique ID is given to the row and each cell within the row.
As you can see, when you add a row, I have logged the row.id and the cell.id, however, the cell.id is supposed to be 'cell_' + rowCount + '_' + i but the rowCount in the cell does not match the one in the row.
// add customer or item
// append row to the HTML table
var rowCount = 1;
var cellCount = 0;
function appendRow(id, style) {
var table = document.getElementById(id); // table reference
length = table.length,
row = table.insertRow(table.rows.length); // append table row
row.setAttribute('id', style);
var i;
row.id = 'row' + rowCount;
rowCount++
// insert table cells to the new row
for (i = 0; i < table.rows[0].cells.length; i++) {
createCell(row.insertCell(i), i, 'cell_' + rowCount + '.' + i); // starts over when row changes
cellCount++
}
}
function createCell(cell, text, style) {
var div = document.createElement('div'), // create DIV element
txt = document.createTextNode('_'); // create text node
div.appendChild(txt); // append text node to the DIV
div.setAttribute('id', style); // set DIV class attribute
div.setAttribute('idName', style); // set DIV class attribute for IE (?!)
cell.appendChild(div); // append DIV to the table cell
console.log(row.id + ' ' + div.id);
}
table {
text-align: center;
}
td {
width: 100px;
}
tr:nth-child(even) {
background-color: #fff;
}
tr:nth-child(odd) {
background-color: #eee;
}
<button id="addCust" class="addSort" onclick="appendRow('custList')">add customer</button>
<div class="custScroll">
<table id="custListTop" contenteditable="false">
<tr>
<td style="border-top-left-radius: 5px;">Customers</td>
<td>Work #</td>
<td>Cell #</td>
<td style="border-top-right-radius: 5px;">Main Location</td>
</tr>
</table>
<table id="custList" contenteditable="true">
<tr>
<td>Someone</td>
<td>903-636-0000</td>
<td>903-626-0000</td>
<td>something</td>
</tr>
</table>
</div>
You have
row.id = 'row' + rowCount;
rowCount++
followed by
'cell_' + rowCount
You are first using rowCount on the row when it's set to 1, then setting it to 2, then using it on the cell when it's set to 2.
I have a simple HTML table that can contain 2-5 rows and 6 columns each. How can I get the value of 1 and 2 columns for each row? I would also like to display it in a output like this: Column1 Column2, Column1 Column2, Column1 Column2 would be the output if it has 3 rows.
EDIT: Created a jsfiddle to describe what Im trying to do and also the sample code where I am at so far https://jsfiddle.net/y6eoc0b4/
You can do this
var myTable = document.getElementById("myTable");
var rows = myTable.getElementsByTagName("tr");
console.log(rows);
var output = [];
for(var i = 0; i< rows.length; i++){
var cells = rows[i].getElementsByTagName("td");
output.push(cells[0].innerText+" "+cells[1].innerText)
}
document.getElementsByClassName("output")[0].innerText = output;
https://jsfiddle.net/LyswLtf8/
JSfiddle based on your comment here
//step first: select items like this
var fisrstTdArr = document.querySelectorAll(".location table tbody tr td:first-child");
var secondTdArr = document.querySelectorAll(".location table tbody tr td:nth-child(2)");
// or like this
var fisrstTdArr2 = document.querySelectorAll("#myId tbody tr td:first-child");
var secondTdArr2 = document.querySelectorAll("#myId tbody tr td:nth-child(2)");
// or even shorter if you have only one table on the page
var fisrstTdArr3 = document.querySelectorAll("td:first-child");
var secondTdArr3 = document.querySelectorAll("td:nth-child(2)");
for (var i = 0; i<fisrstTdArr.length; i++) { // than loop
console.log ('select method 1, fisrts column: ' + fisrstTdArr[i].innerText); // and use
console.log ('select method 1, second column: ' + secondTdArr[i].innerText);
console.log ('select method 2, fisrts column: ' + fisrstTdArr2[i].innerText);
console.log ('select method 2, second column: ' + secondTdArr2[i].innerText);
console.log ('select method 3, fisrts column: ' + fisrstTdArr3[i].innerText);
console.log ('select method 3, second column: ' + secondTdArr3[i].innerText);
}
<div class='location'>
<table id="myId">
<tbody>
<tr>
<td>a</td>
<td>b</td>
<td>else</td>
<td>here</td>
<td>else</td>
<td>here</td>
</tr>
<tr>
<td>c</td>
<td>d</td>
<td>else</td>
<td>here</td>
<td>else</td>
<td>here</td>
</tr>
<tr>
<td>e</td>
<td>f</td>
<td>else</td>
<td>here</td>
<td>else</td>
<td>here</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>else</td>
<td>here</td>
<td>else</td>
<td>here</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
<td>else</td>
<td>here</td>
<td>else</td>
<td>here</td>
</tr>
</tbody>
</table>
</div>
This is a fixable code that can work on a table with any number of columns and any number of rows.
var table = document.querySelector('#my-table'),
trs = table.querySelectorAll('tr'),
outputDiv = document.querySelector('#output') ,
tds = [],
i, j,
output = '';
for (i = 0; i < trs.length; i += 1) {
tds = trs[i].querySelectorAll('td');
output += "Row #" + (i + 1) + "<br>";
for (j = 0; j < tds.length; j += 1) {
output += tds[j].innerText + ' ';
}
output += '<br>-----------------<br>';
}
outputDiv.innerHTML = output;
<table border=1 id="my-table">
<tr>
<td>Row1-Column1</td>
<td>Row1-Column2</td>
<td>Row1-Column3</td>
<td>Row1-Column4</td>
<td>Row1-Column5</td>
</tr>
<tr>
<td>Row2-Column1</td>
<td>Row2-Column2</td>
<td>Row2-Column3</td>
<td>Row2-Column4</td>
<td>Row2-Column5</td>
</tr>
<tr>
<td>Row3-Column1</td>
<td>Row3-Column2</td>
<td>Row3-Column3</td>
<td>Row3-Column4</td>
<td>Row3-Column5</td>
</tr>
</table>
<br>
<span style="font-weight: bold">Desired Output:</span> "Row1-Column1 Row1-Column2, Row2-Column1 Row2-Column2, Row3-Column1 Row3-Column2"
<br>
<br>
<span>Output:</span> <div id="output"></div>
JSFiddle
I have a html table like this:
Group Amount
x 3
x 1
test 2
test 5
But I would like to have this:
Group Amount
x 3
x 1
sum x 4
test 2
test 5
sum test 7
I already can add a row at a index:
$('.mytable > tbody > tr').eq(i-1).after(html);
But how could I get the index and the sum with jquery?
This will do what you need, for all future groups, with the values in any order, but I'd strongly recommend doing all this on the server when you first get the information....
var groups = {};
// get the sums of all the groups in the table, and the index of the last row of each
$(".mytable tbody tr").each(function(i) {
var group = $(this).find("td").eq(0).text();
var value = parseInt($(this).find("td").eq(1).text(), 10);
if (groups.hasOwnProperty(group)) {
groups[group].sum += value;
}
else {
groups[group] = {
sum: value
};
}
groups[group].index = i;
});
// convert the group information into an array so it can be sorted...
var groupArray = [];
for(var group in groups) {
groups[group].name = group;
groupArray.push(groups[group]);
}
// sort the groups in reverse index order
groupArray = groupArray.sort(function(a, b) {
return b.index - a.index;
});
// parse the groups of values and add them to the table, after the final row of each group
for (var i = 0, l = groupArray.length; i < l; i++) {
$(".mytable tbody tr").eq(groupArray[i].index).after("<tr><td>Sum " + groupArray[i].name + "</td><td>" + groupArray[i].sum + "</td></tr>");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table class="mytable">
<thead>
<tr>
<th>Group</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>x</td>
<td>3</td>
</tr>
<tr>
<td>x</td>
<td>1</td>
</tr>
<tr>
<td>test</td>
<td>2</td>
</tr>
<tr>
<td>test</td>
<td>5</td>
</tr>
</tbody>
</table>
Please try this one.
var sums = [];
$("table.mytable tbody tr").each(function(index) {
var label = $(this).find("td:first-child").html();
var value = parseInt($(this).find("td:last-child").html());
if (sums.length == 0 || sums[sums.length - 1].label != label)
sums.push({
index: index,
label: label,
sum: value
});
else
sums[sums.length - 1].sum += value;
});
for (var i = 0; i < sums.length; i++)
$('table.mytable > tbody > tr').eq(sums[i].index + i).after("<tr><td>" + sums[i].label + "</td><td>" + sums[i].sum + "</td></tr>");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<table class="mytable">
<thead>
<tr>
<th>Group</th>
<th>Amount</th>
</tr>
<thead>
<tbody>
<tr>
<td>x</td>
<td>3</td>
</tr>
<tr>
<td>x</td>
<td>1</td>
</tr>
<tr>
<td>test</td>
<td>2</td>
</tr>
<tr>
<td>test</td>
<td>5</td>
</tr>
</tbody>
</table>
The row index you can use de .rowIndex property of the table row element ($tr[0].rowIndex).
The sum, you would have to iterate over the elements, if you elements are ordered by group:
var group, sum = 0;
$('table tr').each(function () {
var $tr = $(this);
if (!group)
group = $tr.children('td:first-child').text();
sum += parseFloat($tr.children('td:last-child').text());
if ($tr.next().children('td:first-child').text() !== group) {
$tr.after('<tr><td>sum of ' + group + '</td><td>' + sum + '</td></tr>');
sum = 0;
group = null;
}
});
Although you can achieve the desired result with that, I encourage you not to do this. You are strongly relying on the data and HTML structure. Your code is going to be fragile, hard to maintain and, probably, with poor performance.
I'm trying to figure out how to use javascript to add rows to a table dynamically. I tested without the table and can get the data but am stumped on populating the table.
I have a function call on a button that is supposed to populate the table. below is my code so far:
<table id="tblData" class="pure-table">
<thead>
<tr>
<th>Staff</th>
<th>Orders</th>
</tr>
</thead>
<tbody>
<!--<tr class="pure-table-odd">
<td>Jim</td>
<td>2</td>
</tr>-->
</tbody>
</table>
function getData()
{
var soData = JSON.parse(staffOrders);
var i = 0;
var c = getRowCount();
//build table
var table = document.getElementById("tblData");
while (i <= c) {
//alert(soData[i].staffName + " had " + soData[i].orders + " orders.");
//"<td>" + soData[i].staffName + "</td>"
//"<td>" + soData[i].orders + "</td>"
i++;
}
}
You need to use the DOM API for the HTML table element. It's documented at
http://www.w3schools.com/jsref/dom_obj_table.asp
Here's an example taken from http://www.w3schools.com/jsref/met_table_insertrow.asp :
// Find a <table> element with id="myTable":
var table = document.getElementById("myTable");
// Create an empty <tr> element and add it to the 1st position of the table:
var row = table.insertRow(0);
// Insert new cells (<td> elements) at the 1st and 2nd position of the "new" <tr> element:
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
// Add some text to the new cells:
cell1.innerHTML = "NEW CELL1";
cell2.innerHTML = "NEW CELL2";
function getData() {
var responseData = [{
"staffName": "Wilkerson Bowman",
"orders": 26
}, {
"staffName": "Finley Nunez",
"orders": 26
}, {
"staffName": "Katie Estrada",
"orders": 7
}];
var thead = document.querySelector('#tblData thead');
responseData.forEach(function(data) {
var row = document.createElement('tr');
row.innerHTML = '<td>' + data.staffName + '</td><td>' + data.orders + '</td>';
thead.appendChild(row);
});
}
getData();
<table id="tblData" class="pure-table">
<thead>
<tr>
<th>Staff</th>
<th>Orders</th>
</tr>
</thead>
<tbody></tbody>
</table>
try this code
window.onload = function(){
function getData() {
var soData = [{orders : 'order1', staffName : 'staffName1'}, {orders : 'order2', staffName : 'staffName2'}]
var i = 0;
var c = 2;
//build table
var table_body = document.getElementById("tblData").getElementsByTagName('tbody')[0];
while (i <= c) {
var tr = document.createElement('tr');
tr.className = "pure-table-odd"; // add class in tr
var td1 = document.createElement('td');
td1.innerHTML = soData[i].orders;
var td2 = document.createElement('td');
td2.innerHTML = soData[i].staffName;
tr.appendChild(td1);
tr.appendChild(td2);
table_body.appendChild(tr);
i++;
}
};
getData();
}
<table id="tblData" class="pure-table">
<thead>
<tr>
<th>Staff</th>
<th>Orders</th>
</tr>
</thead>
<tbody>
<!--<tr class="pure-table-odd">
<td>Jim</td>
<td>2</td>
</tr>-->
</tbody>
</table>
My rows are not getting colored properly"
Please have a look at my HTML output:
<table id="mytable" cellspacing="0" cellpadding="5">
<tbody>
<tr class="tableheader">
<th>Name</th>
<th>Code</th>
<th>Value</th>
<th>Bid</th>
<th>Offer</th>
</tr>
<tr class="rowoddcolor">
<td>Apple</td>
<td>APPL</td>
<td>111</td>
<td>112</td>
<td>110</td>
</tr>
<tr class="tablecontent">
<td>Microsoft</td>
<td>MSFT</td>
<td>78</td>
<td>70</td>
<td>75</td>
</tr>
<tr class="rowevencolor">
<td>Google</td>
<td>GOGL</td>
<td>101</td>
<td>98</td>
<td>102</td>
</tr>
<tr class="tablecontent">
<td>Nokia</td>
<td>NOK</td>
<td>10</td>
<td>8</td>
<td>9</td>
</tr>
<tr class="rowoddcolor">
<td>Samsung</td>
<td>SAMS</td>
<td>89</td>
<td>86</td>
<td>90</td>
</tr>
<tr class="tablecontent">
<td>IntelCorporation</td>
<td>INTC</td>
<td>111</td>
<td>112</td>
<td>110</td>
</tr>
</tbody>
</table>
Now only the 1st and 5th row getting colored? why not 3rd row?
updated code:
function tablerows(id){
if(document.getElementsByTagName){
var tableid = document.getElementById(id);
var rows = tableid.getElementsByClassName('tablecontent');
for(i = 0; i < rows.length; i++){
if(i % 2 == 0){
rows[i].className = "rowevencolor";
}else{
rows[i].className = "rowoddcolor";
}
}
}
}
$(document).ready(function() {
$.getJSON('table.json',function(data){
$('#mytable').empty();
var html = '';
html += '<tr class="tableheader"><th>Name</th><th>Code</th><th>Value</th><th>Bid</th><th>Offer</th></tr>';
for (var i=0, size=data.length; i<size;i++) {
html += '<tr class="tablecontent"><td class="name">'+ data[i].name+ '</td><td class="code">'+ data[i].code+ '</td><td class="value">'
+ data[i].value+ '</td><td class="bid">'
+data[i].bid+'</td><td class="offer">'+data[i].offer+'</td></tr>';
}
$('#mytable').append(html);
tablerows('mytable');
});
});
I am creating html through jquery consuming json. Table is getting created properly. Now through javascript, i am styling my alternate rows to different color and header should be in different color. This is my first question. Please see below my script:
function tablerows(id){
if(document.getElementsByTagName){
var tableid = document.getElementById(id);
var rows = tableid.getElementById("tablecontent");
for(i = 0; i < rows.length; i++){
if(i % 2 == 0){
rows[i].className = "rowevencolor";
}else{
rows[i].className = "rowoddcolor";
}
}
}
}
$(document).ready(function() {
$.getJSON('table.json',function(data){
$('#mytable').empty();
var html = '';
html += '<tr class="tableheader"><th>Name</th><th>Code</th><th>Value</th><th>Bid</th><th>Offer</th></tr>';
for (var i=0, size=data.length; i<size;i++) {
html += '<tr id="tablecontent"><td class="name">'+ data[i].name+ '</td><td class="code">'+ data[i].code+ '</td><td class="value">'
+ data[i].value+ '</td><td class="bid">'
+data[i].bid+'</td><td class="offer">'+data[i].offer+'</td></tr>';
}
$('#mytable').append(html);
});
$(function(){
tablerows('mytable');
});
});
But my rows are not getting styled. Please tell me where is the problem.
Below is css code as well:
.rowoddcolor{
background-color:#FFFFFF;
}
.rowevencolor{
background-color:#D3D3D3;
}
I believe the function "tablerows" is getting executed before the build of table. So put that code after the append method.
Example :
$(document).ready(function() {
$.getJSON('table.json',function(data){
// existing stuff
$('#mytable').append(html);
tablerows('mytable');
});
});
Also the easiest way add the color class on alternating would be :
$('#mytable tr:even').addClass("rowevencolor");
$('#mytable tr:odd').addClass("rowoddcolor");
A few things:
First, Element ID's should be unique. Do not give every tr the same id tablecontent.
After that's fixed, you can ditch the entire helper function tablerows() as it is redundant and that logic can be moved to where you are building the table, i.e.:
for (var i=0, size=data.length; i<size;i++) {
html += '<tr class="tablecontent row' + (i % 2 ? 'even' : 'odd') + 'color"><td class="name">'+ data[i].name+ '</td><td class="code">'+ data[i].code+ '</td><td class="value">'
+ data[i].value+ '</td><td class="bid">'
+ data[i].bid+'</td><td class="offer">'+data[i].offer+'</td></tr>';
}
Or simply use psuedo-selectors in your CSS as recommended by Kundan
The reason why your code is not highlighting table row #3 is because the result of getElementsByClassName is a NodeList, not an Array.
You will thus need to convert the NodeList to an Array before using the indexing operator for random access.
e.g.
var rowsList = tableid.getElementsByClassName('tablecontent');
var rows = Array.prototype.slice.call(rowsList);
for (i = 0; i < rows.length; i++)
// ...
Here is a working fiddle
However, as per Kundan's answer, it seems strange why you wouldn't use a jQuery solution, as it is much less work. jQuery fiddle here