How to detect negative values in a <td> of table in html? - javascript

I have a table in html, I am using Tangle framework to make the values look dynamic of that table.
What I want is to place a check on a specific <td> if its numeric value ever gets negative, the entire <tr> of that particular <td> should change its background color to Red.
Can this be done using java script or some simple lines of code may solve this problem?
Please help me doing this.

<html>
<head>
<style type="text/css">
td.negative { color : red; }
</style>
<script language="JavaScript" type="text/javascript">
<!--
function MakeNegative() {
TDs = document.getElementsByTagName('td');
for (var i=0; i<TDs.length; i++) {
var temp = TDs[i];
if (temp.firstChild.nodeValue.indexOf('-') == 0) temp.className = "negative";
}
}
//-->
</script>
</head>
<body>
<table id="mytable">
<caption>Some Financial Stuff</caption>
<thead>
<tr><th scope="col">Date</th><th scope="col">Money is good</th></tr>
</thead>
<tbody>
<tr><td>2006-05-01</td><td>19.95</td></tr>
<tr><td>2006-05-02</td><td>-54.54</td></tr>
<tr><td>2006-05-03</td><td>34.45</td></tr>
<tr><td>2006-05-04</td><td>88.00</td></tr>
<tr><td>2006-05-05</td><td>22.43</td></tr>
</tbody>
</table>
<script language="JavaScript" type="text/javascript">
<!--
MakeNegative();
//-->
</script>
</body>

