I have a table in html and the first column in each row contains a date. I want to give some sort of separation based on date. So all rows with todays date would be dark grey, yesterdays row would be light grey and then two days ago would be a grey again and so on.
Is there an easy way to do this?
Thanks
To have alternating rows a different colour (with multiple rows having the same date), you'll have to use jQuery to iterate through all the table rows to check whether it should color that row or not.
Below is the jQuery, HTML and CSS for an example.
// iterate over each row
var tableDate = $("#MyTable tbody").parents('tr:first').find('td:first').text();
var shouldColor = true
$("#MyTable tbody tr").each(function(i) {
// find the first td in the row
var value = $(this).find("td:first").text();
// display the value in console
if (value == tableDate) {
if (shouldColor == true) {
$('#MyTable tbody tr:nth-child(' + (i + 1) + ')').addClass("alternate");
}
} else {
if (shouldColor == false) {
shouldColor = true
$('#MyTable tbody tr:nth-child(' + (i + 1) + ')').addClass("alternate");
} else {
shouldColor = false
}
}
tableDate = value
});
#MyTable {
width:100%;
border-collapse:collapse;
}
#MyTable td {
padding:7px; border:blue 1px solid;
}
#MyTable tr {
background: light-grey;
}
#MyTable .alternate {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<table id="MyTable" >
<tbody>
<tr>
<td>4/4/2016</td> <td>Running</td>
</tr>
<tr>
<td>4/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>5/4/2016</td> <td>Running</td>
</tr>
<tr>
<td>6/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>6/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>6/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>6/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>7/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>7/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>8/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>9/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>10/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>11/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>11/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>12/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>12/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>12/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>13/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>13/4/2016</td> <td>Swimming</td>
</tr>
<tr>
<td>13/4/2016</td> <td>Swimming</td>
</tr>
</tbody>
</table>
Related
There is a table:
<table style="width:920px;" id="tblPotrawySkladniki">
<thead>
<tr>
<td class="cell0 style1"><p style="font-style:italic;">Nazwa produktu</p></td>
<td class="cell1 style1"><p style="font-style:italic;">Waga [g]</p></td>
</tr>
</thead>
<tbody>
<tr>
<td>banana</td>
<td>10</td>
</tr>
<tr>
<td>orange</td>
<td>20</td>
</tr>
<tr>
<td>raspberry</td>
<td>35</td>
</tr>
</tbody>
<tfoot>
<tr>
<td class="cell0 style1"><p style="font-weight:bold;">TOTAL</p></td>
<td class="cell1 style1"><p style="font-weight:bold;"></p></td>
</tr>
</tfoot>
</table>
How can I sum up all cells in tbody second column and put the result in tfoot cell also second column?
The table is dynamic. I would like to use jquery.
This would be one way of doing it:
let sum=$("#tblPotrawySkladniki tbody td:nth-child(2)").get().reduce((a,c)=>
+$(c).text().replace(",",".")+a,0);
$("#tblPotrawySkladniki tfoot td:nth-child(2)").text(sum);
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<table id="tblPotrawySkladniki">
<thead>
<tr>
<td class="cell0 style1"><p style="font-style:italic;">Nazwa produktu</p></td>
<td class="cell1 style1"><p style="font-style:italic;">Waga [g]</p></td>
</tr>
</thead>
<tbody>
<tr>
<td>banana</td>
<td>10</td>
</tr>
<tr>
<td>orange</td>
<td>20,3</td>
</tr>
<tr>
<td>raspberry</td>
<td>35,5</td>
</tr>
</tbody>
<tfoot>
<tr>
<td class="cell0 style1"><p style="font-weight:bold;">TOTAL</p></td>
<td class="cell1 style1"><p style="font-weight:bold;"></p></td>
</tr>
</tfoot>
</table>
Instead of parseInt() my script makes use of implicit type conversion with the unary + operator before $(c).text().
You can use jQuery .each() to cycle through the second td of each row, access the contents of the element using $(this).text(), then add them up as you go.
You should parse the value first so that they will add up as numbers and not concatenate.
let values = 0;
jQuery('table tbody tr td:nth-of-type(2)').each(function(){
let value = parseInt($(this).text(),10);
values += value;
});
console.log(values);
<table style="width:920px;" id="tblPotrawySkladniki">
<thead>
<tr>
<td class="cell0 style1">
<p style="font-style:italic;">Nazwa produktu</p>
</td>
<td class="cell1 style1">
<p style="font-style:italic;">Waga [g]</p>
</td>
</tr>
</thead>
<tbody>
<tr>
<td>banana</td>
<td> 10</td>
</tr>
<tr>
<td>orange</td>
<td> <span class='price'>20</span></td>
</tr>
<tr>
<td>raspberry</td>
<td> <span class='price'>35</span></td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="2" style="text-align:center"><span id="sum"></span></th>
</tr>
</tfoot>
$(document).ready(function() {
$('.price').each(function(i) {
calculateColumn(i);
});
});
function calculateColumn(index) {
var total = 0;
$('table tr').each(function() {
var value = parseInt($('.price', this).eq(index).text());
if (!isNaN(value)) {
total += value;
}
});
$('#sum').eq(index).text('Total: ' + total);
}
Let's say there is a table:
<table id="tblPotrawySkladniki">
<tbody>
<tr><td>banana</td><td>10</td></tr>
<tr><td>orange</td><td>20</td></tr>
<tr><td>raspberry</td><td>20</td></tr>
</tbody>
</table>
I would like to remove entire row where i.e. cell1 = orange.
How can I do this using jquery?
Consider the following two examples. Example 1:
$(function() {
$("#tblPotrawySkladniki > tbody td").each(function(i, el) {
if ($(el).text() === "orange") {
$(el).parent().remove();
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tblPotrawySkladniki">
<tbody>
<tr>
<td>banana</td>
<td>10</td>
</tr>
<tr>
<td>orange</td>
<td>20</td>
</tr>
<tr>
<td>raspberry</td>
<td>20</td>
</tr>
</tbody>
</table>
This first example gives you more control over how you compare or seek out the cell. For example, you could use:
$(el).text().trim().toLowerCase() === "orange"
This would help ensure a case insensitive search.
Example 2:
$(function() {
$("#tblPotrawySkladniki > tbody td:contains('orange')").parent().remove();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="tblPotrawySkladniki">
<tbody>
<tr>
<td>banana</td>
<td>10</td>
</tr>
<tr>
<td>orange</td>
<td>20</td>
</tr>
<tr>
<td>raspberry</td>
<td>20</td>
</tr>
</tbody>
</table>
The second example relies on the selector and if they do not match exactly, will not find it. It's quick and uses less lines, yet may not always find the needle.
Each of these, in their own way, will target the Cell and remove the parent Row. See More:
https://api.jquery.com/contains-selector/
https://api.jquery.com/text/
https://api.jquery.com/each/
Here is a dynamic way of doing it. For example, enter Orange or Raspberry into the input and click enter.
$(function() {
$("#inputSearch").on('change', function(){
var v = $(this).val();
$('#tblPotrawySkladniki tr td').filter(function() {
if ($(this).text() === v) {
return true;
}
}).parent().remove();
});
})
table {
margin: 0 auto;
}
tr {
border: 1px solid black;
}
tbody {
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="inputSearch">Search Value:</label>
<input type="text" name="inputSearch" id="inputSearch">
<table id="tblPotrawySkladniki">
<tbody>
<tr><td>banana</td><td>10</td></tr>
<tr><td>orange</td><td>20</td></tr>
<tr><td>raspberry</td><td>20</td></tr>
</tbody>
</table>
I need to make a table with dynamic column sums on a website. Unfortunately, I'm not very good at jQuery. Please help.
[enter image description here][1]
My table in HTML
[1]: https://i.stack.imgur.com/yV2Fo.png
table, td {
border: 1.25px solid black;
}
<table>
<thead>
<tr>
<td> NAME</td>
<td> Name 1 </td>
<td> Name 2 </td>
<td> Name 3 </td>
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
<td><input type="number"</td>
<td><input type="number"</td>
<td><input type="number"</td>
</tr>
<tr>
<td>B</td>
<td><input type="number"</td>
<td><input type="number"</td>
<td><input type="number"</td>
</tr>
<tr>
<td>C</td>
<td><input type="number"</td>
<td><input type="number"</td>
<td><input type="number"</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Total</td>
<td></td>
<td></td>
<td></td>
</tr>
</tfoot>
</table>
I'm not sure how your table is set up. There are different ways you could do it, but I think this could be a solution:
I think something like this is what you are looking for?
Column
Total
A
150
B
100
C
50
Total
200
This is how you can accomplish this:
$(document).ready(() => {
let array = []; // Create an empty array
let sum = 0; // Set sum to 0 - This is only to set the data type to a number
/*
Use Jquery's :nth-child() selector to get target the 2nd cell in the table body
-- You can use :nth-child(3) for the 3rd cell etc...
Then use the $each method to perform a function.
The function will convert this cell's text (Using parseFloat() method) to a number and add (push()) it to our array
*/
$("table tbody td:nth-child(2)").each(function() {
array.push(parseFloat($(this).html()));
});
// Here we will loop over the array and add each value to the sum variable.
for (let i = 0; i < array.length; i++) {
sum += array[i];
}
// Then append the last child (last table cell) in the table's footer with this sum value || Or if you gave the this cell an id, you can use that instead.
$('table tfoot td:last-child').html(sum);
});
/* This can be used over many columns by selecting the different nth-child()'s
*/
table, td {
border: 1.25px solid black;
}
td {
padding: 3px;
text-align: center;
}
td:last-child {
font-weight: bolder;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<!-- Table Heading -->
<thead>
<tr>
<td> Column </td>
<td> Total </td>
</tr>
</thead>
<!-- Table Body -->
<tbody>
<tr>
<td>A</td>
<td>150</td>
</tr>
<tr>
<td>B</td>
<td>100</td>
</tr>
<tr>
<td>C</td>
<td>50</td>
</tr>
</tbody>
<!-- Table Footer -->
<tfoot>
<tr>
<td>Total </td>
<!-- Add an id to this cell for the total or use my method in the js code-->
<td id="tableTotal"></td>
</tr>
</tfoot>
</table>
Please read the comments in the snippet, this will explain the process.
I need to display red background color in <td> that I hovered. For example, if I hovered 'Apple', then 'Apple' in all <td> shall be hovered same color as well. Currently can only hover one <td>Apple</td>.
table {
margin: 2rem;
}
th, td {
border: 1px solid #333;
}
td:hover{
background-color:red
}
html {
font-size: 24px;
}
<h3>Table 1</h3>
<table>
<tr>
<th>Header 1.1</th>
<th>Header 1.2</th>
<th>Header 1.3</th>
</tr>
<tr>
<td>Apple</td>
<td>Orange</td>
<td>Lemon</td>
</tr>
<tr>
<td>Orange</td>
<td>Lemon</td>
<td>Apple</td>
</tr>
</table>
Codepen
You can do that with the help of jQuery. Try running the following snippet.
$('.apple').hover(
function(){
$('.apple').css({"background":"red"});
},function(){
$('.apple').css({"background":"white"});
})
$('.orange').hover(
function(){
$('.orange').css({"background":"orange"});
}
,function(){
$('.orange').css({"background":"white"});
}
)
$('.lemon').hover(
function(){
$('.lemon').css({"background":"yellow"});
}, function(){
$('.lemon').css({"background":"white"});
})
html {
font-size: 24px;
}
table {
margin: 2rem;
}
th, td {
border: 1px solid #333;
}
td span {
display: block;
}
td:hover span.apple {
background-color:red
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3>Table 1</h3>
<table>
<tr>
<th>Header 1.1</th>
<th>Header 1.2</th>
<th>Header 1.3</th>
</tr>
<tr>
<td><span class="apple">Apple</span></td>
<td><span class="orange">Orange</span></td>
<td><span class="lemon">Lemon</span></td>
</tr>
<tr>
<td><span class="orange">Orange</span></td>
<td><span class="lemon">Lemon</span></td>
<td><span class="apple">Apple</span></td>
</tr>
</table>
This cannot be done with just HTML and CSS as CSS is not aware of content.
Using Javascript you can set CSS variables that in turn will set the background of a cell.
This snippet goes through each td element and sets the style background: var(--name of fruit) so for example all apple cells have the style="background: var(--apple);" added to them. Then when a td is hovered the JS sets the --apple to red and when the mouse moves out it sets it to transparent.
That way all those tds with background: var(--apple) get highlighted.
There is no need to iterate through all the cells in the table each time a hover takes place, you can do it by setting everything up once at the start.
function setHighlight(e) {
table.style.setProperty('--' + e.target.textContent, 'red');
}
function removeHighlight(e) {
table.style.setProperty('--' + e.target.textContent, 'transparent');
}
const table = document.querySelector('table');
const tds = document.querySelectorAll('td');
tds.forEach(td => {
td.addEventListener('mouseover', setHighlight);
td.style.backgroundColor = 'var(--' + td.textContent + ')';
});
tds.forEach(td => {
td.addEventListener('mouseout', removeHighlight);
});
<h3>Table 1</h3>
<table>
<tr>
<th>Header 1.1</th>
<th>Header 1.2</th>
<th>Header 1.3</th>
</tr>
<tr>
<td>Apple</td>
<td>Orange</td>
<td>Lemon</td>
</tr>
<tr>
<td>Orange</td>
<td>Lemon</td>
<td>Apple</td>
</tr>
</table>
Add a class in every td and use JQuery.
See the example below.
$(document).ready(function(){
$("td.apple").hover(function(){
$(".apple").css("background-color", "red");
}, function(){
$(".apple").css("background-color", "white");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td class="apple">Apple</td>
<td class="apple">Apple</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td class="apple">Apple</td>
<td>Mexico</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td class="apple">Apple</td>
</tr>
<tr>
<td>Island Trading</td>
<td>Helen Bennett</td>
<td>UK</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Yoshi Tannamuri</td>
<td>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Giovanni Rovelli</td>
<td>Italy</td>
</tr>
</table>
If You don't want to add extra IDs and add jquery as dependency to Your code, You can use vanilla JS
// Get all TDs
const tds = Array.from(document.querySelectorAll("td"));
tds.map(td => {
// bind mouseenter to TDs to paint BG
td.addEventListener("mouseenter", (event) => {
const text = event.target.textContent;
// paint TDs with same text
tds.map(td => {
if(td.textContent === text) {
td.style.background = 'red';
}
});
});
// bind mouseleave to TDs to remove BG
td.addEventListener("mouseleave", (event) => {
tds.map(td => {
td.style.background = 'transparent';
});
})
});
Working example: https://codepen.io/ipasha/pen/eYRKxpP
table {
margin: 2rem;
}
th, td {
border: 1px solid #333;
}
.apple:hover{
background-color:red
}
html {
font-size: 24px;
}
<h3>Table 1</h3>
<table>
<tr>
<th>Header 1.1</th>
<th>Header 1.2</th>
<th>Header 1.3</th>
</tr>
<tr>
<td class="apple">Apple</td>
<td>Orange</td>
<td>Lemon</td>
</tr>
<tr>
<td>Orange</td>
<td>Lemon</td>
<td class="apple">Apple</td>
</tr>
</table>
This is one way you can try:
html {
font-size: 24px;
}
table {
margin: 2rem;
}
th, td {
border: 1px solid #333;
}
td span {
display: block;
}
td:hover span.apple {
background-color:red
}
<h3>Table 1</h3>
<table>
<tr>
<th>Header 1.1</th>
<th>Header 1.2</th>
<th>Header 1.3</th>
</tr>
<tr>
<td><span class="apple">Apple</span></td>
<td><span>Orange</span></td>
<td><span>Lemon</span></td>
</tr>
<tr>
<td><span>Orange</span></td>
<td><span>Lemon</span></td>
<td><span class="apple">Apple</span></td>
</tr>
</table>
I have a table in HTML which I am applying a CSS class using nth-child to give the rows alternating colors. However there are some sets of rows I would like to be the same color. If I put a tbody around these sets of rows, is there a way to specify in CSS to make rows in that tbody the same color, and then continue alternating colors? The alternative is to manually set row colors which seems like a bit too much of a hack.
So for example:
<table class="alternate-row-colors">
<tr>
<td>Blah blah blah</td>
</tr>
<tbody>
<tr>
<td>Same color as below</td>
</tr>
<tr>
<td>Same color as above</td>
</tr>
</tbody>
<tr>
<td>Continue alternating colors of rows</td>
</tr>
</table>
The only solution I can find is to break each section into separate tbody elements and apply the alternate class to the ones with the required styling.
The rows would not completely alternate as the number of rows would, I presume not be known in advance...but it's close.
.alternate-row-colors tr:nth-child(odd) {
background: #bada55;
}
.alternate-row-colors tr:nth-child(even) {
background: gold;
}
<table>
<TBODY class="alternate-row-colors">
<TR>
<TD>Monday</TD>
<TD>09/11/2000</TD>
<TD>Kelsey</TD>
</TR>
<TR>
<TD>Tuesday</TD>
<TD>09/12/2000</TD>
<TD>Lindsey</TD>
</TR>
<TR>
<TD>Wednesday</TD>
<TD>09/13/2000</TD>
<TD>Randy</TD>
</TR>
<TR>
<TD>Thursday</TD>
<TD>09/14/2000</TD>
<TD>Susan</TD>
</TR>
<TR>
<TD>Friday</TD>
<TD>09/15/2000</TD>
<TD>Randy</TD>
</TR>
<TR>
<TD>Saturday</TD>
<TD>09/16/2000</TD>
<TD>Lindsey</TD>
</TR>
<TR>
<TD>Sunday</TD>
<TD>09/17/2000</TD>
<TD>Susan</TD>
</TR>
</TBODY>
<TBODY>
<TR>
<TD>Monday</TD>
<TD>09/18/2000</TD>
<TD>Melody</TD>
</TR>
<TR>
<TD>Tuesday</TD>
<TD>09/19/2000</TD>
<TD>Christiane</TD>
</TR>
<TR>
<TD>Wednesday</TD>
<TD>09/20/2000</TD>
<TD>Symphony</TD>
</TR>
<TR>
<TD>Thursday</TD>
<TD>09/21/2000</TD>
<TD>Starflower</TD>
</TR>
<TR>
<TD>Friday</TD>
<TD>09/22/2000</TD>
<TD>Miko</TD>
</TR>
<TR>
<TD>Saturday</TD>
<TD>09/23/2000</TD>
<TD>Cleo</TD>
</TR>
<TR>
<TD>Sunday</TD>
<TD>09/24/2000</TD>
<TD>Alyx</TD>
</TR>
</TBODY>
<TBODY class="alternate-row-colors">
<TR>
<TD>Monday</TD>
<TD>09/25/2000</TD>
<TD>Dancing Star</TD>
</TR>
<TR>
<TD>Tuesday</TD>
<TD>09/26/2000</TD>
<TD>Dawn</TD>
</TR>
<TR>
<TD>Wednesday</TD>
<TD>09/27/2000</TD>
<TD>Josh</TD>
</TR>
<TR>
<TD>Thursday</TD>
<TD>09/28/2000</TD>
<TD>Ryan</TD>
</TR>
<TR>
<TD>Friday</TD>
<TD>09/29/2000</TD>
<TD>Mary Kay</TD>
</TR>
<TR>
<TD>Saturday</TD>
<TD>09/30/2000</TD>
<TD>Hallie</TD>
</TR>
<TR>
<TD>Sunday</TD>
<TD>10/01/2000</TD>
<TD>Paul</TD>
</TR>
</TBODY>
</table>
If you are wanting to use the <tbody> type of element to hold the 'same colour' blocks then using the nth-child element is easy using the direct selector > thus:
.alternate-row-colors > tr:nth-child(even) {
background-color: #A4D1FF;
}
.alternate-row-colors > tr:nth-child(odd) {
background-color: #EAF4FF;
}
This will then only effect the tr elements which are direct descendent of the class.
How about
CSS
.alternate-row-colors > tr:nth-child(odd) {
background-color: hsla(0, 0%, 0%, .2);
}
.alternate-row-colors > tr:nth-child(even), .alternate-row-colors-solid {
background-color: hsla(0, 0%, 0%, .4);
}
Or set as a third color
.alternate-row-colors-solid {
background-color: blue;
}
And if you want to group than create a table in a table i suspect is the easiest method.
HTML
<table class="alternate-row-colors">
<tr>
<td>Zebra coloring</td>
</tr>
<tr>
<td>Zebra coloring</td>
</tr>
<tr>
<td>
<table class="alternate-row-colors-solid">
<tr>
<td>Same color</td>
</tr>
<tr>
<td>same color</td>
</tr>
<tr>
<td>same color</td>
</tr>
</table></td>
</tr>
<tr>
<td>Zebra coloring</td>
</tr>
<tr>
<td>Zebra coloring</td>
</tr>
</table>
.alternate-row-colors .alternate-row-colors-solid > tr {
background-color: orange;
}
And than set the second table and its childs with width and height of 100% remove padding, margin and so on so they dont look like a sub table.