I am trying to write a script that detects if a tables tds are empty and if they are hide the parent tr
I've searched Stack Overflow and found other scripts but none seem to work for me.
So far I have:
$(".table tr").each(function() {
var cell = $(this).find('td').html();
if (cell == null){
console.log('empty');
$(this).parent().addClass('nodisplay');
}
});
but just can't get it working. Any advice would be appreciated!
Fiddle: http://jsfiddle.net/MeltingDog/S8CUa/1/
Try this -
$("table tr td").each(function() {
var cell = $(this);
if ($(cell).text().length == 0){
console.log('empty');
$(this).parent().addClass('nodisplay');
}
});
Demo
you should try this.
jQuery(document).ready(function(e) {
jQuery(jQuery('table tr td:empty').parents('tr')).addClass('nodisplay');
});
.html() only returns the content of the first matched element, so if your rows have more than one cell this wouldn't work. .text() might be a better fix, unless you have images or other empty tags in the cells.
$("table tr").each(function() {
var cell = $.trim($(this).find('td').text());
if (cell.length == 0){
console.log('empty');
$(this).addClass('nodisplay');
}
});
DEMO
It seems you want to hide rows that have only whitespace content (but the cells might have other element child nodes). Using plain javascript:
var rows = document.getElementsByTagName('tr');
var i = rows.length;
while (i--) {
if ( !trim(getText(rows[i])) ) {
rows[i].className += ' nodisplay';
}
}
Helpers:
function trim(s) {
return s.replace(/(^\s*)|(\s*$)/g, '');
}
function getText(el) {
if (typeof el.textContent == 'string') {
return el.textContent;
} else if (typeof el.innerText == 'string') {
return el.innerText;
}
}
$('table tr').each(function(){
var hide = true;
$('td',this).each(function(){
if ($.trim($(this).text()) != "")
hide = false;
});
if(hide)
$(this).closest('tr').hide();
// OR $(this).closest('tr).addClass('nodisplay');
});
Hide table, if table have no rows using jquery
$('.tblClass').each(function(){
if($(this).find('.rows').length == 0){
$(this).hide();
}
});
Related
I have table which looks like this jsfiddle
Now i need to implement functionality to print just selected rows. Rows can be selected by clicking on check-box on the right of each row.
Can somebody advise me how to complete it, please?
I already implemented full table printing functionality with
var divToPrint=document.getElementById("pretazna");
newWin= window.open("");
newWin.document.write(divToPrint.outerHTML);
newWin.print();
newWin.close();
Try this code... it doesn't create a popup window but instead hides rows using a print stylesheet (demo)
CSS
#media print {
#print, tfoot, tbody tr:not(.printme) {
display: none !important;
}
}
Javascript
function matches(el, selector) {
// https://developer.mozilla.org/en-US/docs/Web/API/Element/matches
var matches = document.querySelectorAll(selector),
i = matches.length;
while (--i >= 0 && matches.item(i) !== el) {}
return i > -1;
}
function closest(el, selector) {
while (el && !matches(el, selector)) {
el = el.parentNode;
}
return matches(el, selector) ? el : null;
}
document.querySelector('table').addEventListener('change', function(event) {
var target = event.target;
closest(target, 'tr').classList[target.checked ? 'add' : 'remove']('printme');
})
document.querySelector("#print").addEventListener('click', function() {
window.print();
});
I have an empty table which i want to fill with tds when i press a button.I want to create a new tr after every 3 tds.
I have the following code:
var ruler=0;
var start=false;
$(document).ready(function(){
$("button").on("click",function(){
if (start === false){$("table").append("<tr>"); start = true;}
if(ruler === 3){
$("table").append("</tr><tr>");
ruler = 0;
}
$("table tr").append("<td>mama</td>");
ruler++;
});
});
html
<table>
</table>
The problem is that even after changing row it will continue adding tds in the first line.Any ideas?
As Teemu stated you are selecting all <tr>. So I added a :last selector.
var ruler = 0;
var start = false;
$(document).ready(function() {
$("button").on("click", function() {
if (start === false) {
$("table").append("<tr>");
start = true;
}
if (ruler === 3) {
$("table").append("</tr><tr>");
ruler = 0;
}
$("table tr:last").append("<td>mama</td>");
ruler++;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button>Click me</button>
<table></table>
Use table tr:last as a selector to make sure for the application to append the content to the last row.
I have a table which has id 'myTable'. Now there is a textbox in which I write down the item name to find whether it exists in the myTable cell or not. To do this I have written the following code -
var retval=0;
var search = $("#searchitem").val().trim();
$("table#myTable tr td").filter(function() {
if($(this).text() == search){retval=1;alert('Same item found');}
else{retval=0;}
});
The problem is that, when it finds the same item in the table cell it shows the alertbox. But the value of my variable retval never changes. It always shows 0. How can I solve it?
I think what you are trying to accomplish could be done by using :contains() selector, like this:
var search = $("#searchitem").val().trim();
var retval = $("table#myTable tr td:contains('"+search+"'") ? 1 : 0;
I haven't tested it but I'm almost sure it works. It's a much more cleaner approach and surely more readable.
jQuery :contains() docs: http://api.jquery.com/contains-selector/
please try return false like this
var retval=0;
var search = $("#searchitem").val().trim();
$("table#myTable tr td").filter(function() {
if($(this).text() == search){
retval=1;
alert('Same item found');
return false;
}else{
retval=0;
}
});
change the variable value only if found , because you assign the variable to 0 at the beginning.
var retval=0;
var search = $("#searchitem").val().trim();
$("table#myTable tr td").filter(function() {
if($(this).text() == search){
retval=1;
alert('Same item found');
}
});
Try this code
var search = $("#searchitem").val().trim();
var filteredData = $("table#myTable tr td").filter(function(element, index)
{
return $(element).text() == search;
});
now this code return array of TD elements which satisfy the condition.
Currently I'm using this bit of Javascript to search an HTML table for matching data in a certain cell.
function searchTable(inputVal) {
var table = $('#tblData');
table.find('tr').each(function(index, row) {
var allCells = $(row).find('td');
if(allCells.length > 0) {
var found = false;
allCells.each(function(index, td) {
var regExp = new RegExp(inputVal, 'i');
if(regExp.test($(td).text())) {
found = true;
return false;
}
});
if(found == true){
$(row).show("highlight");
}
else {
$(row).hide("highlight");
}
}
});
}
The table is setup in the following structure:
<tr>
<td>value1</td>
<td>value2</td>
</tr>
So, when searching for value1, the entire row displays - including value2.
I can't figure out how to get value2 to not display. I was trying to assign a different id for each and then using javascript to display:none, but there are a lot of different rows and it seems like a lot of manual work for something obvious that I might be missing.
Any help is appreciated.
EDIT: Additionally, if anyone is up for it - I'm also trying to figure out how to ignore punctuation when someone searches for a value as well. Right now if the value is "that's" and someone searches "thats", it won't find a match.
This updated code will only show columns that are "found." I think you might want to be adding css classes instead of showing and hiding. The commented text shows how to add and remove the "highlight" class.
function searchTable(inputVal) {
var table = $('#tblData');
table.find('tr').each(function (index, row) {
var allCells = $(row).find('td');
if (allCells.length > 0) {
var found = false;
allCells.each(function (index, td) {
var regExp = new RegExp(inputVal, 'i');
if (regExp.test($(td).text())) {
$(this).show();
//$(this).addClass('highlight');
} else {
$(this).hide();
//$(this).removeClass('highlight');
}
});
}
});
}
jsFiddle
I don't know if you have future purpose for looping through the rows, but your code can be simplified to this:
function searchTable(inputVal) {
$('#tblData tr td').each(function (index, td) {
var regExp = new RegExp(inputVal, 'i');
if (regExp.test($(td).text())) {
//$(this).show();
$(this).addClass('highlight');
} else {
//$(this).hide();
$(this).removeClass('highlight');
}
});
}
jsFiddle
Here are 4 functions I use to improve the usability of a table by:
If cell contains a checkbox and you click outside of a checkbox
The the tr contains data-url then the whole row is "clickable"
with CSS hover effect and redirects on click.
If the last column in the table contains a relative/absolute URL
then also redirects on click.
Check all checkboxes.
Here's my code:
// Click table cell auto check checkbox
$('table tr td').has("input[type=checkbox]").click(function(event) {
// Onl call this if click outside of the checkbox itself
if (event.target.type !== 'checkbox') {
$(':checkbox', this).trigger('click');
}
});
// Table row click
$('table tr[data-url]').each(function(){
var url = $(this).attr("data-url");
if(url.length){
$(this)
.addClass("clickable")
.find("td").click(function(){
window.location = url;
return false;
});
}
});
// Double click row, open edit link
$('table:not(.noDoubleClick) tr td').dblclick(function(e) {
var linkEl = $(this).parents('tr').find('td:last-child a');
var linkElHref = linkEl.attr('href');
// Check if has href and http protocol
if(!linkElHref.length || linkEl.prop('protocol').indexOf("http") !== 0){
e.preventDefault();
return false;
}
if (linkElHref && linkEl.attr('onclick') === undefined && !linkEl.hasClass("popme")) {
document.location = linkElHref;
} else {
linkEl.click();
}
});
// Check all checkboxes
$('table input[type=checkbox][name^="checkall"]').live("click",function() {
var parent = $(this).parents('table');
if(!$(this).parents('table').length){
parent = $(this).parents("form");
}
parent.find(':checkbox[name^="' + $(this).attr("data-name") + '"]').prop("checked", this.checked);
});
Q: how can I modify this into one function so that jquery only has to search for tables once?
Example jsfiddle
Thanks for every bodies suggestions I have ended up taking a slightly different approach:
$('table').each(function(){
var $table= $(this), $cell, $row;
// TABLE ROWS
$table.find('tr').each(function(){
$row = $(this);
// Row click redirect to data-url
var url = $row.attr("data-url");
if(url && url.length){
$row.addClass("clickable").find("td").click(function(){
window.location = url;
return false;
});
}
// TABLE HEADING CELLS
$row.find('th, thead td').each(function(){
$cell = $(this);
// Check all checkboxes
$cell.find('input.checkall').live("click",function() {
var parent = $(this).parents('table');
if(!$(this).parents('table').length){
parent = $(this).parents("form");
}
parent.find(':checkbox[name^="' + $(this).attr("data-name") + '"]').prop("checked", this.checked);
});
});
// TABLE CELLS
$row.find('td').each(function(){
$cell = $(this);
// Check checbox onClick
if($cell.find("input[type=checkbox]")){
$cell.click(function(e) {
if(e.target.type !== 'checkbox') $(':checkbox', this).trigger('click');
});
}
// Double click open edit link
if(!$table.hasClass("noDoubleClick")){
$cell.dblclick(function(e){
var linkEl = $(this).parents('tr').find('td:last-child a');
var linkElHref = linkEl.attr('href');
// Check if has href and http protocol
if(linkElHref && (!linkElHref.length || linkEl.prop('protocol').indexOf("http") !== 0)){
e.preventDefault();
return false;
}
if (linkElHref && linkEl.attr('onclick') === undefined && !linkEl.hasClass("popme")) {
document.location = linkElHref;
} else {
linkEl.click();
}
});
}
}); // end CELLS
}); // end ROWS
}); // end TABLE
You should use .on , .live is being deprecated:
$(document).on('click', 'table tr td', function(event)
{
if( $(this).has("input[type=checkbox]"))
{
if (event.target.type !== 'checkbox')
$(':checkbox', this).trigger('click');
}
});
// Table row click
$(document).on('click', 'table tr[data-url] td', function(e)
{
var url = $(this).parent().attr("data-url");
if(url.length)
{
window.location = url;
return false;
}
});
$(document).on('dblclick', 'table:not(.noDoubleClick) tr td', function(e) {
debugger;
var linkEl = $(this).parents('tr').find('td:last-child a');
var linkElHref = linkEl.attr('href');
// Check if has href and http protocol
if(!linkElHref.length || linkEl.prop('protocol').indexOf("http") !== 0){
e.preventDefault();
return false;
}
if (linkElHref && linkEl.attr('onclick') === undefined && !linkEl.hasClass("popme")) {
document.location = linkElHref;
} else {
linkEl.click();
}
});
// Check all checkboxes
$(document).on('click', 'table input.checkall', function() {
var parent = $(this).parents('table');
if(!$(this).parents('table').length){
parent = $(this).parents("form");
}
parent.find(':checkbox[name^="' + $(this).attr("data-name") + '"]').prop("checked", this.checked);
});
I have made the basic stubs here, i dont want to rewrite all your code.
$(document).ready(function(){
$('table').each(function(){
var table = $(this);
table.find('tr').each(function (){
var tr = $(this);
tr.find('td').each(function(){
var td = $(this);
td.has("input[type=checkbox]").click(function(event) {
// Only call this if click outside of the checkbox itself
if (event.target.type !== 'checkbox') {
$(':checkbox', this).trigger('click');
}
});
});
});
});
});
The logic is: Find all tables, loop through all the tr's and then the td's. I've did your first function and hope that explains how it could be used?
The best thing to do in this case is to:
Get all of the tables in the page
Loop through each table
Find and apply logic to the individual elements as needed
$('table').each(function(){
var table = $(this),
rows = table.find('tr[data-url]'),
cells = table.find('td'),
all = table.find('input[type=checkbox][name^="checkall"]'),
edit = table.is('.noDoubleClick');
cells.each(function(){
//Apply your logic here
if(edit === true){
//Apply your logic to this cell here
}
});
rows.each(function(){
//Apply your logic to this row here
});
all.on('click',function(){
//Apply your logic here
});
});