I'd suggest:
var table = document.getElementsByTagName('table')[0],
cells = table.getElementsByTagName('td'),
hasNegative = 'hasNegative',
text = 'textContent' in document ? 'textContent' : 'innerText', num = 0;
for (var i = 0, len = cells.length; i < len; i++) {
num = parseFloat(cells[i][text]);
if (Math.abs(num) !== num) {
cells[i].parentNode.className += ' hasNegative';
}
}
JS Fiddle demo.
The rather bizarre means to determine negativity was a result of my previous, perhaps naive, check failing to differentiate between 0 and -0 (though I'm not quite sure whether negative-zero would pass, or fail, your criteria).

Related

JS: change "var y = UNDEFINED" for "var y= blank space" with if

I have a table generated from a textarea filled by users, but some of the time, a cell stays empty (and that's all right).
The thing is that the .innerHTML of that cell is also my var y in a script and when that cell is empty (therefore, undefined), my var y becomes UNDEFINED too (the value, not a string), which makes my whole script fail.
Here's a snippet to show the problem:
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body><center>
</center></body>
<!--------- script that generates my table from text areas -->
<script>
function generateTable() {
$('#excel_table1').html("");
var n=1;
var rows=[];
var lng=0;
var maxligne=0;
$('textarea').each(function(){
var data = $(this).val();
if (data !=''){
var rowData = data.split("\n");
rows[n] = rowData;
lng = rowData.length;
if(lng > maxligne)
{
maxligne=lng
}
n++;
}
}
)
var table = $('<table />');
k=0;
while (k < maxligne) {
var row = $('<tr />');
for(var i = 1; i < rows.length; i++)
{
var singleRow = rows[i];
if(singleRow[k]!= undefined){
row.append('<td>'+singleRow[k]+'</td>')
} else {
row.append('<td></td>')
}
}
table.append(row);
k++;
}
$('#excel_table1').append(table);
}
</script>
<textarea placeholder="data 2 Here" name="data1" style="width:100px;height:40px;"></textarea>
<textarea placeholder="data 2 Here" name="data2" style="width:200px;height:40px;"></textarea>
<textarea placeholder="fild not required" name="data3" style="width:200px;height:40px;"></textarea>
<br>
<input id=bouton1 type="button" onclick="javascript:generateTable()" value="GenerateTable"/>
<div id="excel_table1"></div>
<!--------- script that get the data from cells to show it in <H2> -->
<script type="text/javascript">
function buttonTEST()
{
$('#displayCell').html("");
var x = document.getElementById('excel_table1').getElementsByTagName('tr')[0].cells[1].innerHTML;
var y = document.getElementById('excel_table1').getElementsByTagName('tr')[0].cells[2].innerHTML;
if (y === undefined) {
y = " ";
}
document.getElementById('displayCell').innerHTML = x +" "+ y;
}
</script>
<br/><br/>
<h2 id="displayCell"></h2>
<br/><br/>
<input id="Button2" type="button" onclick="buttonTEST()" value="TEST ME"/>
As you can see, if you generate a table with only to columns (which is supposed/needs to happen sometimes), we get this error from the console because we're trying to get "innerHTML" from a undefined:
index.html:120 Uncaught TypeError: Cannot read property 'innerHTML' of undefined
A little specification: When that cell is=undefined , I need it to stay undefined, I only want to change the fact that my var y also becomes undefined.
So I thought that changing the value of var y (and not the value of that cell, otherwise, the 3rd column, supposed to be empty, would be created just because of an blank space) to a blank space would resolve the problem, but I don't seem to get it right (write it in a correct manner).
Any ideas?
Try
var x = document.getElementById('excel_table1').rows[0].cells[0].innerHTML;
var y = document.getElementById('excel_table1').rows[0].cells[1].innerHTML;
using rows instead of getElementsByTagName is cleaner.
Also note that the indexes for cells start from zero not 1, you probably only have 2 cells in your first row, but .cells[2].innerHTML tries to get the innerHTML of the 3rd cell which does not exist.
As others have pointed out, you're already using jQuery, so the easiest way to get the cell contents is to use a css selector to find the cells using the $ function, then call .html() to get the contents. A direct conversion of your current code to this approach could be:
var x = $('#excel_table1 tr:nth-child(1) td:nth-child(2)').html();
var y = $('#excel_table1 tr:nth-child(1) td:nth-child(3)').html();
This works in a way so that the $ function returns a jQuery object, which is essentially a set of elements, which can potentially be empty. Most jQuery functions are then designed to fail gracefully when called on an empty set. For instance, html will return undefined when invoked on an empty set, but it will not fail.
Note that it is not very robust to use the selector above, as it is obviously sensitive to the placement of the cells. It would be more maintainable to assign a class attribute to the cells that describes their content, and then select on that, e.g. something like
var name = $("#excel_table1 tr:nth-child(1) td.name").html()
So here's the answer that worked for me:
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body><center>
</center></body>
<!--------- script that generates my table from text areas -->
<script>
function generateTable() {
$('#excel_table1').html("");
var n=1;
var rows=[];
var lng=0;
var maxligne=0;
$('textarea').each(function(){
var data = $(this).val();
if (data !=''){
var rowData = data.split("\n");
rows[n] = rowData;
lng = rowData.length;
if(lng > maxligne)
{
maxligne=lng
}
n++;
}
}
)
var table = $('<table />');
k=0;
while (k < maxligne) {
var row = $('<tr />');
for(var i = 1; i < rows.length; i++)
{
var singleRow = rows[i];
if(singleRow[k]!= undefined){
row.append('<td>'+singleRow[k]+'</td>')
} else {
row.append('<td></td>')
}
}
table.append(row);
k++;
}
$('#excel_table1').append(table);
}
</script>
<textarea placeholder="data 2 Here" name="data1" style="width:100px;height:40px;"></textarea>
<textarea placeholder="data 2 Here" name="data2" style="width:200px;height:40px;"></textarea>
<textarea placeholder="fild not required" name="data3" style="width:200px;height:40px;"></textarea>
<br>
<input id=bouton1 type="button" onclick="javascript:generateTable()" value="GenerateTable"/>
<div id="excel_table1"></div>
<!--------- script that get the data from cells to show it in <H2> -->
<script type="text/javascript">
function buttonTEST()
{
$('#displayCell').html("");
var x = $('#excel_table1 tr:nth-child(1) td:nth-child(2)').html();
var y = $('#excel_table1 tr:nth-child(1) td:nth-child(3)').html();
if (y ===undefined)
{document.getElementById('displayCell').innerHTML = x ;}
else
{document.getElementById('displayCell').innerHTML = x +" "+ y;}
}
</script>
<br/><br/>
<h2 id="displayCell"></h2>
<br/><br/>
<input id="Button2" type="button" onclick="buttonTEST()" value="TEST ME"/>

How to create a table using a loop with data from an array [duplicate]

This question already has answers here:
JavaScript property access: dot notation vs. brackets?
(17 answers)
Loop through an array in JavaScript
(46 answers)
Closed 3 years ago.
I need to Create a table from a loop that uses the data from an array.
I am using a sample code but i am having trouble trying to figure out how to get the loop to use an array to fill the data. I dont know what i need to put for the function portion or if I dont even need to worry about that?
<!Doctype html>
<html>
<head>
<script type="text/javascript">
function table()
{
this.calcmul = calc;
}
function calc(arg1,arg2)
{
var cars = ["Saab", "Volvo", "BMW"];
var cars2 = ["Saab", "Volvo", "BMW"];
return multi;
}
var table2 = new table();
</script>
</head>
<body>
<table border="solid 2px;" style="font-size:50px;">
<thead><tr>
<script>
for(var j=1; j<=5; j++)
{
document.write("<th><label style= color:red;'>"+i+"</label></th>");
}
</script>
</tr>
</thead>
<tbody>
<script type="text/javascript">
for(var i =1; i<=5; i++)
{
document.write("<tr>");
for(var k=1; k<=2; k++)
{
var cars = i;
var cars2 = k;
document.write("<td>"+table2.cars+"</td>");
}
document.write("</tr>");
}
</script>
</tbody>
</table>
</body>
</html>
I am trying to get the loop to create the table and list the data from the array
First of all, you should check your code for errors!, for example, you have your </tbody> tag outside of the <script> tag.
As to display the data from one of the arrays you have there, I would do it something like this:
<html>
<head>
<title></title>
</head>
<body>
<table border="solid 2px;" style="font-size:50px;" id="myTable">
</table>
<script type="text/javascript">
var cars = ["Saab", "Volvo", "BMW"];
var table = document.getElementById("myTable");
var tableHead = "<thead><th>Cars</th></thead>";
table.innerHTML += tableHead;
//What the above line will do is add to "myTable" the element <thead> and the <th>, in this case it's just one.
for(var i = 0; i<cars.length; i++)
{
/*This loop will enter as long as index i isn't greater than all the elements of the cars array.
In this case, as long as i doesn't exceed or equals 2, it will print things*/
table.innerHTML += "<tbody><td>"+cars[i]+"</td></tbody>";
/*Now, we add the element <tbody> with the respective tds,
depending on the index it will print different things,
for example: in the first run, i = 0, so it will print the body as: <tbody><td>Saab</td></tbody>, why? well, because is the first element of the cars array, then it will continue to print the other values.*/
}
</script>
</body>
</html>
You can see the output in here: https://jsfiddle.net/40wszykn/

How to combine html, js and css from fiddle

I know the Question is silly and fiddle is only for testing your code,
but combining that into one code via putting JS under script<> and css under style<> is not working for me!
link to my code
I have used the following way as suggested by others:
<html>
<head>
<style type="text/css">
table tr td {
border: 1px solid;
padding: 4px;
}
<body>
<div ng-controller="MyCtrl">
<button ng-click="processData(allText)">
Display CSV as Data Table
</button>
<div id="divID">
<table style="border:1px solid">
<tr ng-repeat="x in data">
<td ng-repeat="y in x" rowspan="{{y.rows}}" colspan="{{y.cols}}">{{ y.data }}</td>
</tr>
</table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script language="JavaScript" type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.controller("MyCtrl", function($scope) {
$scope.allText = "RS#2|Through Air CS#2|Over Surface CS#2|\nin.|mm|in.|mm|\nB |3/32\n (a)|2.4 \n (a)|3/32 \n (a)|2.4 \n (a)|\nD |1/16\n (a)|1.6 \n (a)|1/8 \n (a)|3.2 \n (a)|\n";
$scope.processData = function(allText) {
// split content based on new line
var allTextLines = allText.split(/\|\n|\r\n/);
var lines = [];
var r, c;
for (var i = 0; i < allTextLines.length; i++) {
// split content based on comma
var data = allTextLines[i].split('|');
var temp = [];
for (var j = 0; j < data.length; j++) {
if (data[j].indexOf("RS") !== -1) {
r = data[j].split("#").reverse()[0];
} else {
r = 0;
}
if (data[j].indexOf("CS") !== -1) {
c = data[j].split("#").reverse()[0];
} else {
c = 0;
}
temp.push({
"rows": r,
"cols": c,
"data": data[j].replace(/RS#.*$/, '').replace(/CS#.*$/, '')
});
}
lines.push(temp);
}
alert(JSON.stringify(lines));
$scope.data = lines;
}
});
The problem is that you are using an external JS framework, AngularJS. You will have to create another script tag which loads Angular as well. There are two ways you can do this: you can either download the angular source code and then load that into your HTML, or use a CDN.
To use the CDN, you can just add the following above your current <script> tag:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
Your final output should look like this:
<html>
<head>
<style type="text/css">
// CSS Content
</style>
</head>
<body ng-app="myApp">
<!-- some html elements -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script language="JavaScript" type="text/javascript">
// more js here.
</script>
</body>

Create Javascript rows with user input

How would you start writing a for loop for the code provided below:
<html>
<head>
</head>
<body>
Rows: <input name="rows" id="rows" type="text"/><br/>
<input type="submit" value="Make me a table!" onclick="makeTable();"/><br/><br/>
<table border="1" id="theTable">
</table>
<script type="text/javascript">
function makeTable(){
//Insert code here AND ONLY HERE!
//Write a for loop to create the number of rows specified in the "row" input field
</script>
</body>
</html>
As I suspect this is homework I will no provider a full code answer but instead provide you with a few guide lines that hopefully will help you.
You have the html and the javascript, in order to create new html elements you need to use the document.createElement(type) function that will create a new element, in your case - td/th ?
Then you need to insert it into your table
You do that by obtaining the table(by id/type) - search the web for this one its very simple.
And then using the append method on is with the created element.
You do all this process with a normal for loop that will run until the .value of the input tags you have in your html (Again, search for how to obtain these values)
Good luck =]
Is this what you are looking for?
function makeTable(){
// Get values of rows/cols inputs
var rows = document.getElementById('rows').value;
var cols = document.getElementById('cols').value;
// Check the values are in fact numbers
if (!isNaN(rows) && !isNaN(cols)) {
// Get the table element
var table = document.getElementById('theTable');
// Iterate through rows
for (var r = 0; r < rows; ++r) {
// Create row element
var tr = document.createElement('tr');
// Iterate through columns
for (var c = 0; c < cols; ++c) {
// Create cell element
var td = document.createElement('td');
// Setting some text content
td.textContent = 'R: ' + r + ', C: ' + c;
// Append cell to row
tr.appendChild(td);
}
// Append row to table
table.appendChild(tr);
}
}
}
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
</head>
<body>
Rows: <input name="rows" id="rows" type="text"/><br/>
Cols: <input name="cols" id="cols" type="text"/><br/>
<input type="submit" value="Make me a table!" onclick="makeTable();"/> <br/><br/>
<table border="1" id="theTable">
<script type="text/javascript">
function makeTable(){
var html = "";
var row=$('#rows').val();
var col=$('#cols').val();
for(var i=0; i<row; i++){
html+="<tr>";
for(var j=0;j<col; j++)
{
html+= '<td> Your data </td>';
}
html+="</tr>"
}
$('#theTable').html(html);
//Insert code here AND ONLY HERE!
//Write a for loop to create the number of rows specified in the "row" input field
//create a dom element for the row to be added to the table
}
</script>
</body>
</html>
I have kept it simple. Hope it helps.

javascript multiple loops

I am trying to get the sum of a list of words displayed in an HTML browser.
If each word is assigned a number i.e
a is 1,
b is 2
and so on upto z is 26, then the sum of apple should be 50. I want them to be displayed in browser like below:
apple
carrot
money
50
75
72
but I am not able to get the loop to work correctly.
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" rev="stylesheet" href="script.css" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
function newSquare(){
for(var j=0; j<10; j++){
calcAlpha(j);
}
}
function newDisplay(){
for(var k=0; k<10; k++){
calcAlpha(k);
}
}
function calcAlpha() {
var word = document.getElementById("square + j").childNodes[0].data;
var sum = 0;
for(var i=word.length-1; i>=0; i--) {
sum += (word.charCodeAt(i) - 96);
}
document.getElementById("display + k").innerHTML=sum
}
</script>
</head>
<body>
<h1>Calculate sum of words</h1>
<table>
<tr><td id="square1">apple</td></tr>
<tr><td id="square2">carrot</td></tr>
<tr><td id="square3">money</td></tr>
<tr><td id="square4">game</td></tr>
</table>
<table>
<tr><td id="display1"> </td></tr>
<tr><td id="display2"> </td></tr>
<tr><td id="display3"> </td></tr>
<tr><td id="display4"> </td></tr>
</table>
<div id="display"></div>
<button onclick="calcAlpha()">calculate</button>
</body>
</html>
Can someone can sort this for me? I am still a beginner at Javascript, and I dont understand how to put i,j, and k in loops.
Thanks.
Here's a complete answer:
There are three main problems with the code. First, i, j, and k are var's with specific integer values in this example. "square + j" is just a string that does not have the desired values (i.e. square1, square2, etc.). As Michael has suggested, you should put "square" + j.
The second issue is that the only function to run in your webpage is calcAlpha(), which you call in the onclick event of the button element. Within calcaAlpha() you never call newSquare() or newDisplay(), so they never execute.
The third issue is the namespace, or scope of your javascript variables. Within calcAlpha() you cannot access the variables j or k because they are declared in external functions that don't encapsulate the calcAlpha() function. However, you can access the variable i because it is declared in calcAlpha().
The solution to your problem would be to remove newDisplay() and newSquare() and change calcAlpha() to something like this:
function calcAlpha() {
for (var j = 1; j <= 4; j++) {
var word = document.getElementById("square" + j).childNodes[0].data;
var sum = 0;
for(var i=word.length-1; i>=0; i--) {
sum += (word.charCodeAt(i) - 96);
}
document.getElementById("display" + j).innerHTML=sum
}
}
This is basically the combined code for newSquare() and newDisplay() which is put into calcAlpha() and fixed for the other issues described above. Notice that the variable k is unnecessary because you want to put the numeric sum of squareN into displayN, so you can use a single variable, j.
I'm not sure what you want to do with those functions, but try this:
function run() {
// reads, calculates and prints all words
for (var i=1; i<=4; i++) {
var word = document.getElementById("square"+i).childNodes[0].data;
var result = calcAlpha(word);
document.getElementById("display"+i).childNodes[0].data = result;
}
}
function calcAlpha(text) {
text = text.toLowerCase();
var sum = 0;
for (var i=text.length-1; i>=0; i--) {
sum += text.charCodeAt(i) - 96;
}
return sum;
}
And call the run function from the button.
One thing I saw that you did incorrectly right away was getting the element by id. You were including the looping variable as a string instead of an int. Here is my solution:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
function calcAlpha()
{
for(j =1; j<=4; j++)
{
var word = document.getElementById("square" + j).innerHTML;
var sum = 0;
for(var i=word.length-1; i>=0; i--)
{
sum += (word.charCodeAt(i) - 96);
}
document.getElementById("display" + j).innerHTML=sum
}
}
</script>
</head>
<body>
<h1>Calculate sum of words</h1>
<table>
<tr><td id="square1">apple</td></tr>
<tr><td id="square2">carrot</td></tr>
<tr><td id="square3">money</td></tr>
<tr><td id="square4">game</td></tr>
</table>
<table>
<tr><td id="display1"> </td></tr>
<tr><td id="display2"> </td></tr>
<tr><td id="display3"> </td></tr>
<tr><td id="display4"> </td></tr>
</table>
<div id="display"></div>
<button onclick="calcAlpha()">calculate</button>
</body>
</html>
The first problem, like Michael said, is this:
document.getElementById("square + j")
// and
document.getElementById("display + k")
This will look for the element whose id exactly matches "square + j" or "display + k". To concatenate the value of a variable to a string, use "square" + j and "display" + k.
The second problem is that in the context of calcAlpha, the variables j and k are undefined. You can fix this by either making them accessible to calcAlpha (by defining them outside the scope of function calcAlpha) or by passing j (or k) as a parameter. You're already doing the first part of that (actually passing it along). All you need now is to use it in the declaration of calcAlpha, like so:
function calcAlpha(index) {
var word = document.getElementById("square" + index).childNodes[0].data;
// [...]
}
The variable index will now contain the value of the j or k you passed along.
One other thing: you're calling calcAlpha both from the other functions and from the <button>'s onclick. That's probably not what you want to do. Have a look at Bergi's answer, his/her solution should solve your problem.

Categories

Resources