Removing rows from table - javascript

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

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

get the id of parent tr for a child td

I want to get the id of the parrent tr of the td:
In this Jsfiddle I'm getting the id the td which has been chacked; I just return this value only if one row has been checked!
but
$(this).parent().attr("id")
gives me an undefined error! What is the correct way to get the id of parrent?
Thanks
When you use $(this).parent().attr("id") what you actualy get is TBODY element, try using closest('table') or parents('table') instead to find the parent TABLE of your TR.
From your example:
$("#my_tbl").find("tr").each(function() {
if ($(this).find("td:first").hasClass('checked'))
{
count = count + 1;
id = ($(this).closest('table').attr('id'));
// id = ($(this).parents('table').attr('id'));
}
});
Fiddle Demo
You can use:
id = $(this).attr("id");
It's because you're looping through the tr of your table using $("#my_tbl").find("tr").each( so you're already at the tr level.
So there's no need to use parent() to traverse up to the parent anymore, you just need to use $(this) to target current row tr of checked td instead.
Fiddle Demo
try with
just this works check demo
$(this).attr("id");
$(this) here is referring to tr only
Fiddle Demo
You just need to set this:
id = $(this).attr("id");
This is because you are working with currently with that tr.
First, you need to check if parent tag/node has id attribute or not. Also, you would get a better answer if you could share what's your objective and relevant HTML
use toggleClass() to switch the class
use .map() to get the ids of checked tr elemets
Try
function myFunction(element) {
$(element).find("td:first").toggleClass('checked');
}
function check() {
var ids = $("#my_tbl tr td.checked").parent().map(function () {
return this.id;
}).get();
if (ids.length > 0) {
alert(ids.join());
}
}
Demo: Fiddle
A more jQueryish solution will be is to use jQuery event handlers like
jQuery(function ($) {
$('#my_tbl tr').click(function () {
$(this).find("td:first").toggleClass('checked');
})
$('#check').click(function () {
var ids = $("#my_tbl tr td.checked").parent().map(function () {
return this.id;
}).get();
if (ids.length > 0) {
alert(ids.join());
}
})
})
Demo: Fiddle
If you want to support IE7+ only then try this

Is there a way to know if the element is inside a table or a list?

I'm making a generic delete function that will delete a record and then delete the <tr> if the element is inside a <table>, or the <li> if it's inside a <ul>
The element can be in a list inside a table, so I need to know what parent element is closest.
Is there a way to find out this using jQuery?
If I understand you correctly, you want something like this:
if ($(this).closest('li').length) {
$(this).closest('li').remove();
} else { // must be in a table
$(this).closest('tr').remove();
};
http://api.jquery.com/closest
In the unlikely event your element is in a table inside a li, you need to be more creative:
if ($(this).closest('li').length) {
if ( $(this).closest('li').is($(this).closest('tr').closest('li')) ) {
// then we're in a table inside an li
$(this).closest('tr').remove();
} else {
$(this).closest('li').remove();
};
} else { // must be in a table
$(this).closest('tr').remove();
};
http://api.jquery.com/is
You can use closest() jQuery function.
function elementInTable(element) {
if (element.closest("table").length) return true;
return false;
}
Another solution is to search for each table and see if your element is in the table:
function elementInTable(element) {
element = $(element);
$("table").each(function () {
var currentTable = $(this);
if (currentTable.find(element).length) {
return true;
}
});
return false;
}
I guess it's not the best, but can be a solution.
if($(/*query*/).parent().is('table')){}
or if it's not a direct child
if($(target).parents('table').length > 0) {
//do something...
}
You can use the jquery.parents() function to retrieve the closest parent of a given selection:
$(myElemToDelete).parents('tr').remove();
There are several good answers on how to accomplish what you want, but I wonder about the initial premise... could you pass the id of the container to the function?
<li id="li_0">Some content <span class="delete" onclick="deleteRow('li_0')">Delete</span></li>
This would give your function flexibility to work in any structure. But, I don't know if that would really work for what you're wanting.
First,check whether the parent exist or not.
If it does,then check whether its input/tr or whatever element you want to delete and then remove.
if ($(event.target).parent('.selector').size() > 0)
{
$("#elementId").is("input")//or tr or whatever!!!
{
//your removal code
}
}

live each jquery?

<table style="width: 50%" id="myTable">
<tbody>
<tr><td>Row 1</td><td>dd</td><td>red</td><td>dd</td></tr>
<tr><td>Row 2</td><td>dd</td><td>green</td><td>dd</td></tr>
<tr><td>Row 3</td><td>dd</td><td>red</td><td>dd</td></tr>
</tbody>
</table>
Add Row
$(document).ready(function () {
$("a[name=addRow]").click(function() {
$("table#myTable tr:last").after('<tr><td>Row 4</td><td>dd</td><td>red</td><td>dd</td></tr>');
return false;
});
$('#myTable tbody tr td').each(function()
{
if ($(this).text() == 'red')
{
$(this).parent().css('background-color', 'red');
}
else if ($(this).text() == 'green')
{
$(this).parent().css('background-color', 'green');
}
});
});
why if i add new rows then this doesnt work? i try add live:
$('#myTable tbody tr td').live('each', function()
but this also doesnt work
LIVE: http://jsfiddle.net/pytP2/
This works:
$(document).ready(function () {
$("a[name=addRow]").click(function() {
$("table#myTable tr:last").after('<tr><td>Row 4</td><td>dd</td><td>red</td><td>dd</td></tr>');
initRow($("table#myTable tr:last"));
return false;
});
$('#myTable tbody tr').each(function()
{
initRow($(this));
});
function initRow(row)
{
row.find('td').each(function(){
var self = $(this);
var textInTD = $.trim(self.text());
if (textInTD == 'red')
{
row.css('background-color', 'red');
return false;
}
else if (textInTD == 'green')
{
row.css('background-color', 'green');
return false;
}
})
}
});
If you need, I can add comments to the code.
live will attach a handler to a specific event for all existing and future instances of the specified elements, which is different to what you're trying to do, as you need to update the styling of new elements added to the table. live would only be useful if you wanted to add say a 'click' event to each new row in your table.
To fix your code you need to call the style update function after each new element is added, there's a working demo here - http://jsfiddle.net/ipr101/zDvAQ/1/
live takes an event type (such as 'click') as a first parameter. See http://api.jquery.com/live/
This does not work because the onload code is only fired once: on load...
If you want the code to be executed after adding a new row, extract the wanted code into a new function and call it after adding the new rows
if you're worried about performance (if the table can get very big) you could also pass the new row to the function.

How to restore Textbox Data

I have a small requirement,
We have restore the textbox data that was cleared previously.
Below is my HTMl code
<table>
<tr><td><input type="textbox"></td></tr>
<tr><td><input type="checkbox"></td></tr>
</table>
Here is my JQuery Code
$('TABLE TR TD').find(':checkbox').change(function()
{
if($(this).prop('checked'))
{
$(this).parents('TR').siblings('TR').find('input').val("")
}
if(!$(this).prop('checked'))
{
$(this).parents('TR').siblings('TR').find('input').val(?)
}
});
My Requirement is to clear the textbox content if checkbox is checked. And if i deselect it the textbox should be restored with previous data.
Please someone help me.
Use a global variable to store the previous data -
var prevData;
then modify your code this way -
$('TABLE TR TD').find(':checkbox').change(function()
{
if($(this).prop('checked'))
{
var $element = $(this).parents('TR').siblings('TR').find('input')
prevData = $element.val();
$element.val("");
}
else
{
$(this).parents('TR').siblings('TR').find('input').val(prevData);
}
});
When the checkbox is being checked, before clearing the value, store it using the jQuery .data() API.
<table>
<tr><td><input type="text"></td></tr>
<tr><td><input type="checkbox"></td></tr>
</table>
$('input:checkbox').change(function() {
var input = $(this).closest('table').find('input[type="text"]');
if ($(this).prop('checked')) {
input.data('text', input.val());
input.val('');
} else {
input.val(input.data('text'));
}
});
A demo which works if there were multiple pairs, so long as they exist in separate <table> parents. You could change the finder to get the previous sibling if that were not the case. This uses no global variables which are not really best practice - How to avoid global variables in JavaScript?.
Edit: Updated demo based on your other question Keydown event is not working properly but this will only for key events and not if someone pastes text into the <input>.
I'd suggest something a little less reliant on the mark-up remaining the same (though it does require that the checkbox follows the text input):
var prevData, textInputIndex;
$('input:checkbox').change(
function(){
thisIndex = ($(this).index('table input') - 1);
textInput = $('table input').eq(thisIndex);
if ($(this).is(':checked')) {
prevData = $(textInput).eq(thisIndex).val();
$(textInput).eq(thisIndex).val('');
}
else {
$(textInput).eq(thisIndex).val(prevData);
}
});
JS Fiddle demo.
Edited to remove the problem of having only one variable to store the text-input value:
var $textInputs = $('table input:text');
var prevData, textInputIndex, affectedTextInputIndex, textInputValues = [];
$('input:checkbox').change(
function(){
affectedTextInputIndex = $(this).index('table input') - 1;
textInputIndex = $('table input').eq(affectedTextInputIndex).index('table input:text');
if ($(this).is(':checked')) {
textInputValues[textInputIndex] = $textInputs.eq(textInputIndex).val();
$textInputs.eq(textInputIndex).val('');
}
else {
$textInputs.eq(textInputIndex).val(textInputValues[textInputIndex]);
}
});
JS Fiddle demo.
Edited to remove the explicit requirement that the input elements be contained in a table:
var $textInputs = $('input:text');
var prevData, textInputIndex, affectedTextInputIndex, textInputValues = [];
$('input:checkbox').change(
function(){
affectedTextInputIndex = $(this).index('input') - 1;
textInputIndex = $('ul input').eq(affectedTextInputIndex).index('input:text');
if ($(this).is(':checked')) {
textInputValues[textInputIndex] = $textInputs.eq(textInputIndex).val();
$textInputs.eq(textInputIndex).val('');
}
else {
$textInputs.eq(textInputIndex).val(textInputValues[textInputIndex]);
}
});
JS Fiddle demo.
References:
:checkbox selector.
change().
is().
:checked selector.
index().
val().

Categories