change color when the number goes down - javascript

I am trying to change the class name to an element when its value goes down
My view in the blade is a foreach
#foreach ($scaduti as $item )
<tr>
<td>{{$item->name}}</td>
<td>{{$item->lotto}}</td>
<td>{{carbon\Carbon::createFromFormat('Y-m-d', $item->data_di_scadenza)->format('d-m-Y')}}</td>
<td>{{$item->sector->settore}}</td>
<td>{{$item->sector->scaffale}}</td>
<td id="changecolor">{{$item->sector->quantita_rimanente - $item->sector->quantita_bloccata}}</td>
<td>{{$item->sector->quantita_bloccata}}</td>
</tr>
#endforeach
I want to add a class to the td with id "changecolor"
My script is:
var x = document.getElementById("changecolor").innerHTML;
var i;
for (i = 0; i < x.length; i++) {
if(x[i] <= 20){
document.getElementById('changecolor').className= 'changetored';
}
}
The color is applied only to the first element of the foreach and ignoring all the others.
I want to apply it to all foreach results that respect the if
Sorry for my bad English.

The problem is, as many users said, on id univocity. How to easly solve that? Let's say you have an id on $item that is a progressive number from 0 to ...
In this case you could do something like:
#foreach ($scaduti as $item )
<tr>
<td>{{$item->name}}</td>
<td>{{$item->lotto}}</td>
<td>{{carbon\Carbon::createFromFormat('Y-m-d', $item->data_di_scadenza)->format('d-m-Y')}}</td>
<td>{{$item->sector->settore}}</td>
<td>{{$item->sector->scaffale}}</td>
<td id="{{ $item->id }}">{{$item->sector->quantita_rimanente - $item->sector->quantita_bloccata}}</td>
<td>{{$item->sector->quantita_bloccata}}</td>
</tr>
#endforeach
Then the script becames:
var i;
for (i = 0; i < length of scaduti; i++) {
var x = document.getElementById(i).innerHTML;
if(x[i] <= 20){
document.getElementById(i).className= 'changetored';
}
}

document.getElementById will always give you a single element. Most of the time the first element that it finds.
Instead of giving each element same id give them same name like
<td name="changecolor">{{$item->sector->quantita_rimanente - $item->sector->quantita_bloccata}}</td>
then use : document.getElementsByName("changecolor")
This will give all the elements with name 'changecolor'.
You can loop through these elements and do the thing you want.
Your modified code will look something like this:
var x = document.getElementsByName("changecolor");
var i;
for (i = 0; i < x.length; i++) {
if(x[i].innerHTML <= 20){
x[i].className = "changetored";
}
}

This is happening because you are using the id attribute more than once. An id should only appear once on a page. There are a couple ways to solve this problem:
change the id to a class='changecolor', then iterate through all of the elements with the changecolor class.
loop through the s of the and change the color of the 6th
I would suggest looking up document.querySelector to help in this.

Related

I need to change the css style of multiple <td> with the same id

I have a table that's created with asp net using a foreach to iterate through the instances of the viewModel.
I need to change the bakcground color of those but they all have the same id
HTML
#foreach (var item in Model)
{
<tr id="test">
<td>
<p class="small">#Html.DisplayFor(modelItem => item.DT_CADASTRO_FORMATADO)</p>
</td>
<td>
#Html.DisplayFor(modelItem => item.DSC_NATUREZA_INICIAL)
</td>
</tr>
}
JavaScript
$("document")
.ready(function ToPink() {
for (var i = 0; i < 26; i++) {
let tab = document.getElementById("test");
if (tab.cells[1].innerText == 'foo') {
alert(tab.cells[1].innerText);
}
}
});
Well, the IDs should be unique, but what you are looking for is a CSS class. Add a class to the tds and then use document.getElementsByClassName to pull all the elements with that class name.
ID should be unique because getElementById function searches for only one element that is first present with given ID:
alert(document.getElementById("nounique").innerHTML);
<div id="nounique">1</div>
<div id="nounique">2</div>
Give each table a class and in the javascript you query all TD elements
<table class="test">
....
</table>
<script>
var TDs = document.querySelectorAll(".test td");
for (var i=0; i < TDs.length; i++) {
// use TDs[i] here to style your html
}
</script>
Ofcourse you may use jQuery
$(document).ready(function() {
$(".test td").each(function(index) {
// use $(this) here to style your html
});
});

