Hide tbody if number of shown tr is smaller than n - javascript

I have a table who looks like following
<table>
<tbody>
<tbody class="green">
<tr>
<td>Data</td>
</tr>
</tbody>
<tbody class="blue">
<tr>
<td>Data</td>
</tr>
</tbody>
</tbody>
</table>
Is it possible, using jquery, to hide each tbody from the table if the number of the tr inside the tbody is lower than 2? I tiried this but it didin't worked. All the tr in the table got hidden.
$('.table tbody').each(function(){
if($(this).not("tr:hidden").length <2)
{
$(this).parent().find("tbody").hide();
}
});

You can use find() on this object to find the length of all tr
$(this).find("tr").length
Then you can use this to target the specific tbody element to hide.
Please Note: nested tbody (tbody inside tbody) is not valid.
Demo:
$('table tbody').each(function(){
if($(this).find("tr").length < 2){
$(this).hide();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody class="green">
<tr>
<td>First tbody Data1</td>
</tr>
</tbody>
<tbody class="blue">
<tr>
<td>Second tbody Data1</td>
</tr>
<tr>
<td>Second tbody Data2</td>
</tr>
</tbody>
</table>

You can do this with vanilla JS quite easily, just grab all the tbodys and check their children's length for the amount you want and then set display to non if it doesn't meet that threshold.
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style
const tbodys = document.querySelectorAll('tbody')
Array.from(tbodys).forEach(tbody => {
const { children } = tbody;
const threshold = children.length < 2;
tbody.style.display = threshold ? 'none' : '';
})
.blue {background-color: blue}
.green {background-color: green}
<table>
<tbody>
<tbody class="green">
<tr>
<td>Data</td>
</tr>
</tbody>
<tbody class="blue">
<tr>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
</tr>
</tbody>
</tbody>
</table>
But if you want to just Jquery
$('table tbody').each(function() {
if (this.children.length < 2) $(this).hide();
});
.blue {
background-color: blue
}
.green {
background-color: green
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tbody class="green">
<tr>
<td>Data</td>
</tr>
</tbody>
<tbody class="blue">
<tr>
<td>Data</td>
</tr>
<tr>
<td>Data</td>
</tr>
</tbody>
</tbody>
</table>

Related

How to add a class if the number of rows in a table is some number with Javascript/jQuery

I am trying to add class to div if the number of rows in the table is larger than 3.
This is my code.
$('.box').each(function () {
var $this=$(this);
if ($this.find('tbody > tr').length > 3) {
$this.find('.box').addClass('newclass');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box">
<table>
<thead>
<tr>
<th >1</th>
<th >2</th>
</tr>
</thead>
<tbody>
<tr>
<td>lorem1</td>
<td>ipsum1</td>
</tr>
<tr>
<td>lorem2</td>
<td>ipsum2</td>
</tr>
<tr>
<td>lorem3</td>
<td>ipsum3</td>
</tr>
<tr>
<td>lorem4</td>
<td>ipsum4</td>
</tr>
</tbody>
</table>
</div>
I don't see why this code not working, can somebody try to help me with this?
What I try to achieve is this:
<div class="box newclass">
Your code isn't working because this is a reference to the .box element itself. When you do a find() from there you're looking for child elements, so nothing it returned. To fix the issue just remove the find() call.
However you can make the jQuery more succinct by simply using the :has() selector to retrieve .box elements which have more than 3 tr within them:
$('.box:has(tbody > tr:eq(3))').addClass('newclass');
.newclass { color: #C00; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box">
<table>
<thead>
<tr>
<th>1</th>
<th>2</th>
</tr>
</thead>
<tbody>
<tr>
<td>lorem1</td>
<td>ipsum1</td>
</tr>
<tr>
<td>lorem2</td>
<td>ipsum2</td>
</tr>
<tr>
<td>lorem3</td>
<td>ipsum3</td>
</tr>
<tr>
<td>lorem4</td>
<td>ipsum4</td>
</tr>
</tbody>
</table>
</div>
<div class="box">
<table>
<thead>
<tr>
<th>1</th>
<th>2</th>
</tr>
</thead>
<tbody>
<tr>
<td>lorem1</td>
<td>ipsum1</td>
</tr>
</tbody>
</table>
</div>
you already set the $this to the selector. and by now using $this.find will try to find inside the element itself, so u can use $this directly or search the document itself $(document).find instead of $this.find >>> try the button to show classes list
$('.box').each(function () {
var $this=$(this);
if ($this.find('tbody > tr').length > 3) {
$(document).find('.box').addClass('newclass');
}
});
$('button').on('click', function() {
console.log($(document).find('.box').attr('class'));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box">
<table>
<thead>
<tr>
<th >1</th>
<th >2</th>
</tr>
</thead>
<tbody>
<tr>
<td>lorem1</td>
<td>ipsum1</td>
</tr>
<tr>
<td>lorem2</td>
<td>ipsum2</td>
</tr>
<tr>
<td>lorem3</td>
<td>ipsum3</td>
</tr>
<tr>
<td>lorem4</td>
<td>ipsum4</td>
</tr>
</tbody>
</table>
</div>
<button> show classes list </button>

Collapse HTML table rows by default

I'm using slight modification from this answer to make header rows collapsible in an HTML table.
I want to modify the JS snippet so that rows are collapsed rather than expanded by default (on page load/document ready). How can I do this?
Basically what I'm trying to achieve is for:
$(this).find('span').text(function(_, value){return value=='-'?'+':'-'});
$(this).nextUntil('tr.header').slideToggle(100, function(){
to be run once at page load/refresh, in addition to when header rows are clicked and toggled.
I know that I'll need to change the two tags two <span>+</span> in HTML, but am stuck on how to trigger this behavior on page load.
Javascript:
$(document).ready(function(){
$('tr.header').click(function(){
$(this).find('span').text(function(_, value){return value=='-'?'+':'-'});
$(this).nextUntil('tr.header').slideToggle(100, function(){
});
});
});
HTML:
<table border="0">
<tr class="header">
<th colspan="2">Header <span>-</span></th>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr class="header">
<th colspan="2">Header <span>-</span></th>
</tr>
<tr>
<td>date</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
</table>
CSS:
table, tr, td, th
{
border: 1px solid black;
border-collapse:collapse;
}
tr.header
{
cursor:pointer;
}
JSFiddle: https://jsfiddle.net/mkb39x0u/
Seems like you'd just do this in document.ready:
$('tr:not(.header)').hide();
Demo
Also, I'd probably toggle visibility of your plus and minus characters with a class on the row and CSS rather than cluttering up your script with that.
I just update your code with few JS changes, I hope it'll help you out. Thanks
Add below JS code before your click method
$('tr.header').nextUntil('tr.header').slideToggle(100);
$(document).ready(function(){
$('tr.header').nextUntil('tr.header').slideToggle(100);
$('tr.header').click(function(){
$(this).find('span').text(function(_, value){return value=='-'?'+':'-'});
$(this).nextUntil('tr.header').slideToggle(100, function(){
});
});
});
table, tr, td, th {
border: 1px solid black;
border-collapse:collapse;
}
tr.header {
cursor:pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="0">
<tr class="header">
<th colspan="2">Header <span>-</span></th>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr class="header">
<th colspan="2">Header <span>-</span></th>
</tr>
<tr>
<td>date</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
</table>
Another way you can achieve this functionality by using CSS
$(document).ready(function(){
$('tr.header').click(function(){
$(this).find('span').text(function(_, value){return value=='-'?'+':'-'});
$(this).nextUntil('tr.header').slideToggle(100, function(){
});
});
});
table {
border-collapse: collapse;
}
tr {
border: 1px solid #000;
display: none;
}
td + td {
border-left: 1px solid #000;
}
tr + tr {
border-top: 0;
}
tr.header {
cursor: pointer;
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="0">
<tr class="header">
<th colspan="2">Header <span>-</span></th>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr class="header">
<th colspan="2">Header <span>-</span></th>
</tr>
<tr>
<td>date</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
</table>

how to delete Parent table without removing children table content?

How to delete Parent Table with all table attribute, without removing children table using jquery/javascript
<table>
<tr>
<td>Data</td>
<td>
<table>
<tr>
<td>A</td><td>B</td>
</tr>
</table>
</td>
</tr>
</table>
Output::
<table>
<tr>
<td>A</td><td>B</td>
</tr>
</table>
You can take inner table with unwrap and change html of parent element body in this case which will delete old table.
$('body').html($('table table').unwrap())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>Data</td>
<td>
<table>
<tr>
<td>A</td>
<td>B</td>
</tr>
</table>
</td>
</tr>
</table>
Or you can take inner table, delete old one and then add inner table to parent element.
var table = $('table table').unwrap();
$('table').remove()
$('body').html(table)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>Data</td>
<td>
<table>
<tr>
<td>A</td>
<td>B</td>
</tr>
</table>
</td>
</tr>
</table>

Join table rows

I have an unfinished table structure:
<table>
<tr>
<td>ID</td>
<td>Animal</td>
<td>color</td>
<td>age</td>
</tr>
<tr>
<td rowspan="2">1</td>
</tr>
<tr>
<td rowspan="2">2</td>
</tr>
</table>
I want to append the following rows:
<table>
<tr>
<td>dog</td>
<td>brown</td>
<td>5</td>
</tr>
<tr>
<td>cat</td>
<td>white</td>
<td>3</td>
</tr>
<tr>
<td>cat</td>
<td>black</td>
<td>7</td>
</tr>
<tr>
<td>mouse</td>
<td>grey</td>
<td>2</td>
</tr>
</table>
So that the final table looks like that:
<table>
<tr>
<td>ID</td>
<td>Animal</td>
<td>color</td>
<td>age</td>
</tr>
<tr>
<td rowspan="2">1</td>
<td>dog</td>
<td>brown</td>
<td>5</td>
</tr>
<tr>
<td>cat</td>
<td>white</td>
<td>3</td>
</tr>
<tr>
<td rowspan="2">2</td>
<td>cat</td>
<td>black</td>
<td>7</td>
</tr>
<tr>
<td>mouse</td>
<td>grey</td>
<td>2</td>
</tr>
</table>
I'm creating that table dynamically, in an each-loop, so row by row.
That is my approach:
// 1st iteration
tr = "<tr><td>dog</td><td>brown</td><td>5</td></tr>";
$('table tr:eq(1)').append(tr)
// 2nd iteration
tr = "<tr><td>cat</td><td>white</td><td>3</td></tr>";
$('table tr:eq(1)').append(tr)
But the result doesn't look as intended.
Here is a fiddle.
In the first iteration you should append tr body in existing row (without parent tag).
In the second iteration you should put tr after existing row.
/* The rows to append
<tr><td>dog</td><td>brown</td><td>5</td></tr>
<tr><td>cat</td><td>white</td><td>3</td></tr>
<tr><td>cat</td><td>black</td><td>7</td></tr>
<tr><td>mouse</td><td>grey</td><td>2</td></tr>
*/
// 1st iteration
tr = "<tr><td>dog</td><td>brown</td><td>5</td></tr>";
$('table tr:eq(1)').append($(tr).html())
// 2nd iteration
tr = "<tr><td>cat</td><td>white</td><td>3</td></tr>";
$('table tr:eq(1)').after(tr)
// 3rd iteration
tr = "<tr><td>cat</td><td>black</td><td>7</td></tr>";
$('table tr:eq(3)').append($(tr).html())
// 4th iteration
tr = "<tr><td>mouse</td><td>grey</td><td>2</td></tr>";
$('table tr:eq(3)').after(tr)
table,
tr,
td {
border: 1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>ID</td>
<td>Animal</td>
<td>color</td>
<td>age</td>
</tr>
<tr>
<td rowspan="2">1</td>
</tr>
<tr>
<td rowspan="2">2</td>
</tr>
</table>
The first iteration should only include the <td>s and not a <tr> since you are adding it to an existing row. You don't want to append a <tr> to another <tr>
Use after() in the second iteration. Here you should use a <tr>
Try changing it to something like this:
// 1st iteration
tr = "<td>dog</td><td>brown</td><td>5</td>";
$('table tr:eq(1)').append(tr)
// 2nd iteration
tr = "<tr><td>cat</td><td>white</td><td>3</td></tr>";
$('table tr:eq(1)').after(tr)
You need to add row number every odd list item. That way you can add as many
item as possible to your table.
var data = [
'<tr><td>dog</td><td>brown</td><td>5</td></tr>',
'<tr><td>cat</td><td>white</td><td>3</td></tr>',
'<tr><td>cat</td><td>black</td><td>7</td></tr>',
'<tr><td>mouse</td><td>grey</td><td>2</td></tr>',
'<tr><td>dog</td><td>brown</td><td>5</td></tr>',
'<tr><td>cat</td><td>white</td><td>3</td></tr>',
'<tr><td>cat</td><td>black</td><td>7</td></tr>',
'<tr><td>mouse</td><td>grey</td><td>2</td></tr>'
];
var rowNo = 1;
for (var i = 0; i <= data.length; i++) {
var $current = $(data[i]); // Converting data to jQuery item.
// On every odd row add row Number cell to the begining of <tr> tag.
if ((i + 1) % 2 == 1) {
$current.prepend('<td rowspan="2">' + rowNo + '</td>');
rowNo++;
}
$('table').append($current);
}
table,
tr,
td {
border: 1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>ID</td>
<td>Animal</td>
<td>color</td>
<td>age</td>
</tr>
</table>
I also updated your JSFiddle. Check this out: JSFiddle

How to change the background color for tr

$("a").filter(function() {
return $(this).text().match('UP');
}).click(function() {
$('.highlight').removeClass('highlight');
var num = 1;
$('tr').eq(num).toggleClass('highlight');
});
What I want to do is that when I click on my link UP my default tr is to change back to his original color and the tr above change to the yellow color.
This is what i have right now:
Here is a sample that I hope does what you want. It have to be improved a bit, but it will do the trick :)
$(function() {
$('#up').on('click', function(){
var row = $('tr.highlight');
row.prev().addClass('highlight');
row.removeClass('highlight');
});
$('#down').on('click', function(){
var row = $('tr.highlight');
row.next().addClass('highlight');
row.removeClass('highlight');
});
});
tr:nth-child(even) {background: #CCC}
tr:nth-child(odd) {background: #FFF}
tr.highlight{
background: yellow !important;
}
tr:hover{
background: #FF0000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<h2>2: Zebra Striping Demo</h2>
<table width="200" border="1" id = "changes">
<caption>
UP
Zebra Striping Demo DN
</caption>
<thead>
<tr>
<th>January</th>
<th>February</th>
<th>March</th>
</tr>
</thead>
<tbody>
<tr class = "highlight">
<td>April</td>
<td>May</td>
<td>June</td>
</tr>
<tr>
<td>July</td>
<td>August</td>
<td>September</td>
</tr>
<tr>
<td>October</td>
<td>November</td>
<td>December</td>
</tr>
<tr>
<td>Monday</td>
<td>Tuesday</td>
<td>Wednesday</td>
</tr>
<tr>
<td>Thursday</td>
<td>Friday</td>
<td>Saturday</td>
</tr>
<tr>
<td>Spring</td>
<td>Summer</td>
<td>Fall</td>
</tr>
</tbody>
</table>
</body>

Categories

Resources