jQuery toggle tbody - javascript

I am nesting tables within tables and want to toggle the them when you click on a <th class="folder">
$('table').each(function(){
$('th.folder', this).bind('click', function(){
$(this).closest('table').children('tbody').toggle();
});
});
Here is some typical HTML:
<table>
<thead>
<tr>
<th>Title</th>
<th class="type">Type</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<table>
<thead>
<tr>
<th class="folder" colspan="2">Deal flow</th>
</tr>
</thead>
<tbody>
<tr>
<td>item 1</td>
<td>image</td>
</tr>
<tr>
<td>item 2</td>
<td>image</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th class="folder" colspan="2">Rejected deals</th>
</tr>
</thead>
<tbody>
<tr>
<td>item 3</td>
<td>image</td>
</tr>
<tr>
<td>item 4</td>
<td>image</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
Doesn't seem to work and I can't figure out why! Any ideas?

See Working Example
Try this instead:
$('.folder').bind('click', function(){
$(this).closest('table').children('tbody').toggle();
});

Your context is wrong, try just $('th.folder');
Also, I would use live() instead of bind() since live() is faster.

Related

Nested table with data tables

I have the following nested HTML table. I am using the Datatables API to make my tables searchable. One problem I have faced is with the nested tables I'm not sure how to make the nested tables searchable? I have tried adding additional ID tags to the nested tables HTML code and adding that into the dataTables JS code call but that did not work. Any idea how to make the sub-tables searchable?
<link href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<script>
$(document).ready(function() {
$('#example').DataTable();
} );
</script>
<div class="container">
<table id="example" class="table table-striped">
<thead>
<tr>
<th>Image</th>
<th>Date</th>
<th>TC NAME</th>
<th>NS FLOW</th>
<th>SN FLOW</th>
<th>NS FLOW</th>
<th>SN FLOW</th>
<th>NS FLOW</th>
<th>SN FLOW</th>
</tr>
</thead>
<tbody>
<tr>
<td>721</td>
<td>3/15/20</td>
<td>
<table id="example1" class="table table-nostriped">
<tr>
<td>TC1</td>
</tr>
<tr>
<td>TC2</td>
</tr>
<tr>
<td>TC3</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>100</td>
</tr>
<tr>
<td>300</td>
</tr>
<tr>
<td>600</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>100</td>
</tr>
<tr>
<td>800</td>
</tr>
<tr>
<td>400</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>100</td>
</tr>
<tr>
<td>200</td>
</tr>
<tr>
<td>300</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>100</td>
</tr>
<tr>
<td>300</td>
</tr>
<tr>
<td>200</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>200</td>
</tr>
<tr>
<td>200</td>
</tr>
<tr>
<td>200</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>100</td>
</tr>
<tr>
<td>200</td>
</tr>
<tr>
<td>300</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>722</td>
<td>3/16/20</td>
<td>
<table class="table table-nostriped">
<tr>
<td>TC1</td>
</tr>
<tr>
<td>TC2</td>
</tr>
<tr>
<td>TC3</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>200</td>
</tr>
<tr>
<td>300</td>
</tr>
<tr>
<td>600</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>100</td>
</tr>
<tr>
<td>800</td>
</tr>
<tr>
<td>400</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>100</td>
</tr>
<tr>
<td>200</td>
</tr>
<tr>
<td>300</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>100</td>
</tr>
<tr>
<td>300</td>
</tr>
<tr>
<td>200</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>200</td>
</tr>
<tr>
<td>200</td>
</tr>
<tr>
<td>200</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>100</td>
</tr>
<tr>
<td>200</td>
</tr>
<tr>
<td>300</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>633</td>
<td>3/17/20</td>
<td>
<table class="table table-nostriped">
<tr>
<td>TC1</td>
</tr>
<tr>
<td>TC2</td>
</tr>
<tr>
<td>TC3</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>300</td>
</tr>
<tr>
<td>300</td>
</tr>
<tr>
<td>600</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>100</td>
</tr>
<tr>
<td>800</td>
</tr>
<tr>
<td>400</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>100</td>
</tr>
<tr>
<td>200</td>
</tr>
<tr>
<td>300</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>100</td>
</tr>
<tr>
<td>300</td>
</tr>
<tr>
<td>200</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>200</td>
</tr>
<tr>
<td>200</td>
</tr>
<tr>
<td>200</td>
</tr>
</table>
</td>
<td>
<table class="table table-nostriped">
<tr>
<td>100</td>
</tr>
<tr>
<td>200</td>
</tr>
<tr>
<td>300</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</div>
If you by "searchable" mean DataTables inside DataTables you can use the createdRow callback to initialize tables inside a <tr>'s columns.
You must have a columns section in order to compensate for the missing <thead> in the nested tables (avoiding the TypeError: col is undefined error) :
const columns = [
{ title: '' },
]
Init the nested tables in the createdRow callback:
let table = $('#example').DataTable({
createdRow: function(row) {
$(row).find('td table')
.DataTable({
columns: columns,
dom: 'tf'
})
}
})
Notice the dom section. Here only showing the table itself and the filter box. You
can remove the header with
table.dataTable td table thead {
display: none;
}
Dont add this CSS if you want sortable columns in the nested tables.
demo using the markup in question -> http://jsfiddle.net/davidkonrad/8pzkr6yn/
Update. If your concern just is to be able to search within the content of the nested tables (e.g the HTML markup scraped away) just define the relevant columns type as 'html' (https://datatables.net/reference/option/columns.type) :
let table = $('#example').DataTable({
columnDefs: [
{ targets: [2,3,4,5,6,7], type: 'html' },
],
...
})

Getting value from another column when clicking targeted column JQuery

When the user clicks on the 'Number' column I want to be able to get the 'Name' column value in the same row. So for example if I clicked on '999' I would want to be able to get David.
$('#table').on('click', 'td:nth-child(2)', function()
{
row = $(this).text();
alert(row);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border id='table'>
<thead>
<td>Name</td>
<td>Number</td>
<td>Address</td>
</thead>
<tbody>
<tr>
<td>David</td>
<td>999</td>
<td>Street 1</td>
</tr>
<tr>
<td>Bob</td>
<td>555</td>
<td>Street 3</td>
</tr>
<tr>
<td>Jessica</td>
<td>068</td>
<td>Street 5</td>
</tr>
</tbody>
</table>
You can use $(this).closest('tr').find('td:first').text() to get the closest first td and its text.
If the wanted item is inside of the tr but you dont know the place or you want it dynamically, you can add a class or id to the name td and change the code to this $(this).closest('tr').find('#WantedRowId').text()
$('#table').on('click', 'td:nth-child(2)', function() {
alert($(this).closest('tr').find('td:first').text());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border id='table'>
<thead>
<td>Name</td>
<td>Number</td>
<td>Address</td>
</thead>
<tbody>
<tr>
<td>David</td>
<td>999</td>
<td>Street 1</td>
</tr>
<tr>
<td>Bob</td>
<td>555</td>
<td>Street 3</td>
</tr>
<tr>
<td>Jessica</td>
<td>068</td>
<td>Street 5</td>
</tr>
</tbody>
</table>
You can find below a more appropriate solution that dynamically checks what is the "Name" column index and retrieves accordingly.
As such, if you insert other columns, like ID and what not, it'll still work without updating this specific logic.
$('#table').on('click', 'td:nth-child(2)', function()
{
$td = $(this);
indexCol = $td.closest('table').find('td:contains(Name)').index()
alert( $td.closest('tr').find('td').eq(indexCol).text());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border id='table'>
<thead>
<td>Name</td>
<td>Number</td>
<td>Address</td>
</thead>
<tbody>
<tr>
<td>David</td>
<td>999</td>
<td>Street 1</td>
</tr>
<tr>
<td>Bob</td>
<td>555</td>
<td>Street 3</td>
</tr>
<tr>
<td>Jessica</td>
<td>068</td>
<td>Street 5</td>
</tr>
</tbody>
</table>

jQuery table add class for the first matching tbody and add class for last matching tbody

I have my markup like this
<table class="section-table">
<thead class="found">
<tr>
<th>data 1</th>
</tr>
</thead>
<tbody>
<tr>
<td>data test</td>
</tr>
</tbody>
<tbody>
<tr>
<td>data test</td>
</tr>
</tbody>
<tbody class="found">
<tr>
<td>data test</td>
</tr>
</tbody class="found">
<tbody>
<tr>
<td>data test</td>
</tr>
</tbody>
<thead>
<tr>
<th>data 1</th>
</tr>
</thead>
<tbody>
<tr>
<td>data test</td>
</tr>
</tbody>
<tbody>
<tr>
<td>data test</td>
</tr>
</tbody>
<thead class="found">
<tr>
<th>data 1</th>
</tr>
</thead>
<tbody>
<tr>
<td>data test</td>
</tr>
</tbody>
<tbody class="found">
<tr>
<td>data test</td>
</tr>
</tbody>
<tbody>
<tr>
<td>data test</td>
</tr>
</tbody>
<tbody class="found">
<tr>
<td>data test</td>
</tr>
</tbody>
</table>
Now here you can see that in some thead there is class called found. Here in the tbody there is also some tbody has class found. Now I want in jQuery after the thead which has class found it will get the next first tbody which has class found tbody and add class first-row and the last tbody which has class found will be last-row. So basically the out put should be like
<table class="section-table">
<thead class="found">
<tr>
<th>data 1</th>
</tr>
</thead>
<tbody>
<tr>
<td>data test</td>
</tr>
</tbody>
<tbody>
<tr>
<td>data test</td>
</tr>
</tbody>
<tbody class="found first-row">
<tr>
<td>data test</td>
</tr>
</tbody class="found last-row">
<tbody>
<tr>
<td>data test</td>
</tr>
</tbody>
<thead>
<tr>
<th>data 1</th>
</tr>
</thead>
<tbody>
<tr>
<td>data test</td>
</tr>
</tbody>
<tbody>
<tr>
<td>data test</td>
</tr>
</tbody>
<thead class="found">
<tr>
<th>data 1</th>
</tr>
</thead>
<tbody>
<tr>
<td>data test</td>
</tr>
</tbody>
<tbody class="found first-row">
<tr>
<td>data test</td>
</tr>
</tbody>
<tbody>
<tr>
<td>data test</td>
</tr>
</tbody>
<tbody class="found last-row">
<tr>
<td>data test</td>
</tr>
</tbody>
</table>
I have tried this
jQuery('table.section-table').find('thead.found').each(function() {
jQuery(this).next('tbody.found').addClass('first-row');
jQuery(this).prev('tbody.found').addClass('last-row');
});
You have invalid html (a <table> can have multiple <tbody> elements, but only have one <thead> element. Because of that, you will not be able to use normal selectors such as
('tbody').siblings('tbody').first().addClass('first-row')
Instead you will need to loop each element to in the <table>
var foundFirst = false;
$('table').children('.found').each(function(index, item){
if ($(this).is('thead')) {
foundFirst = false; // reset for next set of tbody elements
} else {
if (!foundFirst) {
$(this).addClass('first-row')
foundFirst = true; // toggle
} else {
$(this).addClass('last-row')
}
}
})
Note the above assumes there will not be more that two <tbody class="found"> in the group following a <thead> element
just do this :
jQuery('table.section-table').find('thead').each(function() {
jQuery(this).next().find('tbody.found:first').addClass('first-row');
jQuery(this).next().find('tbody.found:last').addClass('last-row');
});

How to prevent clicking on header column

How to prevent click event in a header column.
HTML:
<table>
<tr>
<th class="column">Header</th>
</tr>
<tr>
<td class="column">Body 1</td>
</tr>
<tr>
<td class="column">Body 2</td>
</tr>
<tr>
<td class="column">Body 3</td>
</tr>
</table>
And my script
$('.column:not("th")').on('click', function(){
alert("test");
});
Why not:
$('td.column').on('click', function(){
alert("test");
});
Add tbody selector on you code
$('tbody .column').on('click', function() {
alert("test");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th class="column">thead</th>
</tr>
<tr>
<th class="column">thead Body 1</th>
</tr>
<tr>
<th class="column">thead Body 2</th>
</tr>
<tr>
<th class="column">thead Body 3</th>
</tr>
</thead>
<tr>
<td class="column">Header</td>
</tr>
<tr>
<td class="column">Body 1</td>
</tr>
<tr>
<td class="column">Body 2</td>
</tr>
<tr>
<td class="column">Body 3</td>
</tr>
</table>

two column html table with group

I expect next to name column is besides iphone, why my table doesn't work as expected?
<table>
<tbody>
<tr>
<td>
<tr>
<td>Name:</td>
<td>iphone</td>
</tr>
<tr>
<td>Price:</td>
<td>123</td>
</tr>
<tr>
<td>Qty</td>
<td>1</td>
</tr>
</td>
<td>next to name:</td>
<td>12345</td>
</tr>
</tbody>
</table>
You can't write tr inside of td. You can add table wrapper for the <tr>
<table border='1'>
<tbody>
<tr>
<td>
<table>
<tr>
<td>Name:</td>
<td>iphone</td>
</tr>
<tr>
<td>Price:</td>
<td>123</td>
</tr>
<tr>
<td>Qty</td>
<td>1</td>
</tr>
</table>
</td>
<td>next to name:</td>
<td>12345</td>
</tr>
</tbody>
</table>

Categories