hide/show tbody of dynamically created tables on click at thead - javascript

As you can see after you run the code, i have multiple tables, let us assume they were dynamically created with PHP. I try to hide/show the entire tbody of a table if i click at it's thead.
I could just give each table it's own id and write the jquery code for each table... but since the tables are dynamically created, i can't solve it like this.
The current version of my jquery script toggles all tbody's if i click on a thead, instead of only the thead of the table which i actually clicked.
My only idea to solve this would be to also create the jquery code dynamically (but im not sure if this will actually work), but before i try this, does someone know if there is an easier solution?
I thought about something like this:
$("this tbody").css("display","none");
So that it only selects the tbody of the thead which i actually clicked on.
var main = function()
{
$toggle = true;
$("thead").click
(
function()
{
if ($toggle)
{
$toggle = false;
$("tbody").css("display","none");
}
else
{
$toggle = true;
$("tbody").css("display","");
}
}
);
}
$(document).ready(main);
table, td {
border: 1px solid black;
}
td {
color: red;
display: block;
max-width: 120px;
white-space: nowrap;
overflow-x: auto;
background-color: blue;
}
th {
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr><th id="here1">First Table</th></tr>
</thead>
<tbody>
<tr><td>A</td></tr>
<tr><td>B</td></tr>
<tr><td>C</td></tr>
</tbody>
</table>
<table>
<thead>
<tr><th id="here1">Second Table</th></tr>
</thead>
<tbody>
<tr><td>A</td></tr>
<tr><td>B</td></tr>
<tr><td>C</td></tr>
</tbody>
</table>

First, instead of using $('tbody'), use this
Second, instead of managing variables for visibility, use toggle function
var main = function() {
$("thead").on("click", function() {
$(this).parents("table").find("tbody").toggle();
});
}
$(document).ready(main);
table,
td {
border: 1px solid black;
}
td {
color: red;
display: block;
max-width: 120px;
white-space: nowrap;
overflow-x: auto;
background-color: blue;
}
th {
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th id="here1">First Table</th>
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
</tr>
<tr>
<td>B</td>
</tr>
<tr>
<td>C</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th id="here1">Second Table</th>
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
</tr>
<tr>
<td>B</td>
</tr>
<tr>
<td>C</td>
</tr>
</tbody>
</table>

try with
$(this).parent().find('tbody').css("display","none");

you can use .next() https://api.jquery.com/next/
$(this).next("tbody").css("display","none");
or better yet use toggle https://api.jquery.com/toggle/
$(this).next("tbody").toggle();

<table class="table" id="item"style="display:none;">
<tbody style="height:0px;width:82%; display:table;"></tbody>
</table>
and using script
<script>`enter code here`
document.getElementById("item").style.display = "block";
</script>

Related

How to make expandable table cells hidden by default using jQuery/JavaScript, and click-able outside of a label?

I have this short piece of code that allows for sections of a table to be collapsed (they are like collapsible headers). This is neat, but I'm trying to make for the inverse to happen upon loading the page -- to be collapsed by default on load, but expandable when clicked. How would I go about doing this?
My present code, shown below, also features sections that only collapse when the words in the section are clicked, not when the section itself (outside of the words) are clicked. This is because I used labels to make the collapsible. Is there a way to make the entire row expandable/collapsible?
table {
width: 100%;
}
table,
tr,
th,
td {
border: 1px solid black;
border-collapse: collapse;
font-family: Arial;
}
[data-toggle="toggle"] {
display: none;
}
<table>
<thead>
<tr>
<th>Name</th>
<th>Number</th>
</tr>
</thead>
<tbody>
<tbody class="labels">
<tr>
<td colspan="2">
<label for="section">Click me!</label>
<input type="checkbox" id="section" data-toggle="toggle">
</td>
</tr>
</tbody>
<tbody class="hide">
<tr>
<td>Jack</td>
<td>100</td>
</tr>
<tr>
<td>Jill</td>
<td>300</td>
</tr>
</tbody>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$('[data-toggle="toggle"]').change(function() {
$(this).parents().next('.hide').toggle();
});
});
</script>
I'm trying to make for the inverse to happen upon loading the page --
to be collapsed by default on load, but expandable when clicked. How
would I go about doing this?
Simply add a line in your jquery above your toggle function and call on your .hide class selector and use .hide(); Then when you click it the toggle function fires.
also features sections that only collapse when the words in the
section are clicked, not when the section itself (outside of the
words) are clicked. This is because I used labels to make the
collapsible. Is there a way to make the entire row
expandable/collapsible?
Yes... Make your label display as block in your CSS file...
label {
display: block;
}
$(document).ready(function() {
$('.hide').hide();
$('[data-toggle="toggle"]').change(function() {
$(this).parents().next('.hide').toggle();
});
});
table {
width: 100%;
}
table,
tr,
th,
td {
border: 1px solid black;
border-collapse: collapse;
font-family: Arial;
}
[data-toggle="toggle"] {
display: none;
}
label {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Name</th>
<th>Number</th>
</tr>
</thead>
<tbody>
<tbody class="labels">
<tr>
<td colspan="2">
<label for="section">Click me!</label>
<input type="checkbox" id="section" data-toggle="toggle">
</td>
</tr>
</tbody>
<tbody class="hide">
<tr>
<td>Jack</td>
<td>100</td>
</tr>
<tr>
<td>Jill</td>
<td>300</td>
</tr>
</tbody>
</table>
Several things going on here...
You were hiding your checkbox, which I don't think was your intent.
Check this example, where I fixed some things: https://jsfiddle.net/za73qf65/
Fixes include:
changing the name of your "hide" class to "hidable"
defaulting that "hidable" class to be display:none
unhiding your checkbox
changing your change() event handler to a click() (optional)
attaching your event handler to a button with an ID (you can vary that)
Point is, with my changes, your example works. You might want to tweak it for a more specific need.

Hide columns except first column on expand/collapse table jQuery

I have a table with one header and columns, and I am expand/collapse based on header click by the below code:
$(this).toggleClass('expand').nextUntil('tr.header').slideToggle(100);
My table is below:
What I need is. When I click first then it should collapse and show only first column that mean the column with data1 others should hide as below:
And it should show + button and when I click again it should go back to previous state.
Please note fiddle: Fiddle
Use:
$(this).toggleClass('expand').next('tr').find('td').not('td:first')
To exclude the first td.
Use this if you have more than one row:
$(this).toggleClass('expand').nextAll('tr').find('td').not('td:first-child').slideToggle(100);
Demo
$('.header').click(function() {
$(this).toggleClass('expand').nextAll('tr').find('td').not('td:first-child').slideToggle(100);
});
table,
tr,
td,
th {
border: 1px solid black;
border-collapse: collapse;
}
tr.header {
cursor: pointer;
}
.header .sign:after {
content: "+";
display: inline-block;
}
.header.expand .sign:after {
content: "-";
}
<table border="0">
<tr class="header expand">
<th colspan="4">Header <span class="sign"></span></th>
</tr>
<tr>
<td>data1</td>
<td>data2</td>
<td>data3</td>
<td>data4</td>
</tr>
<tr>
<td>data1</td>
<td>data2</td>
<td>data3</td>
<td>data4</td>
</tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

How to get the value of 2nd td in html table on click of first td using jquery

I have a requirment where i need to get the value of 2nd td in html table on click of first column in html table. I am using jquery to achieve this.
$('.tbody').on('click','tr td:nth-child(1)', function () {
var id = $(this).closest("td").find('td:eq(1)').text();
alert(id)
});
I am using onclick function to get the value of second td as shown in the above code.But i am getting an empty alert. I dont know where i have gone wrong please help.
As per my understanding $(this).closest("td").find('td:eq(1)').text() should search for next td and .text() method should display the value within td isn'tit?
Below snippet will reflect the issue mentioned above
Please help!
Thanks in advance!
$(function () {
$('.tbody').on('click','tr td:nth-child(1)', function () {
var id = $(this).closest("td").find('td:eq(1)').text();
alert(id)
});
});
#items {
border-collapse: collapse;
width: 100%;
}
#items th {
background-color: #009999;
color: white;
border : 1px solid;
}
#items td{
border : 1px solid;
}
#items tbody{
height:200px;
overflow-y:auto;
}
#items thead,.tbody{
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<table class="table table-striped table-bordered table-hover table-condensed" style="width: 300px; " id="items">
<thead>
<tr>
<th style="width:100px;">Fee Type</th>
<th style="width:100px;">Charges per Qty</th>
<th style="width:100px;">Qty</th>
</tr>
</thead>
<tbody class="tbody">
<tr>
<td style="width:100px;">a</td>
<td style="width:100px;">b</td>
<td style="width:100px;">c</td>
</tr>
<tr>
<td style="width:100px;">d</td>
<td style="width:100px;">e</td>
<td style="width:100px;">f</td>
</tr>
</tbody>
</table>
</div>
The issue with your logic is that this refers to the td already, so closest('td') isn't going to get the element you need. It's also not the parent of the td you want to target either, so find() won't work. You need to use closest('tr') instead:
var id = $(this).closest("tr").find('td:eq(1)').text()
However, the simplest method to achieve this would be to just use next() as the td elements are siblings:
$(function() {
$('.tbody').on('click', 'tr td:nth-child(1)', function() {
var id = $(this).next().text();
console.log(id);
});
});
#items {
border-collapse: collapse;
width: 100%;
}
#items th {
background-color: #009999;
color: white;
border: 1px solid;
}
#items td {
border: 1px solid;
}
#items tbody {
height: 200px;
overflow-y: auto;
}
#items thead,
.tbody {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<table class="table table-striped table-bordered table-hover table-condensed" style="width: 300px; " id="items">
<thead>
<tr>
<th style="width:100px;">Fee Type</th>
<th style="width:100px;">Charges per Qty</th>
<th style="width:100px;">Qty</th>
</tr>
</thead>
<tbody class="tbody">
<tr>
<td style="width:100px;">a</td>
<td style="width:100px;">b</td>
<td style="width:100px;">c</td>
</tr>
<tr>
<td style="width:100px;">d</td>
<td style="width:100px;">e</td>
<td style="width:100px;">f</td>
</tr>
</tbody>
</table>
</div>
Just change the closest element (td to tr) and you will get the expected result
var id = $(this).closest("tr").find('td:eq(0)').text();

how to keep the css style after inserting a row to table by jquery

I have a css style
#mytbody > tr > th {
background-color: red;
}
And the script
function myclick() {
$("#mytbody").append("<tr><td>1</td><td>1</td>/tr>");
}
Here's my html code:
<table>
<thead>
<tr>
<td>head 1</td>
<td>head 2</td>
</tr>
</thead>
<tbody id="mytbody">
<tr>
<th>1</th>
<th>2</th>
</tr>
</tbody>
</table>
<button type="button" onclick="myclick()">button</button>
The css style disappeared for the new line that added by clicking the button.
Why the css doesn't work for the adding line and how to keep the css style for adding new line?
Thank you very much!
Here is my answer,
$("button").click(function(){
$("#mytbody").append("<tr><td>1</td><td>2</td></tr>");
});
#mytbody > tr > th {
background-color: red;
}
#mytbody > tr > td {
background-color: orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<table>
<thead>
<tr>
<td>head 1</td>
<td>head 2</td>
</tr>
</thead>
<tbody id="mytbody">
<tr>
<th>1</th>
<th>2</th>
</tr>
</tbody>
</table>
<button type="button">button</button>
I will not repeat answers from previous examples but want to mention something realated to this.
If you load complete table via ajax and forgot to put <thead> or <tbody> inside your code, you can expirience the similar problem with CSS especially if you use Bootstrap.
Many developers not use that tags inside tables and browsers fix that in DOM but when you load with ajax you will not get that tags if you not define before in file and that can break CSS also.
It is happening because your css is only for the th tag. You should add css for td as well:
#mytbody > tr > th,
#mytbody > tr > td {
background-color: red;
}
It looks like the main reason, from the information you provided, is that the CSS declaration doesn't actually correspond to the added elements. Your style declaration is only for the th tags but not the td tags.
Try something like this:
#mytbody > tr > th,
#mytbody > tr > td {
background-color: red;
}

