I'm using Twitter's Bootstrap, which includes a neat hover effect for table rows, and I would like to add the clickability that users will expect when a row lights up. Is there any foolproof way to do this?
Yes I've done my research, but every solution is extremely awkward and flawed at best. Any help would be most appreciated.
The HTML
<table id="example">
<tr>
<th> </th>
<th>Name</th>
<th>Description</th>
<th>Price</th>
</tr>
<tr>
<td>Edit</td>
<td>Apples</td>
<td>Blah blah blah blah</td>
<td>10.23</td>
</tr>
<tr>
<td>Edit</td>
<td>Bananas</td>
<td>Blah blah blah blah</td>
<td>11.45</td>
</tr>
<tr>
<td>Edit</td>
<td>Oranges</td>
<td>Blah blah blah blah</td>
<td>12.56</td>
</tr>
</table>
The CSS
table#example {
border-collapse: collapse;
}
#example tr {
background-color: #eee;
border-top: 1px solid #fff;
}
#example tr:hover {
background-color: #ccc;
}
#example th {
background-color: #fff;
}
#example th, #example td {
padding: 3px 5px;
}
#example td:hover {
cursor: pointer;
}
The jQuery
$(document).ready(function() {
$('#example tr').click(function() {
var href = $(this).find("a").attr("href");
if(href) {
window.location = href;
}
});
});
I got the code HERE
Although my Google-skills are pretty awesome this is something most people should find...
http://www.electrictoolbox.com/jquey-make-entire-table-row-clickable/
But, to make it a lot easier... What about simply giving the row an id and assigning a link to that id with jQuery?
<table>
<tr id='link1'>
<td>one</td>
<td>two</td>
<td>three</td>
<td>four</td>
</tr>
<tr id='link2'>
<td>two-one</td>
<td>two-two</td>
<td>two-three</td>
<td>two-four</td>
</tr>
</table>
and
$("#link1").click(function(){
window.location = "http://stackoverflow.com/questions/12115550/html-clickable-table-rows";
});
$("#link2").click(function(){
window.location = "http:///stackoverflow.com";
});
also see this: http://jsfiddle.net/avrZG/
Without jQuery:
<table>
<tr id='link1' onclick="document.location='http://stackoverflow.com/about';">
<td>one</td>
<td>two</td>
<td>three</td>
<td>four</td>
</tr>
<tr id='link2' onclick="document.location='http://stackoverflow.com/help';">
<td>two-one</td>
<td>two-two</td>
<td>two-three</td>
<td>two-four</td>
</tr>
</table>
It is not very clear what you are trying to do but you probably want the following. Adding a tabindex to the tr elements will work in most browsers and make it possible to set focus on a row via mouse click or keyboard tab.
<table>
<tr id='link1' tabindex="100">
<td>one</td>
<td>two</td>
<td>three</td>
<td>four</td>
</tr>
<tr id='link2' tabindex="101">
<td>two-one</td>
<td>two-two</td>
<td>two-three</td>
<td>two-four</td>
</tr>
</table>
Related
I have a table generated in a backend. My task is to wrap text in each header column and add it to each body column cells by using .html() and .prepend(). It works as expected (you will see text in green).
Problem: Tables are generated in a backend, sometimes a table has 3 columns, sometimes 4 columns or more! How to write my Jquery dynamically in order to work on each table.
Please give me a hand. Thanks!
$(document).ready(function() {
var firstHead = $("table thead tr th:first-child").html();
var firstBodyCode = $("<span></span>").text(firstHead);
$('table tbody tr td:first-child').prepend(firstBodyCode);
var secondHead = $("table thead tr th:nth-child(2)").html();
var secondBodyCode = $("<span></span>").text(secondHead);
$('table tbody tr td:nth-child(2)').prepend(secondBodyCode);
});
table {
width: 100%;
border: 1px solid gray
}
span {
color: green
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
</thead>
<tbody>
<tr>
<td>January</td>
<td>$100</td>
</tr>
<tr>
<td>February</td>
<td>$80</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Sum</td>
<td>$180</td>
</tr>
</tfoot>
</table>
Use a loop to iterate over all the columns.
$(document).ready(function() {
$("table thead tr th").each(function(i) {
let bodyCode = $("<span>", {
text: $(this).text()
});
$(`table tbody tr td:nth-child(${i+1})`).prepend(bodyCode);
});
});
table {
width: 100%;
border: 1px solid gray
}
span {
color: green
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
</thead>
<tbody>
<tr>
<td>January</td>
<td>$100</td>
</tr>
<tr>
<td>February</td>
<td>$80</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Sum</td>
<td>$180</td>
</tr>
</tfoot>
</table>
I want to show an HTML table with a caption on top and a horizontal line underneath, like this:
I see two ways to implement this, but both have their respective downsides. First method is like this:
<table>
<caption><b>***** yada yada yada *****</b></caption>
<tr>
<th></th>
<th>lorem</th>
<th>ipsum</th>
<th>dolor</th>
<th>sit</th>
<th>amet</th>
</tr>
<tr>
<th>hello</th>
<td>note</td>
<td>the</td>
<td>hori</td>
<td>zontal</td>
<td>line</td>
</tr>
<tr>
<th>world</th>
<td>under</td>
<td>neath:</td>
<td>2nd</td>
<td>caption??</td>
<td>tfoot??</td>
</tr>
<tfoot>
<tr>
<td colspan="6">
<hr>
</td>
</tr>
</tfoot>
</table>
What I don't like about this is that I have to use the colspan attribute; you know, the real table is generated from data, and finding out the colspan means some extra JavaScript I have to write, if I do it like this.
The other way would be like this:
<table>
<caption><b>***** yada yada yada *****</b></caption>
<caption style="caption-side: bottom;">
<hr>
</caption>
<tr>
<th></th>
<th>lorem</th>
<th>ipsum</th>
<th>dolor</th>
<th>sit</th>
<th>amet</th>
</tr>
<tr>
<th>hello</th>
<td>note</td>
<td>the</td>
<td>hori</td>
<td>zontal</td>
<td>line</td>
</tr>
<tr>
<th>world</th>
<td>under</td>
<td>neath:</td>
<td>2nd</td>
<td>caption??</td>
<td>tfoot??</td>
</tr>
</table>
By using caption instead of tfoot, I don't have to give the colspan, which is good. But the table already has a caption, and the second caption is not compliant with the spec.
The second method is simpler and looks just fine in all browsers I tested with, so I'm preferring that - browsers seem to be able to handle lot's of 'meaningful violations' of the spec. But it doesn't feel 100% comfortable to be 'naughty' like that.
Q1: Is there a way to do this without tfoot and colspan, while being spec compliant at the same time?
Q2: do the above methods really look the same in all browsers?
Q1: Is there a way to do this without tfoot and colspan, while being
spec compliant at the same time?
Yes, do your styling with CSS. HTML is a semantic language.
Q2: do the above methods really look the same in all browsers?
In any modern, standards compliant client, yes they will.
Also, the <b> element shouldn't be used for purely stylistic purposes. It's a semantic tag to invoke emphasis. Styling should be done with CSS (shown below).
table { border-bottom: 1px solid black; }
caption { font-weight:bold; }
<table>
<caption>***** yada yada yada ****</caption>
<tr>
<th></th>
<th>lorem</th>
<th>ipsum</th>
<th>dolor</th>
<th>sit</th>
<th>amet</th>
</tr>
<tr>
<th>hello</th>
<td>note</td>
<td>the</td>
<td>hori</td>
<td>zontal</td>
<td>line</td>
</tr>
<tr>
<th>world</th>
<td>under</td>
<td>neath:</td>
<td>2nd</td>
<td>caption??</td>
<td>tfoot??</td>
</tr>
</table>
Q2: do the above methods really look the same in all browsers?
No, they don't. The hr in tfoot is a couple of pixels shorter compared to the hr within caption, the line thickness of '1px solid black' is not really the same line thickness as that of hr, and also, the vertical spacing varies by a few pixels (not many) between the 3 solutions.
But yes, I agree, you should do this with CSS, and not use hr at all.
<!DOCTYPE html>
<html>
<head>
<title>HTML colspan Attribute</title>
<style>
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
padding: 6px;
text-align: center;
}
</style>
</head>
<body>
<center>
<h1 style="color: green;">Table Design</h1>
<h2>HTML colspan & Rowspan Attribute</h2>
<table>
<tr>
<th colspan="2">Name</th>
<th colspan="2">Phone</th>
<th colspan="2">Address</th>
</tr>
<tr>
<td>First Name</td>
<td>Last Name</td>
<td>Home</td>
<td>Office</td>
<td>Present</td>
<td>Parmanent</td>
</tr>
<tr>
<td>Sayeed</td>
<td>Dev</td>
<td>017597383</td>
<td>01784763</td>
<td>BD</td>
<td>Dhaka</td>
</tr>
<tr>
<td>Sayeed</td>
<td>Dev</td>
<td colspan="2">017597383</td>
<td colspan="2">USA</td>
</tr>
<tr>
<td rowspan="2">Sayeed</td>
<td >Dev</td>
<td >017597383</td>
<td >017597383</td>
<td rowspan="2">USA</td>
<td >Dhaka</td>
</tr>
<tr>
<td>Dev</td>
<td >017597383</td>
<td >017597383</td>
<td >Dhaka</td>
</tr>
</table>
</center>
</body>
</html>
$("td:not(:has(input))").each(function ( index,element){
console.log(index);
console.log(element);
console.log($(this).text())});
td {
border: 1px solid black;
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>test1</td>
<td>test2</td>
</tr>
<tr>
<td><input type="text">test3</td>
<td><input type="text">test4</td>
</tr>
</table>
I want to select all td which contain no son node input,that is to say,what i expect is as below:
<td>test1</td>
<td>test2</td>
It's verified by jquery's select expression td:not(:has(input)) ,it works fine.
There is a famous webpage You Don't Need jQuery! and a book Beyond jQuery.
You Don't Need jQuery!
Let's try with pure javascript.
Can we fulfill the work with pure js?
There's no :has selector alternative in native JS, you could do this by looping through all the td's and check manually:
document.querySelectorAll("td").forEach(function(element) {
if (!element.querySelector('input')) {
console.log(element.innerText);
}
});
td {
border: 1px solid black;
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>test1</td>
<td>test2</td>
</tr>
<tr>
<td><input type="text">test3</td>
<td><input type="text">test4</td>
</tr>
</table>
I'm trying to hide and show table rows, the following works but breaks the layout , ie the empty <td> s lose their width is there a way to prevent this?
$(document).on("click ", "tr.grey", function(e) {
e.preventDefault();
$( "tr.sales-details" ).removeClass( "show" );
$(this).nextUntil(".grey").addClass( "show" );
});
tbody tr.sales-details, tbody tr.sales-details-title{
display: none;
&.show{
display: block;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table width="100%" class="modal-table" id="modal-table">
<thead>
<tr><th>Surgeon name</th>
<th>Country</th>
<th>Antiquity</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<tr class="grey">
<td>Alex Lloyd</td>
<td>Spain</td>
<td>new client</td>
<td>2690.58 USD</td>
</tr>
<tr class="sales-details-title">
<td></td>
<td></td>
<td><strong>Seller:</strong></td>
<td><strong>Percentage:</strong></td>
</tr>
<tr class="sales-details">
<td></td>
<td></td>
<td>Support</td>
<td>2690.58 USD</td>
</tr>
</tbody>
</table>
try using {visibility:hidden} and {visibility:visible} to hide or display the elements - this will haide content but keep its place in the DOM and not cause reflowing / reformatting that disply:none causes.
tbody tr.sales-details, tbody tr.sales-details-title{
visibility: hidden;
&.show{
visibility:visible;
}
}
I have a table of my favourite movies. I would like to display the poster of the movie when the user hovers over the name of the movie. I managed to do it for one element:
<body>
<h2> My Top 10 Movies </h2>
<table>
<tr>
<th>Rank</th>
<th>Title</th>
<th>Director</th>
<th>Year</th>
</tr>
<tr>
<td>01</td>
<td onmouseover="imageAppear()" onmouseout="imageDisappear()">Drive<img src="http://upload.wikimedia.org/wikipedia/en/1/13/Drive2011Poster.jpg" id="place-holder-1" style="zindex: 100; position: absolute; visibility: hidden;"/></td>
<td>Nicolas Winding Refn</td>
<td>2011</td>
</tr>
</table>
<script>
function imageAppear() {
document.getElementById('place-holder-1').style.visibility = "visible";}
function imageDisappear() {
document.getElementById('place-holder-1').style.visibility = "hidden";}
</script>
</body>
My question is, how can I do the same for multiple items without writing X functions for each of my movie? I tried using classes, but it does not seem to work (and even if it does, it would show all the pictures when the user hovers over any of the titles).
You can put the id of the element as a parameter of your function:
<script>
function imageAppear(id) {
document.getElementById(id).style.visibility = "visible";}
function imageDisappear(id) {
document.getElementById(id).style.visibility = "hidden";}
</script>
And in your table call it:
<table>
<tr>
<th>Rank</th>
<th>Title</th>
<th>Director</th>
<th>Year</th>
</tr>
<tr>
<td>01</td>
<td onmouseover="imageAppear('place-holder-1')" onmouseout="imageDisappear('place-holder-1')">Drive<img src="http://upload.wikimedia.org/wikipedia/en/1/13/Drive2011Poster.jpg" id="place-holder-1" style="zindex: 100; position: absolute; visibility: hidden;"/></td>
<td>Nicolas Winding Refn</td>
<td>2011</td>
</tr>
</table>
Using jQuery (since you're writting your solution with JS I think it would be ok for you)
You could something like :
<body>
<h2> My Top 10 Movies </h2>
<table>
<tr>
<th>Rank</th>
<th>Title</th>
<th>Director</th>
<th>Year</th>
</tr>
<tr>
<td>01</td>
<td>Drive<img src="http://upload.wikimedia.org/wikipedia/en/1/13/Drive2011Poster.jpg" id="place-holder-1" style="zindex: 100; position: absolute; display: none;"/></td>
<td>Nicolas Winding Refn</td>
<td>2011</td>
</tr>
</table>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
jQuery(function($){
$('tr td:nth-child(2)').mouseenter(function(){
$(this).find('img').show();
});
$('tr td:nth-child(2)').mouseleave(function(){
$(this).find('img').hide();
});
});
</script>
</body>
HTML
<table>
<tr>
<td>01</td>
<td class="imageHover"></td>
<td>Nicolas Winding Refn</td>
<td>2011</td>
</tr>
<tr>
<td>02</td>
<td class="imageHover img1"></td>
<td>Nicolas Winding Refn</td>
<td>2012</td>
</tr>
CSS
.imageHover:hover{
background:url('http://upload.wikimedia.org/wikipedia/en/1/13/Drive2011Poster.jpg');
}
.img1:hover{
background:url('https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcRhKewtNASQ-YZiNOWGXach389U4ZvUiVUyvrxLCAt0OQcR3Evh');
}
.imageHover{
width:100px;
height:100px;
}
.imageHover:before{
content:'Drive';
}
DEMO