Getting value from cell and his inside element JS

I want to get value like in subject, from cell but that cell have element <a>1</a> and in this element is the value.
I tried something like this:
function filter(gvId) {
var table = document.getElementById(gvId);
for (var c = 1; c < table.rows[2].cells.length; c++) {
for (var r = headerNumber; r < table.rows.length; r++) {
var value = table.rows[r].cells[c].getElementsByClassName("a").innerHTML;
console.log(value); //and it should show me :
//1
//2
//3
//4
}
}
}
<table>
<tbody>
<tr>
<td><a>1</a>
</td>
<td><a>2</a>
</td>
</tr>
<tr>
<td><a>3</a>
</td>
<td><a>4</a>
</td>
</tr>
</tbody>
</table>
Everything works greate without <a> tag inside cell. But now I don't know how to get this value.
In your case, the problem is in a row:
var value = table.rows[r].cells[c].getElementsByClassName("a").innerHTML;
Because you're trying to match an element by class, but not by element tag. Link tag <a> has no className a. Your current code will work fine for: <a class="a">1</a> or <div class="a"></div>.
May be you should try something like querySelector instead? Like:
var value = table.rows[r].cells[c].querySelector('a').innerHTML;
Please, also check the MDN docs about getElementsByClassName and querySelector
UPD: All the code could be simplified:
var contentLinks = table.querySelectorAll('td a');
contentLinks.forEach(function(item) {
var value = item.innerHTML;
console.log(value);
});
Get the text content of an element with .textContent instead of .innerHTML
var value = table.rows[r].cells[c].textContent;
Documentation here and here

loop through table tr and retrieve value from second td

I have the following HTML table:
<table id="review-total">
<tbody><tr class="wlp">
<td class="left-cell">WLP Total</td>
<td>199.00</td>
</tr>
<tr class="tax">
<td class="left-cell">GST</td>
<td>19.90</td>
</tr>
<tr class="net">
<td class="left-cell">Order Total</td>
<td class="net-price">$218.90</td>
</tr>
</tbody>
</table>
I'm trying to loop through this table and retrieve the values i.e
199.00, 19.90 and $218.90 I have the following code:
var reviewTotal = document.getElementById('review-total');
for (var i = 1; i < reviewTotal.rows.length; i++) {
if (reviewTotal.rows[i].cells.length) {
wlpTotal = (reviewTotal.rows[i].cells[1].textContent.trim());
gstAmount = (reviewTotal.rows[i].cells[3].textContent.trim());
totalOrderAmount = (reviewTotal.rows[i].cells[5].textContent.trim());
}
}
I'm having a small issue trying to retrieve those values specified above, at present the error I get is textContent is undefined.
Can someone show me how I should go about retrieving those values, unfortunately I'm not strong in Javascript.
You have 3 rows and each row has only 2 cells. The 3 and 5 indices are undefined and undefined doesn't have .textContent property.
If you want to store the values by using specific variable names, you remove the loop and select the target elements manually:
var wlpTotal = reviewTotal.rows[0].cells[1].textContent.trim();
var gstAmount = reviewTotal.rows[1].cells[1].textContent.trim();
var totalOrderAmount = reviewTotal.rows[2].cells[1].textContent.trim();
If you want to store the values in an array, you can code:
var values = [].map.call(reviewTotal.rows, function(row) {
return row.cells[1].textContent.trim();
});
By using ES2015's Destructuring Assignment you can also extract the array's elements:
var [wlpTotal, gstAmount, totalOrderAmount] = values;
First:the index start the 0 either row or cell.
Secend:get value in the tag to use innerText or innerHTML ,The code following:
var reviewTotal = document.getElementById('review-total');
for (var i = 0; i < reviewTotal.rows.length; i++)
{
if (reviewTotal.rows[i].cells.length>1)
{
wlpTotal = (reviewTotal.rows[i].cells[1].innerText);
}
}

