Reputation: 4663
I have a basic table with values that I am trying to control the formatting. I have achieved this in this example http://jsfiddle.net/hVJ4b/ for KPI2 of Service 1.
$('#work_table td.r2c1').each(function(){
var test = $(this).html(); // this works
var target = $('#work_table td.r2c5').html()
var target2 = $('#work_table td.r2c5').html() - 5;
//alert("test: " + test);
//alert("target: " + target);
//alert("target2: " + target2);
if ($(this).html() >= target) { //if >= to target then green
//alert($(this).value())
$(this).css('background-color',green);
} else if ($(this).html() < target && $(this).html() >= target2 ) { //if < to target then orange
$(this).css('background-color',orange);
} else { //if < to target then red
$(this).css('background-color',red);
}
});
$('#work_table td.r2c2').each(function(){
var test = $(this).html(); // this works
var target = $('#work_table td.r2c5').html()
var target2 = $('#work_table td.r2c5').html() - 5;
//alert("test: " + test);
//alert("target: " + target);
//alert("target2: " + target2);
if ($(this).html() >= target) { //if >= to target then green
//alert($(this).value())
$(this).css('background-color',green);
} else if ($(this).html() < target && $(this).html() >= target2 ) { //if < to target then orange
$(this).css('background-color',orange);
} else { //if < to target then red
$(this).css('background-color',red);
}
});
$('#work_table td.r2c3').each(function(){
var test = $(this).html(); // this works
var target = $('#work_table td.r2c5').html()
var target2 = $('#work_table td.r2c5').html() - 5;
//alert("test: " + test);
//alert("target: " + target);
//alert("target2: " + target2);
if ($(this).html() >= target) { //if >= to target then green
//alert($(this).value())
$(this).css('background-color',green);
} else if ($(this).html() < target && $(this).html() >= target2 ) { //if < to target then orange
$(this).css('background-color',orange);
} else { //if < to target then red
$(this).css('background-color',red);
}
});
$('#work_table td.r2c4').each(function(){
var test = $(this).html(); // this works
var target = $('#work_table td.r2c5').html()
var target2 = $('#work_table td.r2c5').html() - 5;
//alert("test: " + test);
//alert("target: " + target);
//alert("target2: " + target2);
if ($(this).html() >= target) { //if >= to target then green
//alert($(this).value())
$(this).css('background-color',green);
} else if ($(this).html() < target && $(this).html() >= target2 ) { //if < to target then orange
$(this).css('background-color',orange);
} else { //if < to target then red
$(this).css('background-color',red);
}
});
Now I can just easily copy and paste my JQuery to apply it to the other rows/KPIs. But i am looking for a better way of doing this without copying and pasting, as I don't think this is good practice.
Can anyone offer advise on this please?
Note: My initial approach to this could be completely wrong. I also want it to be flexible for any changes/additions to the table at a later date...
Upvotes: 0
Views: 155
Reputation: 20415
Here is how I would go about it. I wouldn't worry about classes at all. You know the positions of the cells, so you can just loop through each row and then each cell in that row and color as you go.
var red = "#ff0000", green = "#00ff00", orange = "#ff7f00";
$(function ()
{
$('#work_table tr').each(function (rowIndex)
{
if (rowIndex > 0) // skip header row
{
var $row = $(this),
$cells = $row.find('td'),
count = $cells.length,
target = parseFloat($cells[count - 2].innerText),
target2 = target - 5.0;
$cells.each(function (cellIndex)
{
var min = count - 6,
max = count - 3;
if (cellIndex >= min && cellIndex <= max) // only date cells
{
var $cell = $(this),
value = parseFloat(this.innerText),
color = value >= target
? green : value < target && value >= target2
? orange : red;
$cell.css('background-color', color);
}
});
}
});
});
<table id="work_table" border="2">
<tr>
<th>Service</th>
<th>Measure</th>
<th>Date1</th>
<th>Date2</th>
<th>Date3</th>
<th>Date4</th>
<th>Target</th>
<th>Trend</th>
</tr>
<tr>
<td rowspan="4">Service1</td>
<td>KPI1</td>
<td>93.9</td>
<td>99.0</td>
<td>98.9</td>
<td>99.0</td>
<td>99.0</td>
<td>Value_Trend</td>
</tr>
<tr>
<td>KPI2</td>
<td>91.4</td>
<td>94.2</td>
<td>75.9</td>
<td>47.2.</td>
<td>99.0</td>
<td>Value_Trend</td>
</tr>
<tr>
<td>KPI3</td>
<td>91.0</td>
<td>92.1</td>
<td>83.9</td>
<td>84.9</td>
<td>95.0</td>
<td>Value_Trend</td>
</tr>
<tr>
<td>KPI4</td>
<td>95.7</td>
<td>94.6</td>
<td>87.4</td>
<td>88.3</td>
<td>92.4</td>
<td>Value_Trend</td>
</tr>
<tr>
<td rowspan="3">Service2</td>
<td>KPI1</td>
<td>45.0</td>
<td>95.3</td>
<td>76.4</td>
<td>34.5</td>
<td>90.0</td>
<td>Value_Trend</td>
</tr>
<tr>
<td>KPI2</td>
<td>91.0</td>
<td>92.1</td>
<td>83.9</td>
<td>84.9</td>
<td>95.0</td>
<td>Value_Trend</td>
</tr>
<tr>
<td>KPI3</td>
<td>97.0</td>
<td>96.1</td>
<td>85.9</td>
<td>84.9</td>
<td>93.0</td>
<td>Value_Trend</td>
</tr>
<tr>
<td rowspan="5">Service3</td>
<td>KPI1</td>
<td>97.0</td>
<td>93.1</td>
<td>86.9</td>
<td>82.9</td>
<td>94.0</td>
<td>Value_Trend</td>
</tr>
<tr>
<td>KPI2</td>
<td>50.2</td>
<td>76.3</td>
<td>69.4</td>
<td>84.5</td>
<td>95.0</td>
<td>Value_Trend</td>
</tr>
<tr>
<td>KPI3</td>
<td>12.0</td>
<td>93.1</td>
<td>87.9</td>
<td>86.9</td>
<td>97.0</td>
<td>Value_Trend</td>
</tr>
<tr>
<td>KPI4</td>
<td>91.0</td>
<td>92.1</td>
<td>83.9</td>
<td>84.9</td>
<td>95.0</td>
<td>Value_Trend</td>
</tr>
<tr>
<td>KPI5</td>
<td>99.0</td>
<td>99.1</td>
<td>89.2</td>
<td>89.3</td>
<td>99.0</td>
<td>Value_Trend</td>
</tr>
</table>
Upvotes: 0
Reputation: 20415
If you are copy/pasting the same code into each one, just combine them all using:
var $worktable = $('#work_table'),
$cells = $worktable.find('td');
$cells.filter('.r2c1, .r2c2, .r2c3, .r2c4').each(function ()
{
// your code here.
});
When you plug in your code it would look something like this: See working jsFiddle demo.
I cleaned it up a bit for readability's sake. I removed the commented out parts. You can always add that stuff back in. I also optimized it slightly using cached vars where I could.
Here's the jQuery I used:
var red = "#ff0000",
green = "#00ff00",
orange = "#ff7f00";
$(function ()
{
var $worktable = $('#work_table'),
$cells = $worktable.find('td');
$cells.filter('.r2').each(function ()
{
var $this = $(this),
test = parseFloat($this.html());
if (test >= 3)
$this.css('background-color', '#f0f');
});
$cells.filter('.r2c1, .r2c2, .r2c3, .r2c4').each(function ()
{
var $this = $(this),
test = parseFloat($this.html()),
target = parseFloat($cells.filter('.r2c5').html()),
target2 = parseFloat(target - 5),
color = test >= target
? green
: test < target && test >= target2
? orange
: red;
$this.css('background-color', color);
});
});
Upvotes: 1
Reputation: 2397
Why don't you consider writing a generic function that takes a variable called rowname and then you just pass in the row you got via jquery outside of the function.
var x = $('#work_table td.r2');
rowcolor (x);
function rowcolor (rowname)
{
$(rowname).each(function(){//this is r2 for an example want to get it to work for > values
//var test = $(this).html(); // this works
var test = $(this).val(); // this does not work
//alert("test: " + test);
if ($(this).html() >= 3) {
//alert($(this).value())
$(this).css('background-color','#f0f');
}
});
}
What the guy above me said works just fine. Mine is more javascript style.
Upvotes: 0