How To Get Multiple Outputs to Show From a For Loop - javascript

I have a for loop to get multiple outputs from an array. The currencyType[type] is used to pre-pend the proper letters to match the DIV ID in the HTML.
for(let type = 0; type <= currencyType.length; type++) {
// This grabs the number from XRPUSDVAL + XRPUSDAMT
let node = document.getElementById(currencyType[type].innerHTML+"USDVAL").textContent * document.getElementById(currencyType[type].innerHTML+"USDAMT").value;
let total = node.toFixed(2);
console.log(total)
}
I get 2 values of the total inside my console with the statement above that are dynamic numbers.
65704.50
99.91
However when I add a statement to try to output it to a DIV ID on my HTML, The console then only shows the result of 1 of the outputs
for(let type = 0; type <= currencyType.length; type++) {
// This grabs the number from XRPUSDVAL + XRPUSDAMT
let node = document.getElementById(currencyType[type].innerHTML+"USDVAL").textContent * document.getElementById(currencyType[type].innerHTML+"USDAMT").value;
let total = node.toFixed(2);
console.log(total)
document.getElementById(currencyType[type]+"USDTOTAL").innerHTML = total; // <------ Added This Statement
}
Here is the section of the HTML as well where the Javascript interacts with
<div class="container">
<div class="row">
<div class="col-sm-4 pbf-crypto-container">
<form method="POST" action="/users/currencies/68">
<h3 class="pbfCurrencyType">ETH</h3>
<input class="form-control-lg" id="ETHUSDAMT" name="amount" type="text" value="75">
<h3>Market Value: ($)</h3>
<div id="ETHUSDVAL"></div>
<h3>Total Value: ($)</h3>
<div id="ETHUSDTOTAL"></div>
<hr>
<input class="btn btn-primary" id="pbf-update" type="submit" value="Update">
<button class="btn btn-primary" id="pbf-refresh">Refresh</button>
</form>
</div>
<div class="col-sm-4 pbf-crypto-container">
<form method="POST" action="/users/currencies/60">
<h3 class="pbfCurrencyType">XRP</h3>
<input class="form-control-lg" id="XRPUSDAMT" name="amount" type="text" value="100">
<h3>Market Value: ($)</h3>
<div id="XRPUSDVAL"></div>
<h3>Total Value: ($)</h3>
<div id="XRPUSDTOTAL"></div>
<hr>
<input class="btn btn-primary" id="pbf-update" type="submit" value="Update">
<button class="btn btn-primary" id="pbf-refresh">Refresh</button>
</form>
</div>
</div>
</div>
I was wondering if someone can show me the proper way so that within my for loop it will be able to insert the total's into the section of my DIV that I specified. I am not sure what I am doing wrong here. Any help would be much appreciated. Thank you.

This line seems to be wrong
document.getElementById(currencyType[type]+"USDTOTAL").innerHTML = total;
You need to append USDTOTAL to currencyType[type].innerHTML like earlier in the same loop.
Make it
document.getElementById(currencyType[type].innerHTML +"USDTOTAL").innerHTML = total;
Or refactor the code
for(let type = 0; type <= currencyType.length; type++)
{
let prefix = currencyType[type].innerHTML ;
let node = document.getElementById( prefix +"USDVAL").textContent * document.getElementById( prefix +"USDAMT").value;
let total = node.toFixed(2);
console.log(total)
document.getElementById( prefix + "USDTOTAL").innerHTML = total;
}

try to append the results:
for(let type = 0; type <= currencyType.length; type++) {
// This grabs the number from XRPUSDVAL + XRPUSDAMT
let node = document.getElementById(currencyType[type].innerHTML+"USDVAL").textContent * document.getElementById(currencyType[type].innerHTML+"USDAMT").value;
let total = node.toFixed(2);
console.log(total)
document.getElementById(currencyType[type]+"USDTOTAL").innerHTML += total; // <------ Added This Statement
}

I think that you can improve a lite bit more you code
from here:
for(let type = 0; type <= currencyType.length; type++)
{
let prefix = currencyType[type].innerHTML ;
let node = document.getElementById( prefix +"USDVAL").textContent * document.getElementById( prefix +"USDAMT").value;
let total = node.toFixed(2);
console.log(total)
document.getElementById( prefix + "USDTOTAL").innerHTML = total;
}
to here:
currencyType.forEach(currency => {
const prefix = currency.innerHTML;
const node = document.getElementById(`${prefix}USDVAL`).textContent * document.getElementById(`${prefix}USDAMT`).value;
const total = node.toFixed(2);
document.getElementById(`${prefix}USDTOTAL`).innerHTML = total;
});