DataTables issue: VM9075 dataTables.min.js:24Uncaught TypeError: Cannot set property '_DT_CellIndex' of undefined

I just started using DataTables and everything works fine when creating the table.
When I display 5, 24, 47 rows in my table, DataTables behaves as I would expect.
But I have this table that has around 700 rows and I get the error in Google Chrome,
"VM9075 dataTables.min.js:24Uncaught TypeError: Cannot set property '_DT_CellIndex' of undefined "
and in IE 9,
"SCRIPT5007: Unable to set value of the property '_DT_CellIndex': object is null or undefined
jquery-1.10.2.min.js, line 4 character 2367"
I don't have jQuery included twice btw.
I'm not sure how to proceed from here.
I tried to use the unminified version of the .js file to debug it more myself but i kept getting an "ext" method or property is undefined and couldn't fix that either.
Any help is appreciated!
I figured it out
The biggest issue was not knowing exactly what this error actually meant.
In my case it meant "the number of every <td> element in your table that is a child of a <tr> element doesn't match the number of <th> elements that are a child of the <thead> element."
My table was being generated by the server, and some of the <tr> elements had 27 <td> children (which was filling the whole width of the table up, but some of the <tr> elements only had 3, 4, or 5, ... <td> child elements which isn't a valid table.
I solved it by adding empty <td> elements in my table for the <tr> elements that lacked the correct number of <td> elements
var makeTableValidObject = {
thisWasCalled: 0,
makeTableValid: function() {
var tableToWorkOn = document.getElementById("table1");
//check the number of columns in the <thead> tag
//thead //tr //th elements
var numberOfColumnsInHeadTag = tableToWorkOn.children[1].children[0].children.length;
var numberOf_trElementsToValidate = tableToWorkOn.children[2].children.length;
//now go through each <tr> in the <tbody> and see if they all match the length of the thead columns
//tbody //all trs//all tds elements
//tableToWorkOn.children[2].children.children);
for(var i = 0; i < numberOf_trElementsToValidate; i++) {
//row my row make sure the columns have the correct number of elements
var tdColumnArray = tableToWorkOn.children[2].children[i].children
var trElementToAppendToIfNeeded = tableToWorkOn.children[2].children[i];
if(tdColumnArray.length != numberOfColumnsInHeadTag) {
//since they don't match up, make them valid
if(tdColumnArray.length < numberOfColumnsInHeadTag) {
//add the necessary number of blank <td> tags to the <tr> element to make this <tr> valid
var tdColumnArrayLength = tdColumnArray.length;
for(var j = 0; j < (numberOfColumnsInHeadTag - tdColumnArrayLength); j++) {
var blank_tdElement = document.createElement("td");
blank_tdElement.id = "validating_tdId" + i + "_" + j;
trElementToAppendToIfNeeded.appendChild(blank_tdElement);
}
}
else {
//TODO: remove <td> tags to make this <tr> valid if necessary
}
}
}
}
};
Edit 1:
It has been awhile and this question is still getting a bunch of views. I have since updated the code.
I replaced the first line of code with the second line to be more general
var numberOfColumnsInHeadTag = tableToWorkOn.children[1].children[0].children.length;
var numberOfColumnsInHeadTag = tableToWorkOn.querySelectorAll('thead')[0].querySelectorAll('th');
Pretty much where ever in the prior code you see the children.children I replaced that with the querySelectorAll(...) Function.
It uses css selectors which makes it amazingly powerful.
stay blessed
Ran into this same issue and implemented this same solution (essentially) in jquery based on Coty's. Hope this helps someone. :)
$( '.table' ).each(function( i ) {
var worktable = $(this);
var num_head_columns = worktable.find('thead tr th').length;
var rows_to_validate = worktable.find('tbody tr');
rows_to_validate.each( function (i) {
var row_columns = $(this).find('td').length;
for (i = $(this).find('td').length; i < num_head_columns; i++) {
$(this).append('<td class="hidden"></td>');
}
});
});
As answered by Coty, the problem lies in the mismatch of td elements generated in the header and body of table.
I'd like to highlight one of the reasons why it can occur (For .Net Users).
If Page numbers are being displayed at the end of gridview, they can disrupt table structure.
Remove AllowPaging="true" from your gridview to solve this.
And no worries because Datatable handles Paging.
you always keep four column but sometimes you will receive or append null td or only one td, td count always match with total column so when you does not have record then make td as following.
<th>No</th>
<th>Name</th>
<th>place</th>
<th>Price</th>
----------------------------------------
<td colspan="4">Data not found.</td>
<td style="display: none;"></td>
<td style="display: none;"></td>
<td style="display: none;"></td>
this error can also be triggered if you try to set options for the responsive extension for more columns than you have.
$( '.table' ).each(function( i ) {
var worktable = $(this);
var num_head_columns = worktable.find('thead tr th').length;
var rows_to_validate = worktable.find('tbody tr');
rows_to_validate.each( function (i) {
var row_columns = $(this).find('td').length;
for (i = $(this).find('td').length; i < num_head_columns; i++) {
$(this).append('<td class="hidden"></td>');
}
});
});

Accessing/Changing Information in Tables with Javascript

I am using greasemonkey to change the functionality of an existing web page.. If you aren't familiar with greamonkey it doesn't really matter.. the main information is that the current code for the existing page looks like this:
<div id="sqlDiv" class="sqlBorderDiv" style="display: none;">
<div class="reportBorderDiv">
<table class="reportTable">
<tbody>
<tr>
<tr class="reportRow1">
<tr class="reportRow2">
<td>55555</td>
<td>Bruce Wayne</td>
<td>12456789123</td>
<td>2013-12-17</td>
<td>Batman</td>
<td>Superhero</td>
<td>Menace</td>
<td>123246</td>
<td>12456</td>
<td>123456</td>
<td></td>
</tr>
</tbody>
</table>
</div>
I want to run a script on it that will make the first cell of any reportRow into a hyperlink using the information in that cell. I am trying with a script like below, but something is going wrong and I have no idea what. ( I am really new into javascript). Thank you for any suggestions!!
var anchor = null;
var container;
var rows;
var cells;
var demoNum;
var linkString = "https://somewebsite.com/";
container = document.getElementById('sq1Div');
rows = container.getElementsByTagName("tr");
for (var i = 0; i < rows.length; i++) {
var className = rows[i].getAttribute("class");
if ( className == "reportRow1" || className == "reportRow2" ) {
anchor = rows[i];
cells = anchor.getElementsByTagName("td");
demoNum = cells[0];
linkString = linkString + demoNum;
cells[0] = <a href = linkString > demoNum </a>;
}
}
The problem is in the line
cells[0] = <a href = linkString > demoNum </a>;
That should be in a string, like this:
cells[0]="<a href='"+linkstring+"'>"+demonum+"</a>";
To put that back in the first row of the table, you can do this
row[i].childNodes[0].innerHTML=cells[0];
Also, you have document.getElementById("sq1div"), instead of "sqlDiv"
document.getElementById('sq*1*Div');
incorrect indetifier, you are using number "1" instead of letter "l"
and of course as wrote scrblnrd3 line with new link builds incorrect
It seems to me the HTML has unmatched tags, could this somehow confuse greasemonkey?

Categories