I want to call a function that prints the contents of a row every time I hover over it in a table. So far I have this:
function tablemouseover(event) {
console.log(event.target);
}
<table>
<tr onmouseover='tablemouseover(event)'>
<td>times[row]</td>
<td>locations[row][0]</td>
<td>locations[row][1]</td>
<td>AllDistances[row]m</td>
</tr>
</table>
However this just gets me <td> I am hovered over.
You can get the text of the cell by calling textContent. If you want the col/row indices, you can get them by grabbing the positional index of the element within it's row or table (body).
const getChildIndex = node =>
Array.prototype.indexOf.call(node.parentNode.children, node);
function tablemouseover(event) {
const
row = event.currentTarget,
col = event.target,
rowIndex = getChildIndex(row),
colIndex = getChildIndex(col),
allText = [...row.children].map(td => td.textContent);
console.log(`Cell (${colIndex}, ${rowIndex}): ${event.target.textContent}`);
console.log(`Row [${rowIndex}]: ${JSON.stringify(allText)}`);
}
table, th, td { border: thin solid grey; }
table { border-collapse: collapse; }
th, td { padding: 0.5em; }
.as-console-wrapper { max-height: 5.25em !important; }
<table>
<tr onmouseover='tablemouseover(event)'>
<td>times[row]</td>
<td>locations[row][0]</td>
<td>locations[row][1]</td>
<td>AllDistances[row]m</td>
</tr>
<tr onmouseover='tablemouseover(event)'>
<td>times[row]</td>
<td>locations[row][0]</td>
<td>locations[row][1]</td>
<td>AllDistances[row]m</td>
</tr>
</table>
Use closest('tr') to search up the DOM tree for the closest tr parent and then log its innerHTML like so:
function tablemouseover(event){
console.log(event.target.closest('tr').innerHTML);
}
<table>
<tr onmouseover='tablemouseover(event)'>
<td>times[row]</td>
<td>locations[row][0]</td>
<td>locations[row][1]</td>
<td>AllDistances[row]m</td>
</tr>
</table>
Use onmouseenter not onmouseover
Read what different between
function tablemouseover(event){
console.log(event.target.innerHTML);
}
<table>
<tr onmouseenter ='tablemouseover(event)'>
<td>times[row]</td>
<td>locations[row][0]</td>
<td>locations[row][1]</td>
<td>AllDistances[row]m</td>
</tr>
</table>
Related
I am dynamically adding to a transposed table. Adding the headers works; however when I add the table details (td) they appear under the table instead of to the right.
CSS to transpose table:
table { border-collapse: collapse; }
tr, tbody { display: block; float: left; }
th, td { display: block; border: 1px solid black; }
Table HTML:
<table>
<tr id="tableHeaders">
<!-- Place for exercise headers -->
</tr>
<tbody id="tableBody">
<tr>
<td>20/04/2021</td>
<td>20</td>
<td>10</td>
</tr>
<tr>
<td>27/04/2021</td>
<td>21</td>
<td>11</td>
</tr>
<!-- Place for exercise details -->
</tbody>
</table>
js to populate table:
//Populate the variable number of headers and keep count.
var numHeaders = 1;
$("<th>Date</th>").appendTo($("#tableHeaders"));
$.each(responseJson1a, function() {
$("<th>"+ this.edeType + " - " + this.edeUnit + "</th>").appendTo($("#tableHeaders"));
numHeaders++;
});
//Create an input detail cell for each header
$("<tr>").appendTo($("#tableBody"));
for(let i = 0; i < numHeaders; i++) {
$("<td><input></td>").appendTo($("#tableBody"));
}
$("</tr>").appendTo($("#tableBody"));
This is the result:
The table should look like:
This is what the table would look like when not transposed:
You are adding inputs inside tbody not inside any tr tag . So , you can just use :last this will refer tr tag which is added last and then inside this tr you can add your inputs .
Demo Code :
//just for demo..
var responseJson1a = [{
"edeType": "Speed",
"edeUnit": "km/h"
}, {
"edeType": "Speed",
"edeUnit": "km/h"
}]
var numHeaders = 1;
$("<th>Date</th>").appendTo($("#tableHeaders"));
$.each(responseJson1a, function() {
$("<th>" + this.edeType + " - " + this.edeUnit + "</th>").appendTo($("#tableHeaders"));
numHeaders++;
});
$("<tr></tr>").appendTo($("#tableBody"));//new tr..
for (let i = 0; i < numHeaders; i++) {
$("<td><input></td>").appendTo($("#tableBody tr:last")); //append to last tr which is added
}
table {
border-collapse: collapse;
}
tr,
tbody {
display: block;
float: left;
}
th,
td {
display: block;
border: 1px solid black;
padding: 2px;
height: 20px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<table>
<tbody id="tableBody">
<!--move it inside-->
<tr id="tableHeaders">
</tr>
<tr>
<td>20/04/2021</td>
<td>20</td>
<td>10</td>
</tr>
<tr>
<td>27/04/2021</td>
<td>21</td>
<td>11</td>
</tr>
<!-- Place for exercise details -->
</tbody>
</table>
function getRowIndex() {
var tble = document.getElementById("myTable");
for (var i = 0; i < tble.rows.length; i++) {
for (var j = 0; j < tble.rows[i].cells.length; j++) {
tble.rows[i].cells[j].onclick = function() {
return this.parentElement.rowIndex;
}
}
}
}
var rIndex = getRowIndex();
console.log(rIndex);
This function getRowIndex() is returning undefined when I try to print index. I want to extract the row index value in value when clicked, using javaScript.
I am assuming that you are using HTML table element. You can find row index like this:
document.getElementById('myTable').addEventListener('click', (e) => {
if (e.target.nodeName === 'TD') {
alert(e.target.parentNode.rowIndex);
}
});
table {
border-collapse: collapse;
}
td {
border: 1px solid;
padding: 10px;
cursor: pointer;
}
<table id="myTable">
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
</table>
I am using event delegation here. Instead of iterating over each child element and then bind the event. I am binding the event to parent node itself and then find the click target using event.target. This has great performance benefits as you can already see.
I have one table which is being sorted by clicking on a header field and another which isn't. The table which is working comes before the one that doesn't sort, if the order is a factor.
The first table sorts and the second doesn't.
jsfiddle
$('th').each(function(col) {
$(this).click(function() {
if ($(this).is('.asc')) {
$(this).removeClass('asc');
$(this).addClass('desc selected');
sortOrder = -1;
} else {
$(this).addClass('asc selected');
$(this).removeClass('desc');
sortOrder = 1;
}
$(this).siblings().removeClass('asc selected');
$(this).siblings().removeClass('desc selected');
var arrData = $(this).closest('table').find('tbody > tr:has(td)').get();
arrData.sort(function(a, b) {
//console.log(a, b);
var val1 = $(a).find('td').eq(col).text().toUpperCase();
var val2 = $(b).find('td').eq(col).text().toUpperCase();
if ($.isNumeric(val1) && $.isNumeric(val2))
return sortOrder == 1 ? val1 - val2 : val2 - val1;
else
return (val1 < val2) ? -sortOrder : (val1 > val2) ? sortOrder : 0;
});
//$(this).closest('tbody tr').remove()
$.each(arrData, function(index, row) {
//console.log(row);
$(this).closest('tbody').append(row);
});
});
});
table {
border: none !important;
}
table th {
border: none !important;
}
table td {
border: none;
}
table thead th {
font-weight: bold;
}
table thead tr td {
padding-right: 2em;
}
table tbody {
font-variant-numeric: tabular-nums;
font-weight: normal;
}
table th,
table td {
padding: 10px;
}
table tr:nth-child(even) td {
background-color: rgba(255, 255, 255, 0.1);
}
table thead tr th:hover {
color: rgba(0, 0, 0, 0.6);
cursor: pointer;
font-weight: bold;
}
.selected {
background-color: rgba(255, 255, 255, 0.1);
font-weight: 500;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<table id="leaderboard">
<thead>
<tr>
<th>Position</th>
<th>Name</th>
<th>Duration</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Test</td>
<td>00:15:00</td>
</tr>
<tr>
<td>2</td>
<td>Joe Bloggs</td>
<td>01:00:13</td>
</tr>
<tr>
<td>3</td>
<td>Joe Bloggs</td>
<td>03:00:00</td>
</tr>
<tr>
<td>4</td>
<td>Joe Bloggs</td>
<td>08:00:00</td>
</tr>
</tbody>
</table>
<table id="leaderboard2">
<thead>
<tr>
<th>Position</th>
<th>Name</th>
<th>Duration</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Bob</td>
<td>00:17:52</td>
</tr>
<tr>
<td>2</td>
<td>Joe Bloggs</td>
<td>00:20:35</td>
</tr>
<tr>
<td>3</td>
<td>Alice</td>
<td>23:19:18</td>
</tr>
</tbody>
</table>
The col index returned by .each is wrong for the second table...
Since that index is based on the th collection for the whole page, regardless of the table in which it is in.
So wrap your function with:
$("table").each(function(){
And then use $(this).find('th').each(function(col) {.
The rest is unchanged.
Updated Fiddle
The problem is in the th indexing when you do $('th').each(function(col)
col is index of all th in page which doesn't work well when indexing in the cell sorting
Following approach works
$('table').each(function(col) {
var sortOrder
$(this).find('th').click(function() {
var col = $(this).index()
// all same after this
Suggest you get rid of repetitive calls to $(this) by caching variables for $th, $table,$siblings etc
Note you can also append whole array without each also
DEMO
No need for extra library or plugin for this.
The problem you have is that you have two tables and you r walking all 'th's and save their number in col, so the variable col is 0, 1, 2, 3, 4, 5
in the second table you are searching for td under th which is equal to col in your case 3,4 or 5. But these doesn't exists.
You only have to normlaize your col variable. For example adding this:
arrData.sort(function(a, b) {
col = col >= 3 ? col-3 : col; // add this line
var val1 = $(a).find('td').eq(col).text().toUpperCase();
var val2 = $(b).find('td').eq(col).text().toUpperCase();
....
Fiddle updated here: https://jsfiddle.net/gyfoousf/15/
I need to write a function (or building onto code below) that will highlight a specific row in a table. It needs to always ignore the table headers so start a row count of 0 after table headers.
<style type="text/css">
#myTbl {
border: 1px solid black
}
#myTbl td, th {
border: 1px solid black
}
#myTbl tr.normal td {
color: black;
background-color: white;
}
#myTbl tr.highlighted td {
color: white;
background-color: gray;
}
</style>
<table id="myTbl">
<thead>
<tr>
<th>ID</th>
<th>CreatedDate</th>
<th>Name</th>
<th>Colour</th>
</tr>
</thead>
<tbody>
<tr>
<td>DFRF</td>
<td>05/03/2010</td>
<td>Lamp</td>
<td>Blue</td>
</tr>
Ect...
</tbody>
</table>
<script type="text/javascript">
var table = document.getElementById("myTbl");
var thead = table.getElementsByTagName("thead")[0];
var tbody = table.getElementsByTagName("tbody")[0];
tbody.onclick = function (e) {
e = e || window.event;
var td = e.target || e.srcElement;
//so must be no other elements inside the td
var row = td.parentNode;
alert('Row is ' + (row.rowIndex - 1))
if (this.lst&&this.lst!=row){
this.lst.className='';
}
row.className = row.className==="highlighted" ? "" : "highlighted";
this.lst=row;
}
thead.onclick = function (e) {
e = e || window.event;
var th = e.target || e.srcElement;
//so must be no other elements in the th
alert(th.innerHTML);
}
</script>
Something like
function goToRow('2')
To select row 2.
Need help please
You could add the count as the ID for each TR.
See below:
<table id="myTbl">
<thead>
<tr id="tr0">
<th>ID</th>
<th>CreatedDate</th>
<th>Name</th>
<th>Colour</th>
</tr>
</thead>
<tbody>
<tr id="tr1">
<td>DFRF</td>
<td>05/03/2010</td>
<td>Lamp</td>
<td>Blue</td>
</tr>
Then use this JavaScript:
function goToRow(where)
{
document.getElementById("tr"+where+"").style.color="white";
document.getElementById("tr"+where+"").style.backgroundColor="gray";
}
Hope that helps
I need a pure Javascript (no jQuery) hover effect for HTML table columns.
I found this which supposedly contains a fix for Firefox yet it still looks broken to me.
I found this which works only for the first column.
Unfortunately, my Javascript skills are amateur at best, so my attempts to modify either of these turned out to be fruitless.
Is this possible? Any suggestions would be appreciated.
Here's a column-based approach. When the mouse enters/leaves a cell, find the corresponding <col/> by index and apply/remove the desired class:
(() => {
const myTable = document.getElementById("myTable");
const cols = myTable.querySelectorAll("col");
const events = {
mouseover: e => {
const t = e.target.closest("td");
if (t) {
const cellIndex = t.cellIndex;
for (let i = 0, n = cols.length; i < n; i++) {
cols[i].classList[i === cellIndex ? "add" : "remove"]("hovered");
}
}
},
mouseout: e => {
const t = e.target;
if (t.nodeName === "TD" && !t.contains(e.relatedTarget)) {
cols[t.cellIndex].classList.remove("hovered");
}
}
};
for (let event in events) {
myTable.addEventListener(event, events[event]);
}
})();
.hovered {
background-color: #FF0000;
}
<table id="myTable" cellspacing="0">
<col />
<col />
<col />
<tbody>
<tr>
<td>Col1</td>
<td>Col2</td>
<td>Col3</td>
</tr>
<tr>
<td>Col1</td>
<td>Col2
<span>nested</span>
</td>
<td>Col3</td>
</tr>
<tr>
<td>Col1</td>
<td>Col2</td>
<td>Col3</td>
</tr>
</tbody>
</table>
See also:
Element.classList
Node.Contains()
Element.Closest()
Here are your codes (+ demo):
var HOVER_CLASS = 'hovered';
var hovered;
table.addEventListener('mouseover', function (e) {
if (e.target.tagName.toLowerCase() == 'td') {
var index = e.target.cellIndex;
hovered && hovered.forEach(function (cell) {
cell.classList.remove(HOVER_CLASS);
});
hovered = Array.prototype.map.call(
table.rows,
function (row) {
var i = index;
while (!cell && i >= 0) {
var cell = row.cells[i];
i -= 1;
}
return cell;
}
);
hovered.forEach(function (cell) {
cell.classList.add(HOVER_CLASS);
});
}
}, true);
table.addEventListener('mouseout', function (e) {
hovered && hovered.forEach(function (cell) {
cell.classList.remove(HOVER_CLASS);
});
hovered = null;
}, true);
Best method I can think of is to give each <td> a class name that identifies the column it's in. i.e. "col1, col2, etc"
Then you can use the document.getElementsByClassName("colX") function to get an array of those <td>s, loop through the array and modify the style. Warning, this may not work in older browsers that don't have a getElementsByClassName function, but there are workarounds you can find easily for that. The best of which would be to use jQuery, not sure why you're against it.
You create a class in css
.HoverTabla > tbody > tr:hover,
.HoverTabla > tbody > tr:focus {
background-color: #42C6F7;
}
and then you call it from the table in the html
<table class="table HoverTabla" id="tbl_Plan">
<thead>
<tr>
<th>Tipo de plan</th>
<th>Tiempo en días</th>
<th>Max. Usuario</th>
<th>Max. Capacidad</th>
<th>Max. Casos</th>
<th>Valor plan</th>
<th></th>
</tr>
</thead>
</table>
CSS-only answer I found after a little bit of googling: https://css-tricks.com/simple-css-row-column-highlighting/
Each cell (<td>) in the table is given some padding through pseudo elements, which is used to create the hover effect. To make sure the hover effect doesn't extend further than the table itself, an overflow: hidden is used.
The sub-title in the article summarizes it all: "The trick is using huge pseudo elements on the <td>s, hidden by the table overflow"
Try
<td onMouseOver="this.bgColor='yellow';" onMouseOut="this.bgColor='white';">
This will work, no javascript needed. So it should work even when people turn javascript off.
Jfiddle: http://jsfiddle.net/vJacZ/
Html:
<table>
<tr>
<td class="column1">
Column1
</td>
<td class="column2">
Column2
</td>
</tr>
</table>
Css:
.column1{
color:black;
}
.column1:hover{
color:red;
}
.column2{
color:black;
}
.column2:hover{
color:green;
}