Highlighting Table Rows

I have a dynamically built table that ends up with the below code (with example values):
<table id="patientTable" class="display" cellspacing="0" width="100%">
<thead id="TableHeader">
<tr>
<th>Value1</th>
<th>Value2</th>
<th>Value3</th>
</tr>
</thead>
<tbody id="tableContent">
<tr class="clickable row_0" onclick="selectPatient(10001);" id="10001" style="background: #FFF;">
<td class="tableContent">Value1</td>
<td class="tableContent">Value2</td>
<td class="tableContent">Value3</td>
</tr>
</tbody>
</table>
I am trying to highlight the row that is been hovered over using the below CSS:
.clickable :hover {
background-color: #CCC;
}
For some reason, this changes the background of what would be the "<td>" element, for example, will just highlight Value1, Value2 or Value3 rather than the entire row.
I have tried (to no avail) to use:
.clickable tr:hover {
background-color: #CCC;
}
.clickable:hover {
background-color: #CCC;
}
.tr:hover {
background-color: #CCC;
}
.tr :hover {
background-color: #CCC;
}
I find this unusual behaviour, as it appears to work for everyone else on every other example i've seen..
Worth Mentioning: The table is build from a complex system, that basically performs an AJAX request, which performs a PHP database query, takes the values, throws them into a JSON array, passes them back to JS, re-parses the array as JSON, loops through and creates the table, then outputs it. Could the JS be causing the issue?
The class name ".clickable", "row_#" (where # is a number) and the ID for the table row need to stay, as they are used in future functions and provide me with a way to identify each row individually.
One solution is to apply the hover on child elements td's when hover on parent tr:
.clickable:hover td {
background-color: #CCC;
}
<table id="patientTable" class="display" cellspacing="0" width="100%">
<thead id="TableHeader">
<tr>
<th>Value1</th>
<th>Value2</th>
<th>Value3</th>
</tr>
</thead>
<tbody id="tableContent">
<tr class="clickable row_0" onclick="selectPatient(10001);" id="10001" style="background: #FFF;">
<td class="tableContent">Value1</td>
<td class="tableContent">Value2</td>
<td class="tableContent">Value3</td>
</tr>
</tbody>
</table>
This works (from your question) :
.clickable:hover {
background-color: #CCC;
}
but why is there nothing happening when you hover then ?
because this rule is overwritten by the inline style: style="background: #FFF;"
Hint : NEVER write inline style (except if you REALLY need it)
if you remove style="background: #FFF;" everything will be fine.
Working example :
.clickable {
background-color: #FFF;
}
.clickable:hover {
background-color: #CCC;
}
<table id="patientTable" class="display" cellspacing="0" width="100%">
<thead id="TableHeader">
<tr>
<th>Value1</th>
<th>Value2</th>
<th>Value3</th>
</tr>
</thead>
<tbody id="tableContent">
<tr class="clickable row_0" onclick="selectPatient(10001);" id="10001">
<td class="tableContent">Value1</td>
<td class="tableContent">Value2</td>
<td class="tableContent">Value3</td>
</tr>
<tr class="clickable row_1" onclick="selectPatient(10002);" id="10002">
<td class="tableContent">Value1</td>
<td class="tableContent">Value2</td>
<td class="tableContent">Value3</td>
</tr>
</tbody>
</table>
Edit :
For more information about which CSS rule will have priority over others, see this article on MDN : https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
You can't colour table rows. Colour the table cells (th and td) instead, using the direct child selector (>).
Edit: Apollo (below) is right: Of course you can colour table rows, but if you want to colour the row with a hover, you need this (just like the answer that was given before):
tr:hover > td,
tr:hover > th {
background-color:#ccc;
}

Categories

Resources