Related

Displaying the sum of two Javascript Functions

The output in the result field is showing NaN for the grandTotal function in the following JavaScript and HTML codes. Please assist to identify the error.
function firstSum(){
subPay=()=>{
let comPay = document.getElementById('totPay').value;
if (comPay > 215000){return (comPay - 215000)*0.25;}
else {return comPay*0.15;}
}
document.getElementById('result1').value = subPay();
}
groPay=()=>{
groEstimate=()=>{
let comPay = document.getElementById('totPay').value;
if (comPay > 220000){return (comPay - 220000)*0.33;}
else {return comPay*0.16;}
}
document.getElementById('result2').value = groEstimate();
}
function grandTotal(){
var allPay;
allPay = firstSum() + groPay();
document.getElementById('result').value = allPay;
}
<form>
<input id="totPay" type="number" placeholder = "groPymt">
<input type = "button" onclick = "grandTotal()" value = "Submit">
<div><input type="text" class="totsum" id="result1"></div>
<div><input type="text" class="totsum" id="result2"></div>
<div>Result: <input type="text" id="result"></div><br><br>
</form>
You should either return the values at the end of firstSum and groPay or change grandTotal to something like
function grandTotal(){
firstSum(); groPay();
const fs = document.getElementById('result1').value;
const gp = document.getElementById('result2').value;
document.getElementById('result').value = fs + gp;
}

JavaScript - Password Generator (checkbox)

I am working for an assignment about a password generator. Here is my HTML and JavaScript. When I click the checkbox for number and symbol, the result returns a password including "undefined". I guess the issue is from my if-else statement for checkbox status. What the result I expected is that whichever I click , the result does not include any letter of "undefined". Could someone help me with this issue? Thank you!
const btn = document.querySelector(".btn")
function getChar(num, char) {
if (document.querySelector("input[name=" + num + "]").checked) {
return char
}
}
btn.addEventListener("click", e => {
if (!document.querySelector("input[name=en]").checked && !document.querySelector("input[name=num]").checked && !document.querySelector("input[name=sym]").checked) {
return
}
let password = ""
let alphabet = "abcdefghijklmnopqrstuvwxyz"
let number = "0123456789"
let symbol = "!##$%^&*+="
password += getChar("en", alphabet)
password += getChar("num", number)
password += getChar("sym", symbol)
let result = ""
for (let i = 0; i < 10; i++) {
let num = Math.floor(Math.random() * password.length)
result += password[num]
}
console.log(result)
document.querySelector(".result").innerHTML = result
})
<div class="container">
<div class="english">
<label for="en">English letter</label>
<input type="checkbox" name="en">
</div>
<div class="number">
<label for="num">Number</label>
<input type="checkbox" name="num">
</div>
<div class="symbol">
<label for="sym">Symbol</label>
<input type="checkbox" name="sym">
</div>
<button class="btn">Generate</button>
<div class="result"></div>
</div>
The problem was that the getChar function, returns undefined if the check-box isn't checked. The desired functionality can be achieved by this modifications:
const btn = document.querySelector(".btn")
function getChar(num) {
return document.querySelector("input[name=" + num + "]").checked
}
btn.addEventListener("click", e => {
if (!document.querySelector("input[name=en]").checked && !document.querySelector("input[name=num]").checked && !document.querySelector("input[name=sym]").checked) {
return
}
let password = ""
let alphabet = "abcdefghijklmnopqrstuvwxyz"
let number = "0123456789"
let symbol = "!##$%^&*+="
if (getChar("en")) password += alphabet
if (getChar("num")) password += number
if (getChar("sym")) password += symbol
let result = ""
for (let i = 0; i < 10; i++) {
let num = Math.floor(Math.random() * password.length)
result += password[num]
}
console.log(result)
document.querySelector(".result").innerHTML = result
})
<div class="container">
<div class="english">
<label for="en">English letter</label>
<input type="checkbox" name="en">
</div>
<div class="number">
<label for="num">Number</label>
<input type="checkbox" name="num">
</div>
<div class="symbol">
<label for="sym">Symbol</label>
<input type="checkbox" name="sym">
</div>
<button class="btn">Generate</button>
<div class="result"></div>
</div>
When a checkbox is unchecked, it's value is undefined.
Because you return the value every time when you add new characters to the password variable, you add 'undefined'.
Just add a else statement that returns an empty string.

