Remove the specific column in table - javascript

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/

Related

Change the color of the numbers in the table based on their value by js

I have 2 tables and the numbers in each table change automatically, and I want the numbers in Table 1 to change their background color if they match any of the numbers in Table 2.
My code changes the background color of numbers, but the color only changes one item.
Friends, can you help me how to solve this problem?
setInterval(() => {
const tds =document.querySelector("table").querySelectorAll("tr")[Math.floor(Math.random() * 3)+0].querySelectorAll("td");
tds.forEach((item) => {
item.innerHTML = (Math.floor(Math.random() * 10)+0);
});
$(function(){
$(".table2 tr td").each(function() {
var val = parseInt(this.innerHTML);
$(".table1 tr td").each(function() {
var val2 = parseInt(this.innerHTML);
if (val2 == val) {
this.style.backgroundColor = "#F00000"
}else{
this.style.backgroundColor = "#fff"
}
});
});
});
}, 1000);
table tr td{
border: 1px solid black;
}
table{
width:40%;
font-weight:bold ;
font-size:13px;
text-align:center;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Table 1:
<table class="table1" >
<tr>
<td>21</td>
<td>12</td>
</tr>
<tr>
<td>22</td>
<td>22</td>
</tr>
<tr>
<td>32</td>
<td>32</td>
</tr>
</table>
</div>
<br>
<div>Table 2:
<table class="table2" >
<tr>
<td>2</td>
</tr>
<tr>
<td>1</td>
</tr>
<tr>
<td>6</td>
</tr>
</table>
</div>
You should have the numbers from the second table in an array and see if it contains the generated value in the first table when you loop through it :
const nums = [...document.querySelector(".table2").querySelectorAll("td")].map(e => +e.innerText);
setInterval(() => {
const tds = document.querySelector("table").querySelectorAll("tr")[Math.floor(Math.random() * 3) + 0].querySelectorAll("td");
tds.forEach((item) => {
item.innerHTML = (Math.floor(Math.random() * 10) + 0);
});
const nums = [...document.querySelector(".table2").querySelectorAll("td")].map(e => +e.innerText);
$(function() {
$(".table1 tr td").each(function() {
var val2 = parseInt(this.innerHTML);
if (nums.includes(val2)) {
this.style.backgroundColor = "#F00000"
} else {
this.style.backgroundColor = "#fff"
}
});
});
}, 1000);
table tr td {
border: 1px solid black;
}
table {
width: 40%;
font-weight: bold;
font-size: 13px;
text-align: center;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Table 1:
<table class="table1">
<tr>
<td>21</td>
<td>12</td>
</tr>
<tr>
<td>22</td>
<td>22</td>
</tr>
<tr>
<td>32</td>
<td>32</td>
</tr>
</table>
</div>
<br>
<div>Table 2:
<table class="table2">
<tr>
<td>2</td>
</tr>
<tr>
<td>1</td>
</tr>
<tr>
<td>6</td>
</tr>
</table>
</div>

How To Apply jquery filtering on click of html link

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

check gets checked by click on its class

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

Why did my ChildNodes return undefined on JS event handler?

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.

Use Javascript to search HTML table and keep the complete table row where matches are found and remove the rest

Extremely new to Javascript, somewhat new to HTML so any help is great.
I have an HTML table that I have created and would like to tie a javascript script to it which would allow me to search in my search box, and any entries not matching would disappear and matches would stay on screen with the entire row showing. I currently have it so I can search for a keyword, but just the word appears and everything else disappears leaving whatever keyword found brought over to the first column.
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript" src="js-search.js"></script>
</head>
<style type="text/css"> table {
font-size: 12px;
border: 1px solid #CCC;
font-family: Arial, Helvetica, sans-serif;
}
table td {
padding: 4px;
margin: 3px;
border: 1px solid #CCC;
}
table th {
background-color: #104E8B;
color: #FFF;
font-weight: bold;
}
</style>
<body>
<input type="text" id="search" placeholder="Type to search">
<table id="table">
<table class="searchable">
<thead>
<tr>
<th>High-Level Category</th>
<th>Device Type</th>
<th>Hostname</th>
<th>IP Address</th>
<th>Owner</th>
<th>Organizational Unit</th>
<th>Organizational Unit Email</th>
<th>Universal Forwarder or Syslog?</th>
<th>In PCI?</th>
<th>Notes:</th>
</tr>
</thead>
<tbody>
<tr>
<td>Security Device</td>
<td>Firewall</td>
<td>ITFirewall1</td>
<td>1.1.1.1</td>
<td>User1</td>
<td>Information Technology</td>
<td>test#test.com</td>
<td>Syslog</td>
<td>Yes</td>
<td> </td>
</tr>
<tr>
<td>Security Device</td>
<td>Firewall</td>
<td>ITFirewall2</td>
<td>2.2.2.2</td>
<td>User2</td>
<td>Program Development</td>
<td>test2#test2.com</td>
<td>Syslog</td>
<td>No</td>
<td> </td>
</tr>
That is my table pointing to jquery and my searchable javascript file. The following is what I have for my javascript that does the searching:
$(document).ready(function(){
var $rows = $('table td');
$('#search').keyup(function() {
var val = '^(?=.*\\b' + $.trim($(this).val()).split(/\s+/).join('\\b)(?=.*\\b') + ').*$',
reg = RegExp(val, 'i'),
text;
$rows.show().filter(function() {
text = $(this).text().replace(/\s+/g, ' ');
return !reg.test(text);
}).hide();
});
});
Any ideas on what I am doing wrong? All help would be appreciated.
Thanks!
You are really close, just change the code var $rows = $('table td'); to var $rows = $('table tr'); to make this work. And ideally you should show the table header always. For that you can use var $rows = $('table tr:has(td)');
If using a plugin is an option, I suggest using Datatables don't reinvent the wheel :)
Here is an example of how the search works:
https://datatables.net/examples/basic_init/zero_configuration.html
.hide() is equivalent to css display:none (as opposed to visibility:hidden) - the hidden element occupies no space, so everything else moves. In this snippet, I replaced .hide with .css("opacity","0.1"). I think this is what you wanted to acheive.
$(document).ready(function(){
var $rows = $('table tr');
$('#search').keyup(function() {
var val = '^(?=.*\\b' + $.trim($(this).val()).split(/\s+/).join('\\b)(?=.*\\b') + ').*$',
reg = RegExp(val, 'i'),
text;
$rows.css("opacity","1").filter(function() {
text = $(this).text().replace(/\s+/g, ' ');
return !reg.test(text);
}).css("opacity","0.1");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript" src="js-search.js"></script>
</head>
<style type="text/css"> table {
font-size: 12px;
border: 1px solid #CCC;
font-family: Arial, Helvetica, sans-serif;
}
table td {
padding: 4px;
margin: 3px;
border: 1px solid #CCC;
}
table th {
background-color: #104E8B;
color: #FFF;
font-weight: bold;
}
</style>
<body>
<input type="text" id="search" placeholder="Type to search">
<table id="table">
<table class="searchable">
<thead>
<tr>
<th>High-Level Category</th>
<th>Device Type</th>
<th>Hostname</th>
<th>IP Address</th>
<th>Owner</th>
<th>Organizational Unit</th>
<th>Organizational Unit Email</th>
<th>Universal Forwarder or Syslog?</th>
<th>In PCI?</th>
<th>Notes:</th>
</tr>
</thead>
<tbody>
<tr>
<td>Security Device</td>
<td>Firewall</td>
<td>ITFirewall1</td>
<td>1.1.1.1</td>
<td>User1</td>
<td>Information Technology</td>
<td>test#test.com</td>
<td>Syslog</td>
<td>Yes</td>
<td> </td>
</tr>
<tr>
<td>Security Device</td>
<td>Firewall</td>
<td>ITFirewall2</td>
<td>2.2.2.2</td>
<td>User2</td>
<td>Program Development</td>
<td>test2#test2.com</td>
<td>Syslog</td>
<td>No</td>
<td> </td>
</tr>

Categories

Resources