javascript multiple loops - javascript

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.

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/

Word counting in Javascript

I am trying to figure out a way to count words that are placed in multiple paragraph blocks in javascript. Right now I have a button that is connected to a function and that function is linked to an ID in the paragraph. Here is my code
function processText(elements) {
var count = 0;
for (var i = 0; i < elements.length; i++) {
count += elements[i].textContent.split(/\s/).length;
}
return count;
}
var wordsInParagraphs = processText(document.getElementsByTagName("data"));
<!DOCTYPE html>
<html>
<head>
<meta name="title" content="The Cask of Amontillado--Edgar Allan Poe (1809-1849)">
</head>
<body>
<p><button 1="processText(elements);">Process</button></p>
<p id="data"></p>
</body>
Is this what you're looking for? You just need to call the function on click and grab all the elements you want to count, you have the rest there (I'm using split instead of regex).
function processText() {
var elements = document.querySelectorAll(".data");
var count = 0;
for (var i = 0; i < elements.length; i++) {
count += elements[i].textContent.split(" ").length;
}
console.log(count)
}
<!DOCTYPE html>
<html>
<head>
<meta name="title" content="The Cask of Amontillado--Edgar Allan Poe (1809-1849)">
</head>
<body>
<p><button onclick="processText();">Process</button></p>
<p class="data">text in paragraph one</p>
<p class="data">text in paragraph two</p>
</body>
The markup has some problems, for example, 1="processText(elements);" probably you meant onClick="processText(elements);", however, you're passing a param called elements. Further, you have a tag with id="data" and you're trying to look for tag name those elements.
A better approach is using the function addEventListener for a better logic and you should mark those paragraphs using a class name class="data". Finally, for splitting by spaces use this regex /\s+/
function processText(elements) {
var count = 0;
for (var i = 0; i < elements.length; i++) {
count += elements[i].textContent.split(/\s+/).length;
}
return count;
}
document.getElementById('myButton').addEventListener('click', function() {
var wordsInParagraphs = processText(document.getElementsByClassName("data"));
document.getElementById('total').textContent = wordsInParagraphs;
});
<p><button id='myButton'>Process</button></p>
<p class="data">Ele from Stack</p>
<p class="data">Ele from Venezuela</p>
<p id='total'></p>

How do i make a website that creates a html table using javascript prompts?

<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
var r = prompt ("how many rows ?");
var c = prompt ("how many columns ?");
var red = prompt ("how red ?");
var green = prompt ("how green ?");
var blue = prompt ("how blue ?");
document.write('<table style="width:100%" bgcolor="'+red+''+green+''+blue+'">');
for(var r = i; i > -1; i--){
document.write('<tr>');
for(var c = i; i > -1; i--){
document.write('<th></th>');
};
document.write('</tr>');
};
document.write('</table>');
</script>
</head>
<body>
</body>
</html>
What is wrong with my code ? I answer all the prompts but nothing happens on the screen. My professor said that i would need a for loop inside of an another for loop, what am i missing?
One issue is that you are not initializing the i variable (there is no 'var i' in your code). This variable is the index variable for your loop, set it to the row/column input variable that the user entered.
Also, when you put a nest loops don't try to reuse the index variable (i).
And work through the logic of the loop iterator, you actually want the loop to run to condition i > 0
Change the loops to something like:
for(var i = r; i > 0; i--){
document.write('<tr>');
for(var j = c; j > 0; j--){
...
And check on what the th tag is in html, you really want td
And then you will still not see the table you just created because there is no content in the 'cells', so you can add content or you can see the table when you use the browser developer tools.
Multiple corrections:
Don't use document.write multiple times, since each call will overwrite the contents of the body.
Your iterator assignment logic was backwards - assign i = r, not r = i, since the value of the expression (variable in this case) on the right side gets assigned to the variable on the left side.
You need to use a separate iterator variable (e.g. j) for the inner for loop, otherwise it would interfere with the outer loop.
The iterator conditions are off by 1. If you are going to decrement from the max number (of rows, columns) then iterate while i/j are greater than 0, not -1
var r = prompt ("how many rows ?");
var c = prompt ("how many columns ?");
var red = prompt ("how red ?");
var green = prompt ("how green ?");
var blue = prompt ("how blue ?");
var html = '<table style="width:100%" bgcolor="'+red+''+green+''+blue+'">';
for(var i= r; i > 0; i--){
html += '<tr>';
for(var j = c; j > 0; j--){
html +='<th></th>';
};
html += '</tr>';
};
html +='</table>';
document.write(html);
//or else instead of document.write, use something like the line below :
//document.body.innerHTML = html;
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body id="container">
</body>
</html>

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

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).

Categories

Resources