JQuery zebra stripe table that has groups of rows - javascript

I typically zebra stripe table rows for odd / even like so and it works well:
$("table tbody tr:visible:even",this).addClass("even");
$("table tbody tr:visible:odd",this).addClass("odd");
However, I have a data table where there are three consecutive rows for 1 set of data. The next three consecutive rows would be for the next set of data. So ideally I'd like to take the first three rows and add a class of even and then the next three rows after that to have a class of odd.

Here's something I whipped up on jsfiddle:
$("tr:nth-child(6n)").addClass("odd")
.prev().addClass("odd")
.prev().addClass("odd");
What this does is select every 6th tr element, set its class to odd, and the same to the previous two tr elements, thus giving you the result of 3 "grouped" rows.
More about the nth-child() selector here, and more about the prev() function here.
You could change the code to this to add an even class to the three rows preceding the ones with the odd classname:
$("tr:nth-child(6n)").addClass("odd")
.prev().addClass("odd")
.prev().addClass("odd")
.prev().addClass("even")
.prev().addClass("even")
.prev().addClass("even");
That looks like this.

Here is a solution that can work with more complex formulas.
http://jsfiddle.net/JRPmw/
You use jQuery's filter instead. You provide as complex an equation as you like and return true for rows you want.
$('tr').filter( function(n) {
var x = (n+1) % 6;
if (x >= 1 && x <= 3) return true;
}).addClass('threes');

Try use :nth-child selector :
$("table tbody tr:visible:nth-child(6n+1)").addClass("even");
$("table tbody tr:visible:nth-child(6n+2)").addClass("even");
$("table tbody tr:visible:nth-child(6n+3)").addClass("even");
$("table tbody tr:visible:nth-child(6n+4)").addClass("odd");
$("table tbody tr:visible:nth-child(6n+5)").addClass("odd");
$("table tbody tr:visible:nth-child(6n+6)").addClass("odd");
http://jsfiddle.net/fliptheweb/5Xnvu/

Related

Repeat a javascript code with a different number in each run

I don't know the terminology but hoping this explanation makes sense. I have a JavaScript code that I want to repeat 10 times, each time with an increasing number to target each td in a table (first td then the second then the third and so on)
The goal of this JavaScript is to match the TD width of the thead to the one in the tbody (this is because I have them separated via css with position:absolute).
Right now I managed to match the width of a single TD with this:
var cell4 = $('#divResults tbody > td:nth-child(4)');
$('#divResults thead > tr > td:nth-child(4)').css({ width: cell4.width()});
The easiest, but not practical, way to accomplish setting the remaining TDs is to duplicate the JS but replacing the numbers 9 more times.
I know there is a way to create a loop and target each TD without manual duplication of the code but can't seem to find an answer online.
I appreciate the help
Instead of selecting a specific element, select all elements and loop over them.
$('#divResults tbody > td').each(function( index ) {
// Do some repeating code
});
Link for more details
https://api.jquery.com/each/
In vanilla JS you would use a for loop to achieve this. Using jQuery you can just grab a collection of <td>s and loop over them using .each
// Get the first tr's collection of td elements
var bodyTds = $('#divResults tbody tr:first-child td');
// Loop over the head td's (should be th's really)
$('#divResults thead tr td').each(function(index) {
// Apply the width of the body td to the head td
$(this).css({ width: bodyTds.eq(index).width()});
});

How to modify to every cell in last column in table using Jquery

I'm trying to modify every cell in last column in html table.
My first try is:
$('#example td:last').each(function(elem) {
//do something with elem
});
But above code modify only last cell in last column (so one cell instead of all cells in column).
How should I change selector to much all td in last column?
Try :last-child instead of :last.
You can do:
$('#example tr').each(function() {
var elem = $(this).find('td:last');
//do something with elem
});
Fiddle Demo
:last return a single element, the last element of the jQuery stack. It is exactly the same of doing :
var $td = $('#example td');
$td.eq($td.length - 1);
What you want is the CSS selector :last-child, which return the last child (huh).
$('#example td:last-child').each(...);

Remove table rows using jQuery but prevent remove the first row

