My goal is the checkbox will get selected even clicked outside checkbox. I mean it will check that checkbox even user clicks on td class="checktd". I already tried prop('checked',true) but this not works. Any idea how to do this?
Jquery:
<script type="text/javascript">
$(".checktd").on("click", function () {
$('.checkItem').prop('checked', true);
});
</script>
Html:
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 5px;
text-align: left;
}
</style>
<table style="width:40%">
<tr>
<th>Check</th>
<th>Name</th>
<th>Telephone</th>
</tr>
<tr>
<td class="checktd"><input type="checkbox" class="checkItem"></td>
<td>Bill Gates</td>
<td>55577854</td>
</tr>
<tr>
<td class="checktd"><input type="checkbox" name="checkItem"></td>
<td>Kevin Gates</td>
<td>544444</td>
</tr>
</table>
This way you can "toggle", not only "check".
See that I included an IF inside, to check for currentTarget. That's because if you click on the checkbox itself it would "toggle" two times.
$(function () {
$(".checktd").on("click", function (e) {
if (this != e.target) { return; }
var check = $(this).find("input[type=checkbox]");
check .prop('checked', !check[0].checked);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 5px;
text-align: left;
}
</style>
<table style="width:40%">
<tr>
<th>Check</th>
<th>Name</th>
<th>Telephone</th>
</tr>
<tr>
<td class="checktd"><input type="checkbox" class="checkItem"></td>
<td>Bill Gates</td>
<td>55577854</td>
</tr>
<tr>
<td class="checktd"><input type="checkbox" name="checkItem"></td>
<td>Kevin Gates</td>
<td>544444</td>
</tr>
</table>
This should be what you tried to achieve (note that i made the tr clickable instead of the td and i made it also possible to uncheck it again ( -> toggle) because i think this is more useful):
$(".checktr").on("click", function () {
var toggle = $(this).find('input').prop('checked');
toggle = !toggle
$(this).find('input').prop('checked', toggle);
});
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 5px;
text-align: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table style="width:40%">
<tr>
<th>Check</th>
<th>Name</th>
<th>Telephone</th>
</tr>
<tr class="checktr">
<td><input type="checkbox" class="checkItem"></td>
<td>Bill Gates</td>
<td>55577854</td>
</tr>
<tr class="checktr">
<td class="checktd"><input type="checkbox" name="checkItem"></td>
<td>Kevin Gates</td>
<td>544444</td>
</tr>
</table>
$('#content').on( "click", function() {
$(this).prop('checked', 'checked');
});
This should be in document.ready of jquery. This answer is in addition #Istiaque's answer.
Use this:
Basically, get the children .checkItem from the clicked TD
$(this).children('.checkItem').prop('checked', true);
$(".checktd").on("click", function() {
$(this).children('.checkItem').prop('checked', true);
});
.checktd {
cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
}
th,
td {
padding: 5px;
text-align: left;
}
</style>
<table style="width:40%">
<tr>
<th>Check</th>
<th>Name</th>
<th>Telephone</th>
</tr>
<tr>
<td class="checktd"><input type="checkbox" class="checkItem"></td>
<td>Bill Gates</td>
<td>55577854</td>
</tr>
<tr>
<td class="checktd"><input type="checkbox" class="checkItem"></td>
<td>Kevin Gates</td>
<td>544444</td>
</tr>
</table>
Rewrote my answer completely .
2 click handlers are used here. The second one finds the click on .checkItem and then stops the click event from propagating upward to its parent i.e. .checktd. The first one finds the click on .checktd, then holds the checkbox with class checkItem in variable $cb.Then it checks whether the checkbox is checked. If checked , then it is unchecked. If not then reverse thing takes place. If the click event takes place exactly on the checkbox, then the event propagation is stopped so that the checkbox behaves as it is supposed to do without the first click handler.
N.B: Your 2nd checkbox has name="checkItem", I think you also want to use class="checkItem", right ?
$(".checktd").on("click", function (e) {
var $cb=$(this).find('.checkItem');
if($cb.prop('checked')){
$cb.prop('checked', false);
}else{
$cb.prop('checked', true);
}
});
$(".checkItem").on("click", function (e) {
e.stopPropagation();
});
Related
I have applied jQuery filters on a table with few hundreds rows and it works fine.
But I want to make few HTML links on top of table so users can click on that link to apply filter (instead of typing) for instance. List all record with city name Washington, something like that:
Desired Filtering
List all records with city name Washington
Here is the code:
$(document).ready(function() {
$("#myInput").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#myTable tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td,
th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<h2>Desired Filtering</h2>
<h3>List all records with city name Washington</h3>
<hr />
<h2>Working Filterable Table</h2>
<p>Type something in the input field to search the table for first names, last names or emails:</p>
<input id="myInput" type="text" placeholder="Search..">
<br><br>
<table>
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>City</th>
</tr>
</thead>
<tbody id="myTable">
<tr>
<td>John</td>
<td>Doe</td>
<td>john#example.com</td>
<td>New York</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>mary#mail.com</td>
<td>Washington</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#greatstuff.com</td>
<td>New York</td>
</tr>
<tr>
<td>Anja</td>
<td>Ravendale</td>
<td>a_r#test.com</td>
<td>New York</td>
</tr>
<tr>
<td>Mathew</td>
<td>Stars</td>
<td>a_z#test.com</td>
<td>Washintgon</td>
</tr>
</tbody>
</table>
so users can click on that link to apply filter (instead of typing)
You can store the filter that you want in the link using a data- attribute, then apply that to the search input using .val().
List all records with city name Washington
$(".addfilter").click(function() {
var filter = $(this).data("filter");
$("#myInput").val(filter);
$("#myInput").trigger("keyup");
return false;
});
Here I've given the link a class addfilter so that you can add new links without needing to change the code. The .click handler has return false; (or could use .preventDefault to stop the <a> from navigating away (the href='#' also stops the <a> from changing the whole page).
Updated snippet:
$("#myInput").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#myTable tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
$(".addfilter").click(function() {
var filter = $(this).data("filter");
$("#myInput").val(filter);
$("#myInput").trigger("keyup");
return false;
});
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td,
th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<h2>Desired Filtering</h2>
<h3>
List all records with city name Washington
<br/>
List all records with city name New York</h3>
<hr />
<h2>Working Filterable Table</h2>
<p>Type something in the input field to search the table for first names, last names or emails:</p>
<input id="myInput" type="text" placeholder="Search..">
<br><br>
<table>
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>City</th>
</tr>
</thead>
<tbody id="myTable">
<tr>
<td>John</td>
<td>Doe</td>
<td>john#example.com</td>
<td>New York</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>mary#mail.com</td>
<td>Washington</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#greatstuff.com</td>
<td>New York</td>
</tr>
<tr>
<td>Anja</td>
<td>Ravendale</td>
<td>a_r#test.com</td>
<td>New York</td>
</tr>
<tr>
<td>Mathew</td>
<td>Stars</td>
<td>a_z#test.com</td>
<td>Washintgon</td>
</tr>
</tbody>
</table>
For the above, in order to "apply" the filter, I've used .trigger("keyup") which calls your existing code. This is to keep the number of changes to a minimum; in practice you would want to pull this out into its own function. You also might like to use input instead of keyup as it will catch mouse-paste etc, giving something like:
function applyFilter(value) {
value = value.toLowerCase();
$("#myTable tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
}
$(".addfilter").click(function() {
var filter = $(this).data("filter");
$("#myInput").val(filter);
applyFilter(filter);
return false;
});
$("#myInput").on("input", function() {
var value = $(this).val();
applyFilter(value);
});
I am customizing this basic jQuery Data Table with Search Filter tutorial for my own use and it works great except I can't figure out how to toggle to show a specific message when the filter returns no results: https://www.coderbench.com/develop-jquery-data-table-search-filter/
Here is the script:
$(document).ready(function(){
$("#txtsearch").keyup(function(){
var value = $(this).val().toLowerCase();
$("#table tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
This works for what I need except I want to display the following text above my table when there are no row matches and all rows are toggled hidden:
<span class="warning">Your search returned no results, please modify your entry.</span>
I imagine there's some elaborate conditional statement I could make here but I'm wondering if there's a simple way to do this....as is often the case. Thanks! Here is the full sample page:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>
<script>
$(document).ready(function(){
$("#txtsearch").keyup(function(){
var value = $(this).val().toLowerCase();
$("#table tr").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
</script>
<style>
table {
font-family: arial;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #e3e3e3;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #efefef;
}
</style>
<div>
<input id="txtsearch" type="text" placeholder="Search Here..." />
<br><br>
<table>
<thead>
<tr>
<th>Movies</th>
<th>Rating</th>
</tr>
</thead>
<tbody id="table">
<tr>
<td>Spiderman Homecoming</td>
<td>9/10</td>
</tr>
<tr>
<td>Wonder Woman</td>
<td>8/10</td>
</tr>
<tr>
<td>The Guardians of Galaxy 2</td>
<td>8/10</td>
</tr>
<tr>
<td>Ant Man</td>
<td>7.5/10</td>
</tr>
</tbody>
</table>
</div>
Here's my try.
I don't use jQuery much so feel free to adapt things to a more "jQuery"-way.
const warning = document.querySelector('.warning');
const table = document.querySelector('table');
$(document).ready(function() {
$("#txtsearch").keyup(function() {
let value = $(this).val().toLowerCase();
let numberOfResults = 0;
$("#table tr").filter((index, tableRow) => {
let isAMatch = $(tableRow).text().toLowerCase().indexOf(value) > -1;
$(tableRow).toggle(isAMatch);
if (isAMatch) {
numberOfResults++;
}
});
if (numberOfResults === 0) {
warning.classList.add('show')
table.classList.add('no-results');
} else {
warning.classList.remove('show');
table.classList.remove('no-results');
}
});
});
table {
font-family: arial;
border-collapse: collapse;
width: 100%;
}
table.no-results {
display: none;
}
td,
th {
border: 1px solid #e3e3e3;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #efefef;
}
.warning {
margin-bottom: 10px;
display: none;
}
.warning.show {
display: block;
}
<div>
<span class="warning">Your search returned no results, please modify your entry.</span>
<input id="txtsearch" type="text" placeholder="Search Here..." />
<br><br>
<table>
<thead>
<tr>
<th>Movies</th>
<th>Rating</th>
</tr>
</thead>
<tbody id="table">
<tr>
<td>Spiderman Homecoming</td>
<td>9/10</td>
</tr>
<tr>
<td>Wonder Woman</td>
<td>8/10</td>
</tr>
<tr>
<td>The Guardians of Galaxy 2</td>
<td>8/10</td>
</tr>
<tr>
<td>Ant Man</td>
<td>7.5/10</td>
</tr>
</tbody>
</table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>
This question already has answers here:
How can I select an element which does not contain a certain child element?
(8 answers)
Closed 4 years ago.
I'm using jQuery to conduct some action while clicking a certain 'tr', yet within that object I would like jQuery to ignore one of the children td which contains a url.. Any ideas how can this be done?
<tr class="parent_report>
<tr class="child1">Some text</tr>
<tr class="child2">Some text</tr>
<tr class="child3"><span>Some text</span></tr>
</tr>
And the jQuery:
$(".special_report, .new_report ,.parent_report").not("span").click(function(event){
event.preventDefault();
//do some action
So I would like to ignore the jQuery when clicking the link in child3 and not doing the action configured to jQuery
Any ideas?
Thanks
You are saying that any of the classes you selected can not be a span. You are not saying what is clicked....
So you need to do the check inside of the click that the action is not an anchor
$("tr").on("click", function (evt) {
if ($(evt.target).closest("a").length) {
return true
} else {
console.log("tr was clicked");
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>foo</td>
<td>bar</td>
<td>baz</td>
<td class="child3"><span>Some text</span></td>
</tr>
</tbody>
</table>
If you do not want any click on the td, than just ignore clicks on that td
$("tr").on("click", "td:not(:has(a))", function(evt) {
console.log("tr was clicked");
})
td {
padding: 1em;
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>foo</td>
<td>bar</td>
<td>baz</td>
<td class="child3"><span>Some text</span></td>
</tr>
</tbody>
</table>
I'd move your click events to the table cells for more intuitive code.
$("td").not(':has("a")').click(function () {
console.log("tr was clicked");
});
<style>
td {
padding: 10px;
background: pink;
}
a {
background: lightgreen;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>foo</td>
<td>bar</td>
<td>baz</td>
<td class="child3"><span>Some text</span></td>
</tr>
</tbody>
</table>
I am adding click handler into one of table elements. I confirmed it on inspect -> console that this is the returns the value that I need, the address value.
document.getElementById('donut-attributes').parentNode.childNodes[10].childNodes[1].childNodes[30].innerText
//returns 123 Some Address on console log
This is the complete script on main page:
<script>
window.onload = function(){
var donutContainer = document.getElementById("donut-attributes");
donutContainer.addEventListener('click', function(e){
alert(e.target.parentNode);
address = e.target.parentNode.childNodes[10].childNodes[1].childNodes[30].innerText;
alert("donut container after");
});
}
</script>
I set up several alert() to make sure everything works. When it comes down to alert(e.target.parentNode), it shows [object HTMLTableRowElement]. However, when it comes down to alert(e.target.parentNode.childNodes[10]);, it returns undefined.
How can I fix the click handler so when I click any table element, I would get the address value stored into address? Why does it show the address on console log and it shows undefined when I used it with clickhandler?
EDIT: the table html (index.html.erb) looks something like this:
<table border=1 class="table table-condensed donut-attributes">
<tbody class="table-hover">
<tr>
<td rowspan=5>
Some_image
</td>
<tr>
<td class="center" style="vertical-align: middle">Some_name</td>
</tr>
<tr>
<td class="center" style="vertical-align: middle">Some_phone</td>
</tr>
<tr>
<td class="center" style="vertical-align: middle">Some_rating</td>
</tr>
<tr>
<td class="center" style="vertical-align: middle" id="address" >Some_address</td>
</tr>
<tr>
<td rowspan=5>
Some_image2
</td>
<tr>
<td class="center" style="vertical-align: middle">Some_name2</td>
</tr>
<tr>
<td class="center" style="vertical-align: middle">Some_phone2</td>
</tr>
<tr>
<td class="center" style="vertical-align: middle">Some_rating2</td>
</tr>
<tr>
<td class="center" style="vertical-align: middle" id="address" >Some_address2</td>
</tr>
</tr>
</tbody>
How can I hover on any element on a table row, click it, and get the corresponding address? (i.e. if I hover and click on the second row, on any column in the second row, I need it to return some_address2)
Duplicate values for the id attribute are not allowed in HTML, so you should remove that attribute from the td with id="address", since it gets repeated.
To identify the "last" row in the group, you could reason that this row has a row index (zero-based) of 4, plus a multiple of 5. Or in other words, it is 4 modulo 5. Once you know the row index of the row that is being clicked in, it is not so hard to find the next row that has such an index:
window.addEventListener('DOMContentLoaded', function(){
var donutContainer = document.getElementById("donut-attributes");
donutContainer.addEventListener('click', function(e){
// Get the clicked element
var el = e.target;
// Find row that contains (or is) the clicked element
while (el.tagName !== 'TR') {
if (el === this) return; // give up
el = el.parentNode;
}
// Get last row within group of rows
el = this.rows[el.rowIndex - el.rowIndex % 5 + 4];
// Get its text
address = el.cells[0].textContent;
alert(address);
});
});
table, td {border: 1px solid}
<table id="donut-attributes" class="table table-condensed">
<tbody class="table-hover">
<tr>
<td rowspan=5>[image 1]</td>
</tr>
<tr>
<td class="center" style="vertical-align: middle">name1</td>
</tr>
<tr>
<td class="center" style="vertical-align: middle">phone1</td>
</tr>
<tr>
<td class="center" style="vertical-align: middle">rating1</td>
</tr>
<tr>
<td class="center" style="vertical-align: middle">address1</td>
</tr>
<tr>
<td rowspan=5>[image 2]</td>
</tr>
<tr>
<td class="center" style="vertical-align: middle">name2</td>
</tr>
<tr>
<td class="center" style="vertical-align: middle">phone2</td>
</tr>
<tr>
<td class="center" style="vertical-align: middle">rating2</td>
</tr>
<tr>
<td class="center" style="vertical-align: middle">address2</td>
</tr>
</table>
Note that if you have a special header row in your table, or other rows that do not follow the multiple-of-five pattern, the formula has to be adapted accordingly.
UPDATE
Updated so now it does exactly what OP needed, so if a <tbody> is clicked, we will get the text of the td.addressthat resides within it. In the source is a "lynchpin" comment added to alter the extractData() function so that it'll collect the text of whatever is clicked. Details are commented in the Snippet's code.
SNIPPET
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no">
<title>00A00</title>
<style>
table.X {
padding: 0;
box-shadow: 0 1px 9px 1px #ccc;
border-radius: 6px;
margin: 20px auto;
}
.X th {
color: #FFF;
background: #FA768E;
padding: 10px;
text-align: center;
vertical-align: middle;
}
.X tr:nth-child(odd) {
background-color: #FA768E;
color: #FFF;
}
.X tr:nth-child(even) {
background-color: #D3E9FF;
color: #F9F;
}
.X td {
border-style: solid;
border-width: 1px;
border-color: #FA768E;
padding: 5px;
text-align: left;
vertical-align: top;
}
.X thead th:first-child {
border-top-left-radius: 6px;
}
.X thead th:last-child {
border-top-right-radius: 6px;
}
.X tbody tr:first-child td:first-child {
border-top-left-radius: 6px;
}
.X tbody tr:first-child td:last-child {
border-top-right-radius: 6px;
}
.X thead+tbody tr:first-child td:first-child {
border-top-left-radius: 0;
}
.X thead+tbody tr:first-child td:last-child {
border-top-right-radius: 0;
}
.X tbody tr:last-child td:first-child {
border-bottom-left-radius: 6px;
}
.X tbody tr:last-child td:last-child {
border-bottom-right-radius: 6px;
}
.X tbody td.center.center {
text-align: center;
padding: 10px;
vertical-align: middle;
}
.X tbody a {
color: #121;
}
.a {
background: #FEDAE0;
}
.rating {
font-size: 1.5rem;
}
.col2 {
color: #Fed;
background: #123;
}
.X tr:nth-child(even) td.col2 {
background: #Edf;
color: #325;
}
</style>
</head>
<body>
<table id="toons" class="table table-condensed X">
<tbody class="table-hover" data-lvl='1'>
<tr>
<td rowspan='5' class='col1'>
<img src='http://iconshow.me/media/images/ui/app-ui-icon/png/128/donut.png' class: 'thumbnail' style='margin-bottom:50px;'>
<img src='http://icons.veryicon.com/png/Movie%20%26%20TV/Simpsons%204/Homer%20Simpson%2001%20Donut.png' class='thumbnail' style='width:200px;height:200px;'>
</td>
</tr>
<tr>
<td class="link center col1"><a href='https://www.facebook.com/HurtsDonutCompany'>Hurt's Donut Company</a>
</td>
</tr>
<tr>
<td class="phone center col1">417.300.6106</td>
</tr>
<tr>
<td class="rating center col1">⭐⭐⭐⭐⭐</td>
</tr>
<tr>
<td class="address center col1">320 Park Central W.
<br>Springfield, Missouri, USA</td>
</tr>
</tbody>
<tbody class="table-hover">
<tr>
<td rowspan='5' class='col2'>
<img src='http://imgh.us/space-donut.gif' class: 'thumbnail' style='margin-bottom:50px;width:200px;'>
<img src='http://imgh.us/gir_zim.gif' class='thumbnail' style='width:200px;height:200px;'>
</td>
</tr>
<tr>
<td class="link center col2"><a href='https://training.gov.au/Training/Details/FDFRB3014A'>Fried Yeast Products</a>
</td>
</tr>
<tr>
<td class="phone center col2">꩸၏🜐🝳</td>
</tr>
<tr>
<td class="rating center col2">🌎🌎🌎🌎🌎</td>
</tr>
<tr>
<td class="address center col2">WarpGate U812
<br>Horsehead Nebula, Irk</td>
</tr>
</tbody>
</table>
<script>
// Collect and reference every <tbody>
var T = document.querySelectorAll('tbody');
// For each <tbody>...
[].forEach.call(T, function(t, idx) {
/* When any part of the <tbody> is clicked...
|| ...function extractData() is called
*/
T[idx].addEventListener('click', extractData, false);
});
/* extractData() will pass an event object...
|| ...and using it's properties to find...
|| ...event.target (the node that was clicked)...
|| ...Next we store the event.target in a var...
|| ...and check to see if it has the class .address...
|| ...if it doesn't, we will find the <tbody> ...
|| ...that it belongs to. From there we'll find...
|| ...td.address and get it's text content...
|| ...Otherwise if we had clicked the td.address...
|| ...we'll have the text already.
*/
function extractData(event) {
if (event.target !== event.currentTarget) {
var dataSource = event.target;
//* Remove a '/' to get the exact text of each <td>
if (!dataSource.classList.contains('address')) {
var grandma = dataSource.closest('tbody');
console.log(grandma.querySelector('.address').textContent);
} else //*/
console.log(dataSource.textContent);
}
}
</script>
</body>
</html>
In the markup (HTML), each "subject" is in it's own <tbody> this helps us to not only to organize the data better, it also facilitates DOM transversal as well. Having multiple <tbody> is completely valid as well.
I'm struggling with the table column hide and show using check box. I want to remove the Mars column(Bold) and with respective data(Bold).
After removing the Mars column, Venus and its respected data values to be centered in the table.
check here: http://jsfiddle.net/bL44n3aj/3/
After Removing Mars Column, I want this Output : http://jsfiddle.net/2Lcsc2go/
My CSS and HTML part:
td{
border:1px solid #000;
}
th{
border:1px solid red;
font-weight:normal !important;
}
tr.sub-header th{
text-align:center !important;
border:1px solid blue !important;
font-weight:bold !important;
}
tr.sub-header-value td{
text-align:center !important;
font-weight:bold !important;
}
<table width="80%">
<tr>
<th>Produced</th>
<th>Sold</th>
<th>Produced</th>
<th>Sold</th>
</tr>
<tr class="sub-header">
<th colspan="2">Mars</th>
<th colspan="2" scope="colgroup">Venus</th>
</tr>
<tr>
<td>50,000</td>
<td>30,000</td>
<td>100,000</td>
<td>80,000</td>
</tr>
<tr class="sub-header-value">
<td colspan="2">Mars data</td>
<td colspan="2"> Venus data </td>
</tr>
<tr>
<td>10,000</td>
<td>5,000</td>
<td>12,000</td>
<td>9,000</td>
</tr>
<tr class="sub-header-value">
<td colspan="2">Mars data</td>
<td colspan="2">Venus data</td>
</tr>
</table>
<input type="checkbox"> Remove Mars
This is a hacky way. To make it less hacky, you would need to add classes to all of the tds.
I'm using jQuery, do you want a JavaScript version?
$(function(){
var removed = false;
$("#removeMars").click(function(){
if (!removed) {
$.each($("#t tr"), function(){
var tds = $(this).find("th, td");
if (tds.length == 2) {
$(tds[1]).attr("colspan", "4");
$(tds[0]).remove();
}
})
removed = true;
}
})
})
td{
border:1px solid #000;
}
th{
border:1px solid red;
}
tr.sub-header th{
text-align:center !important;
border:1px solid blue !important;
font-weight:bold !important;
}
tr.sub-header-value td{
text-align:center !important;
font-weight:bold !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="t" width="80%">
<tr>
<th>Produced</th>
<th>Sold</th>
<th>Produced</th>
<th>Sold</th>
</tr>
<tr class="sub-header">
<th colspan="2" >Mars</th>
<th colspan="2" scope="colgroup">Venus</th>
</tr>
<tr>
<td>50,000</td>
<td>30,000</td>
<td>100,000</td>
<td>80,000</td>
</tr>
<tr class="sub-header-value">
<td colspan="2">Mars data</td>
<td colspan="2"> Venus data </td>
</tr>
<tr>
<td>10,000</td>
<td>5,000</td>
<td>12,000</td>
<td>9,000</td>
</tr>
<tr class="sub-header-value">
<td colspan="2">Mars data</td>
<td colspan="2">Venus data</td>
</tr>
</table>
<input type="checkbox" id="removeMars"> Remove Mars
The completed Solution:
$(function(){
var removed = false;
$("#removeMars").change(function(){
if(this.checked) {
if (!removed) {
$.each($("#t tr"), function(){
var tds = $(this).find("th, td");
if (tds.length == 2) {
$(tds[1]).attr("colspan", "4");
$(tds[0]).hide();
}
})
removed = true;
}
}
else{
$.each($("#t tr"), function(){
var tds = $(this).find("th, td");
if (tds.length == 2) {
$(tds[1]).attr("colspan", "2");
$(tds[0]).show();
}
})
removed = false;
}
})
})
Check this Fiddle link : http://jsfiddle.net/qLo60ux8/