How to do a mini calculator using a single event Listener instead of onclick events in each button?

The challenge is to do a simple mini calculator with one input, 4 buttons, and an output.
The input is to add a number that will appear in the output immediately, next I will choose one of the four buttons (+,-,*,/)to do the math and next write again another number on the input. In the output will appear the result of that operation, further will continuing to do maths by clicking again in the buttons and add another number, and actualizing always the result.
I have done this before with onclick event in each button and using a prompt to write the numbers. now I want to use an input to write the numbers and using one event listener to all the buttons. Can anybody help me with the solution and explain to me each step?
This is my code so far :
let input =document.querySelector('#input');
let output =document.querySelector('#output');
let divButtons = document.querySelector('#buttons');
let messageOutput = (message) =>{
output.innerHTML = message;
}
messageOutput(input.value); // this doesn't work. What I miss to do show the input in the output?
divButtons.addEventListener('click', () =>{
//do something
})
<section class="container">
<h1 class="heading">Do some maths</h1>
<div class="calculator">
<input class="inputNumbers" id="input" type="number" placeholder="choose a number here">
<div class="buttons" id="buttons">
<button id="plus" class="btn btn-plus">+</button>
<button id="minus" class="btn btn-minus">-</button>
<button id="multiply" class="btn btn-multiply">*</button>
<button id="divide" class="btn btn-divide">/</button>
</div>
<div id="output" class="visor"></div>
</div>
</section>
I am new so I need help to solve this challenge and understand what should I have to do.
Thank you
Modified JS code a bit, using the listener you already wrote, let me know if you need more explaining. Hope it helps.
let input =document.querySelector('#input');
let output =document.querySelector('#output');
let divButtons = document.querySelector('#buttons');
let a = null;
let b = null;
let op = null;
let messageOutput = (message) =>{
output.innerHTML = message;
}
messageOutput(input.value); // this doesn't work. What I miss to do show the input in the output?
divButtons.addEventListener('click', (event) =>{
//checking if button is pressed
if(event.target.type = 'submit') {
//if a is not set before, meaning first time input
if(a == null) {
a = Number(input.value);
} else {
// second number
b = Number(input.value);
if(op == 'plus') {
a += b;
} else if(op == 'minus') {
a -= b;
}else if(op == 'multiply') {
a *= b;
} else {
a /= b;
}
}
//saving the operator that was pressed
op = event.target.id;
//showing output
output.innerHTML = a + " " + op;
//resetting input on each button pressed.
input.value = '';
}
});
<section class="container">
<h1 class="heading">Do some maths</h1>
<div class="calculator">
<input class="inputNumbers" id="input" type="number" placeholder="choose a number here">
<div class="buttons" id="buttons">
<button id="plus" class="btn btn-plus">+</button>
<button id="minus" class="btn btn-minus">-</button>
<button id="multiply" class="btn btn-multiply">*</button>
<button id="divide" class="btn btn-divide">/</button>
</div>
<div id="output" class="visor"></div>
</div>
</section>
Hope this helps. Modified your snippet a little and added a few variables.
let input = document.querySelector("#input");
let output = document.querySelector("#output");
let divButtons = document.querySelector("#buttons");
let result = null;
let selectedOperation = null;
let messageOutput = message => {
output.innerHTML = message;
};
divButtons.addEventListener("click", event => {
//do something
let id = event.target.id;
let value = parseInt(input.value);
switch (selectedOperation) {
case "plus":
result += value;
break;
case "minus":
result -= value;
break;
case "multiply":
result *= value;
break;
case "divide":
result /= value;
break;
default:
result = value;
break;
}
selectedOperation = id;
input.value = "";
messageOutput(`${result} ${selectedOperation}`);
});
Save your input number into a variable, then save the math function clicked by the user into a variable, then apply it to the saved input number using the current value the user has input as the factor.
Something like this:
let input = document.querySelector('#input');
let output = document.querySelector('#output');
let inputnumber = 0;
let subtotal = 0;
let total = 0;
let calculate = 0;
let x;
let y;
input.oninput = (e) => {
if(subtotal == 0) {
output.value = e.target.value;
}
x = Number(e.target.value);
y = Number(subtotal);
switch (calculate) {
case "btn-divide":
calc = y / x;
break;
case "btn-multiply":
calc = y * x;
break;
case "btn-plus":
calc = x + y;
break;
case "btn-minus":
calc = y - x;
break;
case 0:
calc = x;
break;
}
output.value = calc;
}
const divs = document.querySelectorAll('#buttons');
divs.forEach(el => el.addEventListener('click', event => {
calculate = event.target.classList[1];
input.value = null;
subtotal = calc;
}));
<section class="container">
<h1 class="heading">Do some maths</h1>
<div class="calculator">
<input class="inputNumbers" id="input" type="number" placeholder="choose a number here">
<div class="buttons" id="buttons">
<button id="plus" class="btn btn-plus">+</button>
<button id="minus" class="btn btn-minus">-</button>
<button id="multiply" class="btn btn-multiply">*</button>
<button id="divide" class="btn btn-divide">/</button>
</div>
<input id="output" type="number" class="visor" value=0>
</div>
</section>
Term you are looking for is called event delegation.
let input =document.querySelector('#input');
let output =document.querySelector('#output');
let divButtons = document.querySelector('#buttons');
let messageOutput = (message) =>{
output.innerHTML = message;
}
messageOutput(input.value); // this doesn't work. What I miss to do show the input in the output?
divButtons.addEventListener('click', (e) =>{
console.log(e.target.id)
})
<section class="container">
<h1 class="heading">Do some maths</h1>
<div class="calculator">
<input class="inputNumbers" id="input" type="number" placeholder="choose a number here">
<div class="buttons" id="buttons">
<button id="plus" class="btn btn-plus">+</button>
<button id="minus" class="btn btn-minus">-</button>
<button id="multiply" class="btn btn-multiply">*</button>
<button id="divide" class="btn btn-divide">/</button>
</div>
<div id="output" class="visor"></div>
</div>
</section>
Basically you do not attach event listeners on every element, but you attach same event on parent of all elements and you can track the source of event using e.target.

