Color table row based on column value - javascript

I have an html table and I want to color the rows based on the value in the first column of that row. If the value is "CONFIRMED" I want to color the row green, and if it is "UNCONFIRMED" I want to color the row red.
The JS I am using to do this is:
$(function(){
$("tr").each(function(){
var col_val = $(this).find("td:eq(1)").text();
if (col_val == "CONFIRMED"){
$(this).addClass('selected'); //the selected class colors the row green//
} else {
$(this).addClass('bad');
}
});
});
The CSS looks like this:
.selected {
background-color: green;
color: #FFF;
}
.bad {
background-color: red;
color: #FFF;
}
The html table is generated from a pandas dataframe in my Django view and passed in like this:
<div class="table-responsive" style="margin-left: 15%; margin-right: 15%; overflow:auto;">
{{ datatable | safe }}
</div>
The problem is that it's coloring all of my rows red. Can anyone tell me what I'm doing wrong?

Since you use ==="CONFIRMED" make sure it's really: UPPERCASE, and that there's no leading or ending spaces " CONFIRMED" or "CONFIRMED " in the HTML.
The code you're showing will color .selected the entire row whos :eq(1) TD has the "CONFIRMED" content:
$(function(){
$("tr").each(function(){
var col_val = $(this).find("td:eq(1)").text();
if (col_val == "CONFIRMED"){
$(this).addClass('selected'); //the selected class colors the row green//
} else {
$(this).addClass('bad');
}
});
});
.selected{
background-color:green;
}
.bad{
background-color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>1</td><td>CONFIRMED</td>
</tr>
<tr>
<td>2</td><td>UNCONFIRMED</td>
</tr>
</table>
nothing bad about it.
if that's not what you see on your screen note that :eq() is index based, and elements index start at 0 so :eq(0) is probably what you want?
Another probable thing is that you don't have the exact content string set as "CONFIRMED" but probably there's some spaces before or after - so make sure to trim them using $.trim()
if( $.trim(col_val) === "CONFIRMED" )
if you additionally want to make your code even more flexible about the UPPERCASE or Capitalization you can do as:
if( $.trim(col_val.toLowerCase() ) === "confirmed" )
// Will work on "CONFIRMED", "Confirmed", "conFIRMed" etc

<style>
tr[data-stat="confirmed"]{
background-color: green;
color: #fff;
}
tr[data-stat="unconfirmed"]{
background-color: red;
color: #fff;
}
</style>
<table>
<tr data-stat="confirmed">
<td>1</td>
<td>Confirmed</td>
<td>bla.. bla.. bla..</td>
</tr>
<tr data-stat="unconfirmed">
<td>2</td>
<td>Not Confirmed</td>
<td>bla.. bla.. bla..</td>
</tr>
</table>

To find the first column in a row, you want to use the first-child selector. You can iterate over every first column with the each function.
We then look at the text and then add the appropriate class to the column's parent (tr).
$(document).ready(function() {
$("td:first-child").each(function() {
if ($(this).text() === "Confirmed") {
$(this).parent().addClass("green");
}
else {
$(this).parent().addClass("red");
}
});
});
http://jsfiddle.net/cw43ejjf/

If you are looking for the first column in the row you want to use:
var col_val = $(this).find("td:eq(0)").text();
Change the td:eq(1) to td:eq(0)

Related

How to send the element object as parameter to javascript function without ID

In function ClickedRow, i want to use the "a" which is being clicked. So i want to receive it as a parameter.
<td ...... >
<span class="......>
<span onmousedown="event.cancelBubble = true">
<a class="GridLinkRenderer" href="javascript:ClickedRow(this)" onclicklink="javascript:ClickedRow(this)" urlText="XXXX">
<td ......
<span class="......>
<span onmousedown="event.cancelBubble = true">
<a class="GridLinkRenderer" href="javascript:ClickedRow(this)" onclicklink="javascript:ClickedRow(this)" urlText="XXXXX">
Based on clicked <a ....> I would like to hide/show it (or to show/hide next <a class= "GridLinkRenderer" in other <td ...>) by function ClickedRow(this).
How can I do it ?
I've tried to send the clicked $(row).next().eq(0).tagName and row.style.display = 'none' , it says that it is "undefined".
function ClickedRow(row){
$(row).next().eq(0).hide();
$(row).hide();
}
Instead of this, remove href and use
$('#TheidOfTheA').on('click'function(){
let myAElement = $(this);
}
have you looked at closest(),find() and next() ?
https://api.jquery.com/closest/
https://api.jquery.com/next/
https://api.jquery.com/find/
$(row).closest('td').next('td').find('.GridLinkRenderer')
haven't tested this.. but if I'm thinking right this should be at least the point to right direction.
I can't tell by OP if the td are being used in a tr and the tr in a table as it should so I'll just mention real quick that it's invalid HTML should there be any td without a tr as a parent and it's invalid HTML having a tr without a table as its ancestor.
If starting at a tag nested within a td you'll need to climb out:
$(this).closest('td')...
Once at the cell level look around for the cells to the left: ....prev('td'), or to the right: ....next('td') or both: ....siblings('td'). Then go down each td and find the link nested within and turn it off/on: ....find('.gLR').fadeToggle();
$(this).closest('td').siblings('td').find('.gLR').fadeToggle();
$('.gLR').not('.g5').hide();
$('.gLR').on('click', function(e) {
if ($(this).hasClass('g5')) {
$('.gDir').fadeToggle();
} else if ($(this).hasClass('g1') || $(this).hasClass('g9')) {
const cell = $(this).closest('td');
cell.siblings('td').find('.gLR').fadeToggle();
} else if ($(this).hasClass('g4')) {
$(this).closest('td').prev('td').find('.gLR').fadeToggle();
} else if ($(this).hasClass('g6')) {
$(this).closest('td').next('td').find('.gLR').fadeToggle();
} else {
return false;
}
});
:root {
font: 700 5vw/1.5 Consolas
}
table {
table-layout: fixed;
border-collapse: collapse;
}
td {
width: 20%;
text-align: center
}
a {
display: block;
height: 10vh;
text-decoration: none;
color: cyan;
}
a:hover {
color: tomato;
}
a.g5:hover {
font-size: 0;
}
a.g5:hover::after {
content: '\1f536';
font-size: 5vw;
}
td b {
display: block;
height: 10vh;
}
<table>
<tr class='gRA'>
<td colspan='2'>
<b>🌈</b>
</td>
<td><b>⮝</b></td>
<td colspan='2'>
<b>🦄</b>
</td>
</tr>
<tr class='gRB'>
<td><b>🏰</b></td>
<td><b>⮜</b></td>
<td><b>🔷</b></td>
<td><b>⮞</b></td>
<td><b>🏯</b></td>
</tr>
<tr class='gRC'>
<td colspan='2'>
<b>🔥</b>
</td>
<td><b>⮟</b></td>
<td colspan='2'>
<b>💀</b>
</td>
</tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I tried both recommendations(thx for it) - no success.
It looks that the "this" argument is not passed like clicked element(object) reference.
The parameter "row" seems to be like parent of all object, so like new Object and not the clicked object.
I am not sure if href="javascript:ClickedRow(this)" onclicklink="javascript:ClickedRow(this)" is correct syntax though.
so copied Your sample and came up with this. ;) try this out.. and
make sure You understand what's happening here.
$(() => {
$("body").on("click",".GridLinkRenderer", (e) => {
e.preventDefault();
//works on the first link.. stil misses a few check..
//for example do we have the next td.. at all..
console.log($(e.currentTarget).closest('td').next('td').find('.GridLinkRenderer'));
})
});

Change Div Class On Each Click

I am building Bootstrap HTML and PHP website. Basically I need a solution so that when a div is clicked on it changes color and adds some text.
I can do this however I need a solution so that it can be done 3 times, bronze, silver and gold in this instance.
Below is my JSFiddle which shows it working, it changes to bronze and inserts the text as it should however the second click will not work and the third click won't work.
https://jsfiddle.net/vvecu9qa/1/
Hope that makes sense,
Thanks in advance guys!
HTML
<table class="table table-bordered">
<tbody>
<tr>
<td>Name</td>
<td>Spin on a variety of body parts</td>
<td>Spin with control and body tension</td>
<td>Spin in a variety of shapes</td>
<td>Identify appropriate places to perform a spin</td>
</tr>
<tr>
<td>Jon Smith</td>
<td class="progress1"> </td>
<td class="progress2"> </td>
<td class="progress3"> </td>
<td class="progress4"> </td>
</tr>
</tbody>
CSS
.emerging {
background-color: #cd7f32;
color: #fff;
text-align: center;
}
.expected {
background-color: #c0c0c0;
color: #fff;
text-align: center;
}
.exceeding {
background-color: #ffd700;
color: #fff;
text-align: center;
}
JavaScript
$('.progress1').click(function(){
$(".progress1").removeClass("progress1");
$(this).addClass('emerging');
$(this).text('Emerging');
});
$('.emerging').click(function(){
$(".emerging").removeClass("emerging");
$(this).addClass('expected');
$(this).text('Expected');
});
$('.expected').click(function(){
$(".expected").removeClass("expected");
$(this).addClass('exceeding');
$(this).text('Exceeding');
});
change your script like this, it will work
$(document).on("click",'.progress1',function(){
$(".progress1").removeClass("progress1");
$(this).addClass('emerging');
$(this).text('Emerging');
});
$(document).on("click",'.emerging',function(){
$(".emerging").removeClass("emerging");
$(this).addClass('expected');
$(this).text('Expected');
});
$(document).on("click",'.expected',function(){
$(".expected").removeClass("expected");
$(this).addClass('exceeding');
$(this).text('Exceeding');
});
here is the updated fiddle link
Since you only have 3 scenarios, your approach is fine. However, a more intuitive approach would be to create an array and an index, then cycle through them. This way you would only need one click event instead of 1 per step.
Updated Fiddle Here
var classes = ['emerging', 'expected', 'exceeding'];
var index = 0;
$('.progress1').click(function(){
$(this).removeClass(); //Removes all classes
$(this).addClass(classes[index]);
$(this).text(classes[index]);
if(index == (classes.length - 1)) {
index = 0; //Reset index at end of array
} else {
index++; //Increment index if not at the end of array
}
});
Try this approach. I have used the data attribute to make it a bit cleaner.
https://jsfiddle.net/mvinayakam/m4q3rgrq/
<td class="progress" data-progress="base" ><span> <span></td>
The Javascript part
$('.progress').click(function(){
progressAttr=this.getAttribute('data-progress');
switch (progressAttr)
{
case "base":
this.setAttribute('data-progress',"emerging");
break;
case "emerging":
this.setAttribute('data-progress',"exceeding");
break;
}
});
The CSS
[data-progress="emerging"] {
/* Styles */
background-color: #cd7f32;
color: #fff;
text-align: center;
}
[data-progress="emerging"]:after {
content:"Emerging";
}

Replace HTML content and revert on hover

I have a HTML table filled with short sentences in two colors.
I want to cover the text with bars of corresponding colors and, when each block is hovered, the content has to revert to its original HTML state.
I would like to do the following either with JS or CSS:
leave the default HTML table as-is
switch the original content via javascript to a sequence of ASCII 219 / &block / █
make it switch to "original" content when each block (e.g. "last week tonight with J.Oliver) is hovered.
Any help with this method, or a more efficient method, is appreciated. Thanks!
EDIT / a similar code might do it for me, the only thing i miss is the "original content" word:
div:hover span {display:**ORIGINAL CONTENT**}
div:hover:before {content:"&block;&block;&block;&block;&block;"}
You can get a similar effect with just CSS - set the same color and background on the cells, then switch to something readable on hover:
.red {
color: red;
background-color: red;
}
.blue {
color: blue;
background-color: blue;
}
.revealer:hover td {
color: black;
background-color: white;
}
<div class="revealer">
<table>
<tr>
<td class="red">One</td>
<td class="blue">Two</td>
</tr>
<tr>
<td class="red">Three</td>
<td class="blue">Four</td>
</tr>
</table>
</div>
If you include jQuery, this will do what you originally requested:
$(function(){
$('td').each(function(idx){
$(this).data().originaltext = $(this).text();
$(this).html(fill_with_blocks($(this).data().originaltext));
})
$('td').hover(function(){
$(this).html($(this).data().originaltext);
},
function(){
$(this).html(fill_with_blocks($(this).data().originaltext));
});
});
function fill_with_blocks(str) {
var blocks = '';
for(var i = 0;i<str.length;i++){
blocks += '█';
}
return blocks;
}

Disabled inputs in bootstrap. How to apply it to a different TAG?

By using disabled attribute on an input is possible to prevent user input and trigger a slightly different look.
Here is the demo http://jsfiddle.net/D2RLR/3023/
Let's suppose I want to apply the same style to a different TAG like a table.
In fact, I am using handsontable to generate an Excel-like data grid editor.
How can I apply disabled attribute in the following context (TAG like a table)?
Here is the demo using handsontable and bootstrap http://jsfiddle.net/D2RLR/3025/
You can't apply Bootstrap's existing input[disabled] styling, but you can add new CSS that mimics the styles exactly.
For example:
#exampleGrid td {
cursor: not-allowed;
background-color: #EEE;
color: #9E9999;
}
Obviously this doesn't include your readonly logic, and looks a little weird with your fiddle (because the column and row headers are the same color), but that's the gist of it.
Check here:
http://handsontable.com/demo/conditional.html
There is .readOnly cell property - use it!
HTML inputs also have readonly property, not only disabled property, an there are some considerable differences between their behaviour.
Boostrap is only styling the inputs based on their disabled attribute like:
input[disabled], select[disabled], textarea[disabled], input[readonly], select[readonly], textarea[readonly] {
background-color: #EEEEEE;
cursor: not-allowed;
}
So you won't be able to use bootstrap to do that, because tables don't have such attribute.
You should use a plugin of sorts or roll your own.
Maybe this can help... changes the look of the cell and you can edit on it.
HTML
<table class="editableTable">
<thead>
<tr>
<th>Code</th>
<th>Name</th>
<th>E-mail</th>
<th>Telephone</th>
</tr>
</thead>
<tbody>
<tr>
<td>001</td>
<td>João Carlos</td>
<td>joca#email.com</td>
<td>(21) 9999-8888</td>
</tr>
<tr>
<td>002</td>
<td>Maria Silva</td>
<td>mariasilva#mail.com</td>
<td>(81) 8787-8686</td>
</tr>
<tr>
<td>003</td>
<td>José Pedro</td>
<td>zepedro#meuemail.com</td>
<td>(84) 3232-3232</td>
</tr>
</tbody>
</table>
CSS
* {
font-family: Consolas;
}
.editableTable {
border: solid 1px;
width: 100%
}
.editableTable td {
border: solid 1px;
}
.editableTable .editingCell {
padding: 0;
}
.editableTable .editingCell input[type=text] {
width: 100%;
border: 0;
background-color: rgb(255,253,210);
}
JS
$(function () {
$("td").dblclick(function () {
var originalContent = $(this).text();
$(this).addClass("editingCell");
$(this).html("<input type='text' value='" + originalContent + "' />");
$(this).children().first().focus();
$(this).children().first().keypress(function (e) {
if (e.which == 13) {
var newContent = $(this).val();
$(this).parent().text(newContent);
$(this).parent().removeClass("editingCell");
}
});
$(this).children().first().blur(function(){
$(this).parent().text(originalContent);
$(this).parent().removeClass("editingCell");
});
});
});

Automatically add class with jQuery

<table>
<thead>
<tr>
<td>sf</td>
</tr>
<tr>
<td>sf</td>
</tr>
<tr>
<td>sf</td>
</tr>
<tr>
<td>sf</td>
</tr>
</thead>
</table>
.red {
background-color: red;
}
.green {
background-color: green;
}
How can i make automatically add class red and green for TR with jQuery?
LIVE EXAMPLE: http://jsfiddle.net/2Htwx/
$('tr:odd').addClass('red');
$('tr:even').addClass('green');​
Assuming you want every other row red or green, as per your JS-fiddle. Note that this is within each table, so you won't see red/green/red across ALL table rows.
If you want that, try this:
var oddFilter = function(index) {
console.log(index);
return (index % 2) == 1;
},
evenFilter = function(index) {
console.log(index);
return (index % 2) == 0;
}
$('tr').filter(oddFilter).addClass('red').end()
.filter(evenFilter).addClass('green');​
Note that <thead>, <tfoot> etc can still mess up the display, since that moves rows around the display.
You don't need JavaScript to accomplish this 'table-striping' effect. Use of the CSS nth-child selector will do the trick
thead tr {
background: green; /* Set all tr elements to green */
}
thead tr:nth-child(even) {
background: red; /* Override the colour for just the even ones */
}
Note: This selector is not supported in older browsers. IE8 and down.
Further reading on CSS nth-child:
http://css-tricks.com/how-nth-child-works/
You mean like this?
$(document).ready(function() {
var class = "";
$("tr").each(function(idx, elem) {
class = (idx % 2 == 0)?"red":"green";
$(elem).addClass(class);
});
});
Could you please explain "automatically"?
You mean at page ready event?
Maybe somthing like this:
$(document).ready(function (){
$("tr:odd").css("background-color", "#f00");
$("tr:even").css("background-color", "#0f0");
});
Here's the simplest method:
$("tr").addClass("red");
try this
var trs = jQuery('tr');
trs.filter(':even').addClass('red');
trs.filter(':odd').addClass('green');
to not selecting two-times every tr

Categories