I am using jQuery to remove table rows - my script works ok but I don't want the button to be able to remove the very first table row. Can anyone suggest how this is done?
$("#remove").click(function(event) {
event.preventDefault();
$("table tr:last").remove();
i++;
});
Try the following:
if ($("table tr").length != 1) {
$("table tr:last").remove();
}
How about
$("tr:last:not(:first)").remove();
You don't need the table selector as all rows are inside tables, but it might be useful to specify the table element from which you want to remove (avoiding side effects if you later would add other tables).
Example: Remove all rows from $table except the first:
$("tr:not(:first)", $table).remove();
You can use gt() and not():
$('table').find('tr:gt(0):last').remove();
This finds all rows with an index greater than 0, gt(0) and selects the last row, :last and then removes that element.
Demo: http://jsfiddle.net/XhtC8/
If you wanted to remove all rows but the first then you can remove :last:
$('table').find('tr:gt(0)').remove();
Try:
$("#remove").click(function(event) {
event.preventDefault();
$("table tr:not(':first')").remove();
i++;
});
Demo here: http://jsfiddle.net/aGukb/

jQuery remove range of rows

Let's say I have a table with these rows:
<table>
<tr id="before_dynamic_rows"></tr>
<tr id="after_dynamic_rows"></tr>
</table>
Using jQuery, I insert automatically generated rows (search results) before the after_dynamic_rows row. How can I delete a range of rows, namely - you guess it - the ones between the row with the id before_dynamic_rows and the row after_dynamic_rows? (In order to be able, after having inserted them, to remove them and insert different ones.)
var response = ajax.responseText;
$('#after_dynamic_rows').before(response);
That's how I insert the new rows. Considering the first answer: how can I assign a class to whatever the response text may be?
This answer is based on a literal interpretation of the question with the idea that the only rows which should be removed are those rows that are in between #before_dynamic_rows element and #after_dynamic_rows.
See working version at: http://jsfiddle.net/7wBzd/
var $rows = $("tr");
$("tr:lt("+ $rows.index($("#after_dynamic_rows")) +"):gt("+ $rows.index($("#before_dynamic_rows")) +")").remove();
$("table tr:gt(0)").not("#after_dynamic_rows").remove();
Try it out here.
Note if #after_dynamic_rows is the last row, then you can just do:
$("table tr:gt(0)").not(":last").remove();
or:
$("table tr:gt(0):not(:last)").remove();
...and if there are rows before #before_dynamic_rows, just do:
$("table tr:not(#before_dynamic_rows, #after_dynamic_rows)").remove();
I would assign a class to those added rows to make them easy to select, but you could select all tr children and use the 'not' method to remove the two you want to keep.
$("table tr").not("#before_dynamic_rows").not("#after_dynamic_rows").remove();

Selector - Selecting all tables on a page in jQuery

Say I have multiple tables (no IDs or names) on a page at various levels within embedded divs. What would my selector be (if it is possible) to select all tables regardless of where it resides on a page and iterate or filter the tables based on the content of the first cell in the first row?
You can simply use $('table') as your selector.
Then you can use the existing filters such as ":contains" or ":has", or the .filter() function if you need more finegrained control over in filtering your results. For example,
$('table:has(td > span)')
or
$('table').filter(function(index){
return $(this).html() == "<tr><td>something</td></tr>";
});
Try...
$("table").each(function(){
var curTable = $(this);
var cell = $(this).find("tr:first td:first");
if ($(cell).text() == "some text"){
}
});
alternatively you could all check the html of the first cell in the if clause by $(cell).html()
To select all tables couldn't be simpler:
$("table")
Adding a filter
$("table:has(td:first:contains('mytext'))")
This will select all the tables:
$("table")
This will select the first TD cell of the first row of each table:
$("table tr:first td:first")
You can get every table by just using jQuery('table'). Whether the tables are in various levels or embedded within divs or whatever doesn't change.
To do additional filtering:
jQuery('table').filter( function() { ... } );
The passed in function will map the table element to this, and you would need to return true to keep it in your collection, or false to discard it.
$('table').each(function(){
$(this).find('tr :first')...
});
If you are wanting to look at the first cell in the first row of each table you can use:
$("table tr:first td:first").each(function() {
var html = this.innerHTML;
/* Iterative logic here */
});
You should try something like $('table tr:first td:first:containts("whatever")') to grab the first cell of the first row with specific content.

Categories