Hide table When there are no elements in its body - javascript

I have ajax link in my table which will delete elements on click. I want to make sure that when all the elements are deleted the table should hide itself. I cannot add any event on the ajax call. Meaning to say I cannot edit or change any ajax success or anyother parameter or function. I want something that will keep checking the table on its own and when there is no element in the table body hide the table and when an entry is made it will display its self

You could use setInterval() to repeatedly call a function to do the check for you. Then use the variation of .toggle() that takes a boolean:
setInterval(function() {
var $table = $('.tablesorter');
$table.toggle($table.find('tbody').children().length > 0);
}, 500);
That will check roughly twice every second (once every 500 milliseconds), you can change the second argument to increase or decrease the frequency of the check.

Here, for example the table class is named table
$('.table > tbody:empty').parent().hide();
For checking all the tables:
// Call the CheckTables function after 100 milliseconds
setInterval(CheckTables, 100);
function CheckTables()
{
$( "table " ).each(function( index ) {
$(this).find('tbody:empty').parent().hide();
$(this).find('tbody:not(:empty)').parent().show();
});
}

try this
$('.className> tbody:empty').parent().hide();
or
$('.className tr').each(function() {
if ($(this).find('td:empty').length) $(this).remove();
});​

Try this:
$(document).ajaxComplete(function() {
$('table').each(function(){
if($('tbody:empty',this))
$(this).hide();
else $(this).show();
});
});

Related

Jquery each function only working once