how to store elements in array but by trucating leading zeros

function getResult(exp)
{
var result, num = [], signs = [];
//console.log("here" + exp.lastIndexOf(""));
parts = exp.split(/([+-/*])/);
for (var i = 0; i < parts.length; i++)
{
var item = parts[i].trim()
if (isNaN(item))
signs.push(item);
else
num.push(item);
}
console.log(num);
}
function maincalculation()
{
var txtprint = document.getElementById("texa");
if(!document.getElementById("texa").value)
{
}
else
{
var result = getResult(txtprint.value);
txtprint.value = result;
}
}
<html>
<body>
<div class = "textbox">
<!-- <input type="text" value="" id="tex" />
<input type="button" value="equal" onclick="equal()" id="add" />
<input type="button" value="click-count" onclick="click()" id="click" />
<p><input type="button" name="button" value="Saying Hello" id="hello" onclick="hello();"/></p> -->
<br><br>
<input types="text" id="texa">
<input type = "button" value = "calculate" onclick="maincalculation()" />
</div>
</body>
</html>
My code contain text-box it takes the whole String type by the user now i want to store the array elements separately in array. it stores perfectly as it is but i want to store array elements like by truncating leading zeros i have use regex function num = num.replace(/^[0]+/g,""); it eliminate all the leading zeros as i want but when user type only 0 it will eliminate 0 value too and stores the blank so is there any way that if user type suppose like [10+30+001+08*0/89] then this value must be store like this [10+30+1+8*0/89] truncating all leading zeros but not the single zero value.
Example for my comment:
var regex = new RegExp('0*(?=[0-9])+', 'g');
console.log('0'.replace(regex, '')); //0
console.log('0000'.replace(regex, '')); //0
console.log('01'.replace(regex, '')); //1
console.log('00106'.replace(regex, '')); //106
console.log('4'.replace(regex, '')); //4
console.log('10+30+001+08*0/89'.replace(regex, ''));
function getResult(exp) {
var result, num = [], signs = [];
parts = exp.split(/([+-/*])/);
for (var i = 0; i < parts.length; i++) {
var item = parts[i].trim()
if (isNaN(item))
signs.push(item);
else
num.push(+item.replace(regex,''));
}
console.log(num);
}
function clickMe() {
getResult($('#calculation').val());
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="calculation" value="10+30+001+08*0/89"/>
<button onclick="clickMe()">Get result</button>

Why does my value keep returning as "NaN"?

Here is the link to the jsbin.
I was almost finished with my project (I thought I was) and then I tested it out. It is supposed to add buttons with the chosen title of the task and the number of points it awards. Every time the button is clicked the points would be added on to the "Points" section and every 500 points my "Level" would increase.
Upon finishing it, it worked. Then I went to clear the localStorage since that's what I used to save the information, but I wanted to start over. When I did that, the 'Points' section, or 'results' value, keeps returning as "NaN". The code is exactly the same as it was when it worked. Can someone please tell me how to fix this problem, thank you in advance.
Here is the code. (Used bootstrap for CSS)
HTML
<center>
<br>
<h2> Add task </h2>
<div class='well' style='width:500px' id="addc">
<div id="addc">
<input class='form-control' style='width:450px' id="btnName" type="text" placeholder="New Task" /><br>
<input class='form-control' style='width:450px' id="btnPoints" type="text" placeholder="Points" /><br>
<button id="addBtn">Add</button>
</div> </div>
<div class='well' style='width:230px' id="container">
</div>
<hr style="width:400px;">
<h3>Points </h3>
<div id="result">0</div>
</div>
<hr style="width:400px;">
<div style="width:400px;">
<h3>Level
<p id='lvl'>0</p>
</div>
<hr style="width:400px;">
</center>
JavaScript
var res = document.getElementById('result');
res.innerText = localStorage.getItem('myResult');
var level = document.getElementById('lvl');
level.textContent = localStorage.getItem('myLevel');
var btns = document.querySelectorAll('.btn');
for(var i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function() {
addToResult(this.getAttribute('data-points'));
this.parentNode.removeChild(this.nextElementSibling);
this.parentNode.removeChild(this);
});
}
var addBtn = document.getElementById('addBtn');
addBtn.className = "btn btn-default";
addBtn.addEventListener('click', function() {
var container = document.getElementById('container');
var btnName = document.getElementById('btnName').value;
var btnPoints = parseInt(document.getElementById('btnPoints').value);
if(!btnName)
btnName = "Button ?";
if(!btnPoints)
btnPoints = 50;
var newBtn = document.createElement('button');
var newPnt = document.createElement('span');
newBtn.className = 'btn btn-danger';
newBtn.innerText = btnName;
newBtn.setAttribute('data-points', btnPoints);
newBtn.addEventListener('click', function() {
addToResult(this.getAttribute('data-points'));
this.parentNode.removeChild(this.nextElementSibling);
this.parentNode.removeChild(this);
});
newPnt.className = 'label';
newPnt.innerText = "+" + btnPoints;
container.appendChild(newBtn);
container.appendChild(newPnt);
});
function addToResult(pts) {
var result = document.getElementById('result');
result.innerText = parseInt(result.innerText) + parseInt(pts);
var lvl = 0;
var a = 100;
while (result.innerText > 5*a) {
lvl+=1;
a+=100;
}
document.getElementById('lvl').innerText = lvl;
var res = document.getElementById('result');
localStorage.setItem("myResult", res.innerText);
var level = document.getElementById('lvl');
localStorage.setItem("myLevel", level.textContent);
}
You were parsing result.innerText as a number, but its value, initially, was actually either NaN or nothing, both which end up being NaN. One fix is to just check if it parsed to a number, and if it didn't, fall back to 0.
I just basically changed that and removed some getElementByIds that, in my opinion, were redundant, check the addToResult function:
http://jsfiddle.net/owc26a0p/1/
function addToResult(pts) {
// NaN is falsy, so you can just use || to make a fallback to 0
var result = parseInt(resDiv.innerText, 10) || 0,
lvl = 0,
a = 100;
result = result + parseInt(pts, 10) || 0;
while (result > 5 * a) {
lvl += 1;
a += 100;
}
resDiv.innerText = result;
levelDiv.innerText = lvl;
localStorage.setItem("myResult", result);
localStorage.setItem("myLevel", levelDiv.textContent);
}
I ended up using jsFiddle since I couldn't always get jsBin to save my changes. Good luck.

Categories