Coloring every second row with rowspan - javascript

I want to color every second row of a table. While every regular table can be colored using this:
$('tr:odd').css( "background-color", "orange" );
In my case there are several rowspan, what makes the task more difficult.
This is my desired output:
Using this code above doesn't lead to the desired result:
Here is a fiddle.
$('tr:odd').css("background-color", "orange");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border="1">
<tr>
<td>Col 1</td>
<td>Col 2</td>
<td>Col 3</td>
</tr>
<tr>
<td rowspan="2">Col 1</td>
<td>Col 2</td>
<td rowspan="2">Col 3</td>
</tr>
<tr>
<td>Col 1</td>
</tr>
<tr>
<td>Col 1</td>
<td>Col 2</td>
<td>Col 3</td>
</tr>
<tr>
<td rowspan="2">Col 1</td>
<td rowspan="2">Col 2</td>
<td>Col 3</td>
</tr>
<tr>
<td>Col 1</td>
</tr>
<tr>
<td>Col 1</td>
<td>Col 2</td>
<td>Col 3</td>
</tr>
</table>

Do something like this:
$("table tr").filter(function() {
return $(this).children().length == 3;
}).filter(':odd').addClass('alt');
$("tr.alt td[rowspan]").each(function() {
$(this).parent().nextAll().slice(0, this.rowSpan - 1).addClass('alt');
});
.alt { background-color: orange; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table border="1">
<tr>
<td>Col 1</td>
<td>Col 2</td>
<td>Col 3</td>
</tr>
<tr>
<td rowspan="2">Col 1</td>
<td>Col 2</td>
<td rowspan="2">Col 3</td>
</tr>
<tr>
<td>Col 1</td>
</tr>
<tr>
<td>Col 1</td>
<td>Col 2</td>
<td>Col 3</td>
</tr>
<tr>
<td rowspan="2">Col 1</td>
<td rowspan="2">Col 2</td>
<td>Col 3</td>
</tr>
<tr>
<td>Col 1</td>
</tr>
<tr>
<td>Col 1</td>
<td>Col 2</td>
<td>Col 3</td>
</tr>
</table>

Related

Sticky header inside a container

I have a table that is in a container on a page. I am trying to get the headers of the table to stick to the top of the page when the user scrolls past. I have tried multiple methods to make the headers sticky but I am not having much luck.
The table data is being generated in JS.
Any help would be great!
HTML
<div class="container-fluid">
<div id="userTable" class="sticky-table">
<table id="ticketsTable">
<thead id="head" class="sticky-header"</thead>
<tbody id="body">
</tbody>
</table>
</div>
</div>
JavaScript
function generateTableHeader() {
var headerArray = generateHeaderArray(),
headerString = "<thead id='head'><tr>" + "<th></th>";
if (!headerArray.length) {
$("#head").empty();
$("#userTable").append("<h1 id='noTicketsFound'>No tickets found.</h1>");
return;
}
headerOrder.forEach(function(key) {
var isChecked = key;
if (!$(".dropdown-menu-fixed #" + key).is(":checked")) {
isChecked += " uncheckedColumn";
}
headerString += "<th data-property='" + key + "' class='sortableHeader " + isChecked + "'>" +
dictionary[key] + "</th>";
});
headerString += "</tr></thead>";
// replaceWith seems faster than separate calls to empty then append.
$("#head").replaceWith(headerString);
// Add SORTCLASS to SORTPROPERTY column, since that is already sorted.
$(".sortableHeader." + SORTPROPERTY).addClass(SORTCLASS);
}
make headers sticky on scroll function
function stickyTableHeader() {
$(".sticky-table").each(function() {
var el = $(this),
offset = el.offset(),
scrollTop = $(window).scrollTop(),
stickyHeader = $(".stickyHeader", this);
if (scrollTop > offset.top && scrollTop < offset.top + el.height()) {
stickyHeader.css({
visibility: "visible"
});
} else {
stickyHeader.css({
visibility: "hidden"
});
}
});
}
// DOM Ready
$(function() {
var clonedHeaderRow;
$(".sticky-table").each(function() {
clonedHeaderRow = $(".sticky-header", this);
clonedHeaderRow
.before(clonedHeaderRow.clone())
.css("width", clonedHeaderRow.width())
.addClass("stickyHeader");
});
$(window)
.scroll(stickyTableHeader)
.trigger("scroll");
});
This is pretty simple using CSS:
th {
position: sticky;
top: 0;
background: #eee;
}
td, th {
padding: 10px;
}
<div class="container">
<h1>Some Title</h1>
<table>
<thead>
<tr>
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
</tbody>
</table>
</div>
I believe the position:sticky; is not yet supported by all browsers.
I have a solution that is a bit heavy-handed but it works across all browsers. Basically you use one Div as a mask over another Div.
Both of these divs contain the same exact table.
The mask-div will effectively crop the table to show only the thead.
<div class = 'mask-div'>
<table>Copy of Table A</table>
</div>
<div class='scrolling-div">
<table> Table A </table>
</div>
<style>
div{
top:0px;
left:0px;
}
.mask-div{
width:100%;
position: fixed;
height:40px;
overflow: hidden;
background:white;
}
<style>
th {
position: sticky;
top: 0;
background: #eee;
}
td, th {
padding: 10px;
}
<div class="container">
<h1>Some Title</h1>
<table>
<thead>
<tr>
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
<tr>
<td>Thing 1</td>
<td>Thing 2</td>
<td>Thing 3</td>
</tr>
</tbody>
</table>
</div>

How to remove the contents of a <td> in a table dynamically using JS

I want when the user clicks the button with the class name "removeElement" the next "td" with class "forRemove" should have its contents removed.
How can I do it?
<table class="table">
<tbody class="list" id="list">
<tr>
<td>BODY 1</td>
<td>BODY 2</td>
<td>
<button class="removeElement">removeNextTd</button>
</td>
<td class="forRemove">BODY 4</td>
</tr>
<tr>
<td>BODY 1</td>
<td>BODY 2</td>
<td>
<button class="removeElement">removeNextTd</button>
</td>
<td class="forRemove">BODY 4</td>
</tr>
<tr>
<td>BODY 1</td>
<td>BODY 2</td>
<td>
<button class="removeElement">removeNextTd</button>
</td>
<td class="forRemove">BODY 4</td>
</tr>
</tbody>
</table>
The solution to your problem is here.
$('.removeElement').click(function(e){
$(this).parent().next().remove();
});
Also, I create the fiddle for you.
checkout this
<table class="table">
<tbody class="list" id="list">
<tr>
<td>BODY 1</td>
<td>BODY 2</td>
<td>
<button class="removeElement">removeNextTd</button>
</td>
<td class="forRemove">BODY 4</td>
</tr>
<tr>
<td>BODY 1</td>
<td>BODY 2</td>
<td>
<button class="removeElement">removeNextTd</button>
</td>
<td class="forRemove">BODY 4</td>
</tr>
<tr>
<td>BODY 1</td>
<td>BODY 2</td>
<td>
<button class="removeElement">removeNextTd</button>
</td>
<td class="forRemove">BODY 4</td>
</tr>
</tbody>
</table>
<script>
const buttons = document.getElementsByClassName('removeElement');
for(let i =0; i < buttons.length; ++i) {
buttons[i].onclick = function(event) {
const parent = event.currentTarget.parentNode.parentNode;
parent.children[parent.children.length - 1].innerHTML = "";
}
}
</script>
Is this more or less what you're looking for? To be honest I wouldn't access table elements like this, this is doing a bit much for such simple functionality, for exmaple, on the buttons I would add an indexer at the end of the class name or id, I would use IDs for in this case not only because is faster but also because you'd want quicker access to these elements without the hassle of having to go through so many nodes. i.e.:
<table class="table">
<tbody class="list" id="list">
<tr>
<td>BODY 1</td>
<td>BODY 2</td>
<td>
<button id="removeElement-0" class="removeElement">removeNextTd</button>
</td>
<td class="forRemove-0">BODY 4</td>
</tr>
<tr>
<td>BODY 1</td>
<td>BODY 2</td>
<td>
<button id="removeElement-1" class="removeElement">removeNextTd</button>
</td>
<td class="forRemove-1">BODY 4</td>
</tr>
<tr>
<td>BODY 1</td>
<td>BODY 2</td>
<td>
<button id="removeElement-2" class="removeElement">removeNextTd</button>
</td>
<td class="forRemove-2">BODY 4</td>
</tr>
</tbody>
</table>
<script>
const buttons = document.getElementsByClassName('removeElement');
for(let i =0; i < buttons.length; ++i) {
buttons[i].onclick = function(event) {
document.getElementsByClassName("forRemove-"+event.currentTarget.id[event.currentTarget.id.length-1])[0].innerHTML = "";
}
}
</script>
But Whatever works for you mate.
This clears the td. It is still there so the table wouldn't brake, but it is emty.
$('.removeElement').on('click', function() {
$(this).closest('tr').find('.forRemove').empty();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table">
<tbody class="list" id="list">
<tr>
<td>BODY 1</td>
<td>BODY 2</td>
<td>
<button class="removeElement">removeNextTd</button>
</td>
<td class="forRemove">BODY 4</td>
</tr>
<tr>
<td>BODY 1</td>
<td>BODY 2</td>
<td>
<button class="removeElement">removeNextTd</button>
</td>
<td class="forRemove">BODY 4</td>
</tr>
<tr>
<td>BODY 1</td>
<td>BODY 2</td>
<td>
<button class="removeElement">removeNextTd</button>
</td>
<td class="forRemove">BODY 4</td>
</tr>
</tbody>
</table>
This will remove the contents of the next TD, with the class forRemove
$(".removeElement").on("click", function() {
$(this).closest("tr").find(".forRemove").empty();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table class="table">
<tbody class="list" id="list">
<tr>
<td>BODY 1</td>
<td>BODY 2</td>
<td>
<button class="removeElement">removeNextTd</button>
</td>
<td class="forRemove">BODY 4</td>
</tr>
<tr>
<td>BODY 1</td>
<td>BODY 2</td>
<td>
<button class="removeElement">removeNextTd</button>
</td>
<td class="forRemove">BODY 4</td>
</tr>
<tr>
<td>BODY 1</td>
<td>BODY 2</td>
<td>
<button class="removeElement">removeNextTd</button>
</td>
<td class="forRemove">BODY 4</td>
</tr>
</tbody>
</table>
In short, when you click the button it will find the nearest tr element by traversing up the DOM tree, and then find the element within that with the class forRemove, and then empty() it.
not exactly what you asked but you can do it like this with jquery
$this .parent()
.parent()
.remove();
since the delete button is within the row you want to delete this should work

Hide all the rows after a specific row

I'm developing an ASP.NET MVC application with C#, .NET Framework 4.7 and jQuery 3.1.1.
I have a view with a table:
<table id="myTable">
<tbody>
<tr> ... </tr>
<tr> ... </tr>
<tr> ... </tr>
<tr id="row_x"> ... </tr>
<tr> ... </tr>
<tr> ... </tr>
<tr> ... </tr>
...
I want to hide all the rows under the row <tr id="row_x"> ... </tr> but I don't know how to access those rows. Do I need to set an id to all of them?
I've thought to surround them with a <div> but I don't think it is a good idea or possible.
You can use the jQuery method nextAll()
$("#row_x").nextAll().hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
<tbody>
<tr>
<td>Row 1</td>
</tr>
<tr>
<td>Row 2</td>
</tr>
<tr>
<td>Row 3</td>
</tr>
<tr>
<td>Row 4</td>
</tr>
<tr id="row_x">
<td>Row 5</td>
</tr>
<tr>
<td>Row 6</td>
</tr>
<tr>
<td>Row 7</td>
</tr>
<tr>
<td>Row 8</td>
</tr>
<tr>
<td>Row 9</td>
</tr>
</tbody>
</table>
$("#row_x").nextAll('tr').hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
<tbody>
<tr>
<td>Row 1</td>
</tr>
<tr>
<td>Row 2</td>
</tr>
<tr>
<td>Row 3</td>
</tr>
<tr>
<td>Row 4</td>
</tr>
<tr id="row_x">
<td>Row 5</td>
</tr>
<tr>
<td>Row 6</td>
</tr>
<tr>
<td>Row 7</td>
</tr>
<tr>
<td>Row 8</td>
</tr>
<tr>
<td>Row 9</td>
</tr>
</tbody>
</table>
Just try like this
$('#row_x').nextAll('tr').hide();

JQUERY - Hide all table cells underneath table columns based on cell class

we are currently developing an internal report for a client and I can't quite crack this one...
I have a HTML table with a variable amount of column headers and then a variable amount of data rows. Each in the table is assigned a class of either 'td-Red' 'td-Green' or 'td-Grey'. This controls the colour of the cell.
If all of a column's tds have the 'td-Grey' class, we want to hide the entire column including the header.
I'm sure this can be done with jQuery but I'm failing to do so...
Is anybody able to help?
Loop through the headings , use heading index to filter data cells in each column that also have the grey class. Compare length of that collection to total rows and hide accordingly
var $dataRows = $('#myTable tbody tr'),
rowCount = $dataRows.length;
$('#myTable thead th').each(function(i){
var $greyCells = $dataRows.find('td:eq(' + i + ').td-Grey');
if($greyCells.length === rowCount){
$greyCells.add(this).hide();
console.log('Hiding column index = ',i)
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
<thead>
<tr>
<th>Heading 1</th>
<th>Heading 2</th>
<th>Heading 3</th>
<th>Heading 4</th>
<th>Heading 5</th>
</tr>
</thead>
<tbody>
<tr>
<td class="td-Grey">Col 1</td>
<td>Col 2</td>
<td>Col 3</td>
<td class="td-Grey">Col 4</td>
<td>Col 5</td>
</tr>
<tr>
<td class="td-Grey">Col 1</td>
<td>Col 2</td>
<td>Col 3</td>
<td class="td-Grey">Col 4</td>
<td>Col 5</td>
</tr>
<tr>
<td class="td-Grey">Col 1</td>
<td>Col 2</td>
<td>Col 3</td>
<td class="td-Grey">Col 4</td>
<td>Col 5</td>
</tr>
<tr>
<td class="td-Grey">Col 1</td>
<td>Col 2</td>
<td>Col 3</td>
<td class="td-Grey">Col 4</td>
<td>Col 5</td>
</tr>
<tr>
<td class="td-Grey">Col 1</td>
<td>Col 2</td>
<td>Col 3</td>
<td class="td-Grey">Col 4</td>
<td>Col 5</td>
</tr>
</tbody>
</table>

html table rows height issue

Okay so I made that table which I want it too look like a gradebook but I cant edit the row heights.
In the picture below I drew a line around the rows I want their size to be decrease so they can look different than the student's rows.
and heres the HTML
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="col-lg-12 table-responsive">
<table class="table table-bordered" style="background-color:white;">
<tbody>
<tr>
<th rowspan="4">Student</th>
<th>Assignment</th>
<td>Assignment 1</td>
<td>Assignment 2</td>
<td>Assignment 3</td>
<td>Assignment 4</td>
</tr>
<div>
<tr>
<th>Category:</th>
<td>Category 1</td>
<td>Category 2</td>
<td>Category 3</td>
<td>Category 4</td>
</tr></div>
<tr>
<th>Due:</th>
<td>Due 1</td>
<td>Due 2</td>
<td>Due 3</td>
<td>Due 4</td>
</tr>
<tr>
<th>Points:</th>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>Moemen Waleed</td>
<td>90% A-</td>
<td>Moemen 1</td>
<td>Moemen 2</td>
<td>Moemen 3</td>
<td>Moemen 4</td>
</tr>
<tr>
<td>Mazen Waleed</td>
<td>93% A</td>
<td>Mazen 1</td>
<td>Mazen 2</td>
<td>Mazen 3</td>
<td>Mazen 4</td>
</tr>
</tbody>
</table>
</div>
Add this style to your hmtl:
<style>
tr:nth-child(-n+4){
line-height: 10px;
min-height: 10px;
height: 10px;
}
</style>
This styles all first four rows in the table.
Here is the result: https://jsfiddle.net/Lbx8xh1a/4/
You can add line-height to that <tr> tags.
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="col-lg-12 table-responsive">
<table class="table table-bordered" style="background-color:white;">
<tbody>
<tr style="line-height: 6px;">
<th rowspan="4">Student</th>
<th>Assignment</th>
<td>Assignment 1</td>
<td>Assignment 2</td>
<td>Assignment 3</td>
<td>Assignment 4</td>
</tr>
<div>
<tr style="line-height: 6px;">
<th>Category:</th>
<td>Category 1</td>
<td>Category 2</td>
<td>Category 3</td>
<td>Category 4</td>
</tr></div>
<tr style="line-height: 6px;">
<th>Due:</th>
<td>Due 1</td>
<td>Due 2</td>
<td>Due 3</td>
<td>Due 4</td>
</tr>
<tr style="line-height: 6px;">
<th>Points:</th>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>Moemen Waleed</td>
<td>90% A-</td>
<td>Moemen 1</td>
<td>Moemen 2</td>
<td>Moemen 3</td>
<td>Moemen 4</td>
</tr>
<tr>
<td>Mazen Waleed</td>
<td>93% A</td>
<td>Mazen 1</td>
<td>Mazen 2</td>
<td>Mazen 3</td>
<td>Mazen 4</td>
</tr>
</tbody>
</table>
</div>

Categories