I have the following jquery function. It will only update the first row and then stops. Strangely though if i take out the line:
$("#prev_loan_approval_date").html("Not Yet Approved");
and replace it with an alert it fires off for each row. Is there any reason why this would be the case. Was thinking it mightnt return true on the next iteration because i changed the text value but this was for the previous row so the next row should still return true and change the value.
$(document).ready(function() {
$('.loan_history_application > tbody > tr').each(function()
{
if ($("#prev_loan_approval_date").text() == "01/01/1900")
{
$("#prev_loan_approval_date").html("Not Yet Approved");
};
});
tr has a child "#prev_loan_approval_date"?
If yes, you must write
$(document).ready(function() {
$('.loan_history_application > tbody > tr').each(function()
{
if ($(this).find("#prev_loan_approval_date").text() == "01/01/1900")
{
$(this).find("#prev_loan_approval_date").html("Not Yet Approved");
};
});
The problem is likely to be that you use an ID instead of class for $("#prev_loan_approval_date").html("Not Yet Approved"); so it will only update the first row.
Change this to:
$(".prev_loan_approval_date").html("Not Yet Approved");
And make sure you also change ID to class in your HTML.
Was thinking it mightnt return true on the next iteration because i changed the text value but this was for the previous row
No, this isn't for the previous row. There's several things wrong here. Firstly the fact that you're using an ID for something that seems to occur more than once (ID's must be unique). You should use a class.
Secondly, where you're changing the text - you're not doing it just for that row. You're always doing it on every row.
$(document).ready(function() {
$('.loan_history_application > tbody > tr').each(function() {
if ($(".prev_loan_approval_date", this).text() == "01/01/1900")
{
$(".prev_loan_approval_date",this).html("Not Yet Approved");
};
});
And in your HTML change id='prev_load_approval_date' to class='prev_loan_approval_date'
If you have multiple items with the same ID, it doesn't work. IDs should be unique. Change them to class and change in your code:
$(".prev_loan_approval_date").html("Not Yet Approved");
Full Code:
$(document).ready(function() {
$('.loan_history_application > tbody > tr').each(function() {
if ($(this).find(".prev_loan_approval_date").text() == "01/01/1900")
$(this).find(".prev_loan_approval_date").html("Not Yet Approved");
});
});

click event on a cell and not entire row - with FIDDLE

I am currently using this code for row click event in a bootstrap table
$('#myTable').bootstrapTable().on('click-row.bs.table', function (e, row, $element)
{
//....my operation
}
The problem is this triggers for the entire row and I want to be able to trigger it for a single cell.
Note I am using the arguments, row and $element
Here is the FIDDLE
$element is the entire row, you cannot know what cell have been clicked by this way,
bootstrap table do not have cell click event, so you need manually add click event on last cell and fill your needed vars yourself
$('#table').bootstrapTable({
data: data
}).on('click','td:last-child',function(){
var $t = $(this), $row = $t.parent(), i = $row.index(), row = data[i];
var $firstTd = $row.children().eq(0);
if($firstTd.data("haveTable") !== true){
$firstTd.data("haveTable",true);
$firstTd.append('<table class="newTable"><tr><td>NEW TABLE</td></tr></table>');
} else {
$firstTd.data("haveTable",false);
$firstTd.children("table").remove();
}
});
https://jsfiddle.net/e3nk137y/1663/
try
$('#myTable').bootstrapTable().on('click-row.bs.table td', function (e, row, $element)
{
//....my operation
}
Based on my guess, when you click on that cell, you probably want only the triggers for that particular cell to execute and not for the whole table.
This can be achieved by stopping the propagation of event from the table cell to the table row.
$('#myTable').bootstrapTable().on('click-row.bs.table', function (e, row, $element){
//stop the propagation for target cell
if($(event.target).hasClass('myClass')) e.stopPropagation();
//the code for handler
...
...
}
There are many ways stopPropagation can be utilized to do this thing. This was just one of those.
Since I dont know how your other triggers are set, I can't write code that works with those with assumptions.
Try this:
$('#myTable tr td:last-child').on('click', function() {
if( $('.newTable', $(this)).length ) {
$('.newTable', $(this)).remove();
} else {
$(this).append( '<table class="newTable"><tr><td>NEW TABLE</td></tr></table>' );
}
});

Removing rows from table

Assume we have table:
<table>
<tr>first</tr>
<tr class="ClassName">second</tr>
<tr class="ClassName">third</tr>
</table
And We want to remove row with class='ClassName'
I wrote a code:
var Ids = $('.ClassName').map(function () {
return this
}).get();
if (Ids.length > 0) {
for (var i; i = 0; i++) {
Ids[i].hide();
}
}
I need to know if there are any rows with this class. If yes I need to remove them. If no I call ajax, read from db and add rows to table. Its part of Show/Hide mechanism
But my code do nothing. Rows still appear in the page. What should I change?
jQuery
// check if are any rows with this class
var $rows = $('table tr.ClassName');
if( $rows.length > 0 ) {
// remove them or hide with .hide();
$rows.remove();
} else {
// call ajax ...
}
Why not just:
$('table tr.ClassName').hide();
if you want remove permanent then you can use this one.
$('.ClassName').each(function(){
$(this).remove();
});
Here you go -
$("table tr[class='ClassName']").remove();
Please mark this as "Answered" if this solves your problem.
Try using hasClass() in jquery.
JQuery:
//Check if any row has class
if($('table tr').hasClass("ClassName")){ //remove from table }
else{
//do your ajax call here.
}
You can just remove all with that class and then check if there was any:
$(function () {
var $trs = $('table tr.ClassName');
$trs.remove();
if ($trs.length === 0) {
// Ajax-call
}
});
It should work
$("table").find(".ClassName").remove();
If you want to remove all the table rows other than first row means you can try this
$("table").find("tr:gt(0)").remove();

How can I prevent double binding on JavaScript?

Here's my situation, I have a table which can add/remove rows dynamically and I need to bind the remove row when the page loads.
Here's my code:
<script type="text/javascript">
$(document).ready(function(){
$(".btnRemoveRow").bind("click", removeRow); });
</script>
But I also need to Bind another removeRow when I add rows here's on my external js
function addRow(){
{--add row code here--}
$(".btnRemoveRow").bind("click", removeRow);
}
so that the newly added rows will also be bind with the removeRow function,
here is my removeRow function:
function removeRow(){
var row = $(this).closest('tr');
var selected = row.find('input.qty,input.price,textarea,select').val();
$.getScript("calculate.js", function(){});
if(selected)
{
var r=confirm("Confirm Remove?");
if (r==true)
{
row.find('input.qty,input.price,textarea,select').attr("disabled", true);
row.find('input.hidden-deleted-id').val("yes");
row.find('.subtotal>center>h3').text("0");
calculate();
row.hide();
return false;
}
else
{
return false;
}
}
else{
row.find('input.qty,input.price,textarea,select').attr("disabled", true);
row.find('input.hidden-deleted-id').val("yes");
row.find('.subtotal>center>h3').text("0");
calculate();
row.hide();
return false;
}
};
Case 1: when I remove row without adding any rows first, it works fine (dialog box only appears once).
Case 2: when I add row first then remove the rows that were already bound on the page ready, dialog box appears twice.
Case 3: when I remove rows that I added, it works fine (dialog appears once).
(PS: still learning JavaScript)
Any idea how may I solve case no.2 please?
Add one event handler that is delegated, that way it will work for existing elements, and future elements
<script type="text/javascript">
$(document).ready(function(){
$(document).on("click", ".btnRemoveRow", removeRow);
});
</script>
replace document with the closest non-dynamic parent element.
Try this:
<script type="text/javascript">
$(function(){
$(".btnRemoveRow").click(function(){removeRow();});
});
</script>

Registering jQuery click, first and second click

Is there a way to run two functions similar to this:
$('.myClass').click(
function() {
// First click
},
function() {
// Second click
}
);
I want to use a basic toggle event, but .toggle() has been deprecated.
Try this:
$('.myClass').click(function() {
var clicks = $(this).data('clicks');
if (clicks) {
// odd clicks
} else {
// even clicks
}
$(this).data("clicks", !clicks);
});
This is based on an already answered question: Alternative to jQuery's .toggle() method that supports eventData?
Or this :
var clicks = 0;
$('.myClass').click(function() {
if (clicks == 0){
// first click
} else{
// second click
}
++clicks;
});
this I worked for my menu
var SubMenuH = $('.subBoxHederMenu').height();
var clicks = 0;
$('.btn-menu').click(function(){
if(clicks == 0){
$('.headerMenu').animate({height:SubMenuH});
clicks++;
console.log("abierto");
}else{
$('.headerMenu').animate({height:"55px"});
clicks--;
console.log("cerrado");
}
console.log(clicks);
});
i don't know what you are tryin to do but we can get basic toggle by
$('.myClass').click({
var $this=$(this);
if($this.is(':hidden'))
{
$this.show('slow');
}else{
$this.hide('slow');
}
})
note: this works for endless click event for that element .. not just for two clicks (if that is what you want)
OR you can use css class to hide/show the div and use jquery.toggleClass()
In the method mentioned below We are passing an array of functions to our custom .toggleClick() function. And We are using data-* attribute of HTML5 to store index of the function that will be executed in next iteration of click event handling process. This value, stored in data-index property, is updated in each iteration so that we can track the index of function to be executed in next iteration.
All of these functions will be executed one by one in each iteration of click event. For example in first iteration function at index[0] will be executed, in 2nd iteration function stored at index[1] will be executed and so on.
You can pass only 2 functions to this array in your case. But this method is not limited to only 2 functions. You can pass 3, 4, 5 or more functions in this array and they will be executed without making any changes in code.
Example in the snippet below is handling four functions. You can pass functions according to your own needs.
$.fn.toggleClick = function(funcArray) {
return this.click(function() {
var elem = $(this);
var index = elem.data('index') || 0;
funcArray[index]();
elem.data('index', (index + 1) % funcArray.length);
});
};
$('.btn').toggleClick([
function() {
alert('From Function 1');
}, function() {
alert('From Function 2');
}, function() {
alert('From Function 3');
}, function() {
alert('From Function 4');
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button type="button" class="btn">Click Me</button>
<button type="button" class="btn">Click Me</button>
If you literally only want the first and second click:
$('.myClass').one( 'click', function() {
// First click
$('.myClass').one( 'click', function() {
// Second click
});
);
var click_s=0;
$('#show_pass').click(function(){
if(click_s % 2 == 0){
$('#pwd').attr('type','text');
$(this).html('Hide');
}
else{
$('#pwd').attr('type','password');
$(this).html('Show');
}
click_s++;
});
When You click the selector it automatically triggers second and waiting for another click event.
$(selector).click(function(e){
e.preventDefault(); // prevent from Posting or page loading
//do your stuff for first click;
$(this).click(function(e){
e.preventDefault();// prevent from Posting or page loading
// do your stuff for second click;
});
});
I hope this was helpful to you..
I reach here looking for some answers, and thanks to you guys I´ve solved this in great manner I would like to share mi solution.
I only use addClass, removeClass and hasClass JQuery commands.
This is how I´ve done it and it works great:
$('.toggle').click(function() {
if($('.categ').hasClass("open")){
$('.categ').removeClass('open');
}
else{
$('.categ').addClass('open');
}
});
This way a class .open is added to the Html when you first clikc.
Second click checks if the class exists. If exists it removes it.

Categories