hiding/showing a table row breaks layout - javascript

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;
}
}

Related

Get prepend() dynamically

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>

How to get the first td value using jquery

I have create a table with following style. Now I want to get first td value as 1,2,3 using jQuery.
<html>
<head>
<style type='text/css'>
table {
counter-reset: rowNumber;
}
table tr {
counter-increment: rowNumber;
}
table tr td:first-child::before {
content: counter(rowNumber);
min-width: 1em;
margin-right: 0.5em;
}
</style>
</head>
<body>
<table border="1" id="MyTable">
<tr>
<td></td> <td>blue</td>
</tr>
<tr>
<td></td><td>red</td>
</tr>
<tr>
<td></td><td>black</td>
</tr>
</table>
</body>
</html>
I tried with following script but it showing row counter as text. How to get the value of first td?
<script>
$("#MyTable").find('tr').each(function (i, el) {
$(this).find('td:eq(0)').each(function () {
console.log(window.getComputedStyle(this, ':before').content);
});
});
</script>
Based on this:
Generated content does not alter the document tree. In particular, it is not fed back to the document language processor.
So if you see the html that generated, you will see all td is empty while you see counter (1,2,3) in page. this is html generated:
But this is result:
So generated content does not alter the document tree and you can't access to value of it.
There are lots of alternative you can do it:
$("#MyTable").find('tr').each(function (i, el) {
debugger
$(this).find('td:eq(0)').each(function (index, el) {
$(this).html(i+1)
console.log($(this).html());
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1" id="MyTable">
<tbody>
<tr>
<td></td>
<td>blue</td>
</tr>
<tr>
<td></td>
<td>red</td>
</tr>
<tr>
<td></td>
<td>black</td>
</tr>
</tbody>
</table>
Update
You can rest number after each modification on your table:
function setnumber() {
$('#MyTable tbody tr').each(function (i) {
$($(this).find('td')[0]).html(i + 1);
});
}
$(".delete").click(function () {
$(this).closest('tr').remove();
setnumber();
});
setnumber();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1" id="MyTable">
<tbody>
<tr>
<td></td>
<td>blue</td>
<td><span class="delete"><i class="fas fa-trash"></i>delete</span></td>
</tr>
<tr>
<td></td>
<td>red</td>
<td><span class="delete"><i class="fas fa-trash"></i>delete</span></td>
</tr>
<tr>
<td></td>
<td>black</td>
<td><span class="delete"><i class="fas fa-trash"></i>delete</span></td>
</tr>
</tbody>
</table>
Probably, you want to put 1,2,3 in TDS on DOM.
You can do like this:
$("#MyTable").find('tr').each(function (i, el) { $(el).find("td").eq(0).text(i); });
https://codesandbox.io/s/jquery-playground-forked-pmtgc?file=/src/index.js
You can use child selector to select the child of tr
jQuery("body > table > tr:nth-child(1) > td:nth-child(1)").text();

HTML/CSS/JS: Fix thead when scroll-y

How can I fix the complete thead when scrolling in Y-Direction?
It's important to note that the table width is greater than the wrapping div. So scrolling in X-Direction should also scroll the thead - so separating thead from table is not an option I guess.
Please see this fiddle
HTML
<div>
<table>
<thead>
<tr>
<th>
One
</th>
<th>
Two
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
DataOne
</td>
<td>
DatTwo
</td>
</tr>
<tr>
<td>
DataOne
</td>
<td>
DatTwo
</td>
</tr>
<tr>
<td>
DataOne
</td>
<td>
DatTwo
</td>
</tr>
<tr>
<td>
DataOne
</td>
<td>
DatTwo
</td>
</tr>
</tbody>
</table>
</div>
CSS
div {
width:80px;
height:100px;
}
table {
height:100px;
display:block;
overflow:auto;
}
A solution would be to assign a function to the scroll event handler using javascript. Use a second table, and if table1 isn't scrolled downwards, have table 2 hidden. When table1 is scrolled downwards call .show() on table2's .
Note: you will need to include JQuery in your HTML.
HTML
<table id="table-1">
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
<tbody>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
</tbody>
CSS
body { height: 1000px; }
#header-fixed {
position: fixed;
top: 0px; display:none;
background-color:white;
}
Javascript/JQuery
var tableOffset = $("#table-1").offset().top;
var $header = $("#table-1 > thead").clone();
var $fixedHeader = $("#header-fixed").append($header);
$(window).bind("scroll", function() {
var offset = $(this).scrollTop();
if (offset >= tableOffset && $fixedHeader.is(":hidden")) {
$fixedHeader.show();
}
else if (offset < tableOffset) {
$fixedHeader.hide();
}
});
Fiddle:
http://jsfiddle.net/py8b0s7v/
th{
position: sticky;
top: 0;
background-color:white;
}
Hi,
Add above Css.
Set position as sticky instead of fixed.
Fixed will "fix" the component to the top of the screen no matter where it is on the page. Sticky uses JS to calculate where it is on the page and only fix to the top when the viewport reaches it. Simply put, use sticky if you want content above the component.
This solved it for me:
document.getElementById("TableHead").addEventListener("scroll", function(){
var translate = "translate(0,"+this.scrollTop+"px)";
this.querySelector("thead").style.transform = translate;
});
Fiddle: https://jsfiddle.net/pxtokb4g/97/

How to toggle table in column on button click using jQuery's toggleClass

So, I want to be able to toggle a column in a table on a button click.
I looked into jQuery's toggle class function and figured I could give the th (table header) and td (cell in HTML table) the same class and then do a toggleClass on a button click.
Here's my table in my Dashboard.tsx file:
<table>
<thead>
<tr>
<th class="lastname">LastName</th>
<tr>
</thead>
<tbody>
{
this.1stUserInfo.map((value, index, array) => {
return(
<tr>
<td class="lastname">{value.LastName}</td>
</tr>);
}, this)
}
</tbody>
</table>
Here's my button:
<Button id="lastnamebutton" onClick={(e) => this.ShowLastName(e,this)}>Toggle Last Name</Button>
And here's my function in my JavaScript where I implement toggleClass
public ShowLastName(event, caller) {
$("#lastnamebutton").toggleClass(".lastname");
}
What am I doing wrong and/or can you think of another way I can toggle a column in my table?
The toggleClass() is invoked on the incorrect elements. Instead of #lastnamebutton, it should be invoked on .lastname.
Here is an example (BTW, this case is not related with React):
window.toggleColumn = function() {
$('.yclass').toggleClass('hide');
};
.hide {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<th>X</th>
<th class="yclass">Y</th>
<th>Z</th>
</thead>
<tbody>
<tr>
<td>42</td>
<td class="yclass">45</td>
<td>46</td>
</tr>
<tr>
<td>72</td>
<td class="yclass">62</td>
<td>22</td>
</tr>
</tbody>
</table>
<button onclick="window.toggleColumn()">
Click
</button>

Show image on mouse over for elements of a table

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

Categories