I am trying to code a calculator but the equal button is not working with eval() and its giving null with (Invalid or unexpected token
at HTMLButtonElement.)
const btns = document.querySelectorAll('.btn');
const screen = document.querySelector('.screen');
const equalbtn = document.querySelector('.btnequal');
for(i=0; i<btns.length; i++){
btns[i].addEventListener('click', function(){
var number = this.getAttribute("data-num");
screen.value += number;
//console.log(screen.value);
})
}
equalbtn.addEventListener('click', function(){
if(screen.value === ''){
alert('Please select a value');
} else {
let value = eval(screen.value);
console.log(value);
screen.value = value;
}
})
This is an example of a running calculator based on your given code. Note that I never got any null value. Maybe your html code was wrong, you didn't add any.
const btns = document.querySelectorAll('.btn');
const screen = document.querySelector('.screen');
const equalbtn = document.querySelector('.btnequal');
let reset = false;
for(let i=0; i<btns.length; i++){
btns[i].addEventListener('click', function(){
let number = this.getAttribute("data-num");
if(reset){
screen.value = number;
reset = false;
}
else{
screen.value += number;
}
})
}
equalbtn.addEventListener('click', function(){
if(screen.value === ''){
alert('Please select a value');
} else {
let value = eval(screen.value);
screen.value = value;
reset = true;
}
})
<input class="screen" readonly="readonly" />
<button class="btn" data-num="1">1</button>
<button class="btn" data-num="2">2</button>
<button class="btn" data-num="3">3</button>
<button class="btn" data-num="+">+</button>
<button class="btn" data-num="-">-</button>
<button class="btn" data-num="*">*</button>
<button class="btn" data-num="/">/</button>
<button class="btnequal">=</button>
Related
I have a code like this -
<button class="btn">New York</button>
<button class="btn">Amsterdam</button>
<button class="btn">New Jersey</button>
<button class="btn">Alabama</button>
<button class="btn">Michigan</button>
<button id="undo" class="undo-selection">Undo last selection</button>
and have below code to check the order at which these buttons are clicked.
var click = 0;
var buttons = document.querySelectorAll('button.btn');
buttons.forEach(button => {
button.addEventListener('click', function(){
var current = button.innerText;
var existingClicks = current.split(" ");
if(existingClicks.length > 1) {
button.innerText += ` & ${++click}`;
}
else {
button.innerText = `clicked = ${++click}`;
}
});
});
By using the Undo button I want to clear last selection made and should be able to select new button. Any help is appreciated.
Maybe something like this:
let click = 0;
const buttons = document.querySelectorAll('button.btn');
const clicks = [];
buttons.forEach((button, index) => {
button.addEventListener('click', function(){
const clicked = clicks.includes(index);
clicks.push(index);
if (!clicked) {
button.innerText = `clicked = ${++click}`;
} else {
button.innerText += ` & ${++click}`;
}
});
});
document.getElementById('undo').addEventListener('click', () => {
if (!clicks.length) {
return;
}
const lastClicked = clicks.pop();
click--;
let text = buttons[lastClicked].innerText.split('&');
text.pop();
text = text.join('&');
buttons[lastClicked].innerText = text || buttons[lastClicked].getAttribute('data-text');
});
<button class="btn" data-text="New York">New York</button>
<button class="btn" data-text="Amsterdam">Amsterdam</button>
<button class="btn" data-text="New Jersey">New Jersey</button>
<button class="btn" data-text="Alabama">Alabama</button>
<button class="btn" data-text="Michigan">Michigan</button>
<button id="undo" class="undo-selection">Undo last selection</button>
I have an Virtual keyboard with Javascript the keyboard is typing in two inputs after reached maxlength it is focusing to second input. my problem is when i want to type in first input i should clicked to first input to focus it than typing with keyboard numbers
My question is How i can typing using this keyboard without clicking inside input, the first input should start typing immediately after i clicked on the buttons numbers
const maxLength = 7;
const firstInput = document.querySelector("#pin");
const secondInput = document.querySelector("#key");
const changedEvent = new Event("change")
let activeInput;
firstInput.addEventListener("focus", (event) => {
activeInput = event.target;
});
firstInput.addEventListener("change", (event) => {
console.log("i'm changing!");
if (firstInput.value.length >= maxLength) {
activeInput = secondInput;
secondInput.focus();
}
});
secondInput.addEventListener("focus", (event) => {
activeInput = event.target;
});
function resetNumber() {
if (!activeInput) {
console.log("pin");
return;
}
activeInput.value = "";
}
function setNumber(number) {
if (!activeInput) {
console.log("pin");
return;
}
activeInput.value = activeInput.value === number ? "" : (activeInput.value += number);
// manually tell the input that it has changed, so that the event listener defined above gets called. this usually only will happen with actual keyboard input
activeInput.dispatchEvent(changedEvent);
}
<button onclick="resetNumber()">Reset</button>
<button onclick="setNumber(0)">0</button>
<button onclick="setNumber(1)">1</button>
<button onclick="setNumber(2)">2</button>
<button onclick="setNumber(3)">3</button>
<button onclick="setNumber(4)">4</button>
<button onclick="setNumber(5)">5</button>
<button onclick="setNumber(6)">6</button>
<button onclick="setNumber(7)">7</button>
<button onclick="setNumber(8)">8</button>
<button onclick="setNumber(9)">9</button>
<br />
<input type="text" id="pin" />
<input type="text" id="key" />
<button id="reset" onclick="resetNumber()">Reset</button>
<br />
<input type="text" id="pin" />
<input type="text" id="key" />
<script>
const maxLength = 7;
const firstInput = document.querySelector('#pin');
const secondInput = document.querySelector('#key');
const resetBtn = document.querySelector('#reset');
for (let i = 9; i >= 0; i--) {
const numBtn = document.createElement('button');
numBtn.className = 'number';
numBtn.innerText = i;
resetBtn.parentElement.insertBefore(numBtn, resetBtn.nextSibling);
}
const numberBtns = document.querySelectorAll('.number');
const resetNumber = () => {
firstInput.setAttribute('value', '');
secondInput.setAttribute('value', '');
};
const setVal = (e) => {
const num = parseInt(e.target.innerText, 10);
if (firstInput.value.length <= maxLength) return firstInput.setAttribute('value', firstInput.value + num);
secondInput.setAttribute('value', secondInput.value + num);
};
numberBtns.forEach((btn) => btn.addEventListener('click', setVal));
</script>
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.
I just started programming with js again and having some trouble.
This is the code i have problems with:
var actual = [10,50,20];
var sum = 0;
for(var i = actual.length; i > 0; i--){
sum = sum + actual[i];
}
What did i do wrong?
Start loop from actual.length-1, because every array starts from 0, so last element is actual.length-1 not actual.length.
I see Your calculator code is too complicated.
You do low level operation to add just "1" You multiply all things to 10 and add 1.
Be simple (;
var inputElement = document.getElementById("input");
var resultElement = document.getElementById("result");
var accept = [0,1,2,3,4,5,6,7,8,9,'-','+','calc'];
var input = [];
function op(value){
if(accept.indexOf(value) < 0) {
return;
}
if(value == 'calc') {
return calc();
}
input.push(value);
inputElement.innerHTML = input.join('');
}
function calc() {
resultElement.innerHTML = eval(input.join(''));
input = [];
}
<button onclick="op(1)">1</button>
<button onclick="op(2)">2</button>
<button onclick="op(3)">3</button>
<br/>
<button onclick="op(4)">4</button>
<button onclick="op(5)">5</button>
<button onclick="op(6)">6</button>
<br/>
<button onclick="op(7)">7</button>
<button onclick="op(8)">8</button>
<button onclick="op(9)">9</button>
<br/>
<button onclick="op(0)">0</button>
<button onclick="op('.')">.</button>
<button onclick="op('calc')">=</button>
<hr/>
<button onclick="op('+')">+</button>
<button onclick="op('-')">-</button>
<hr/>
INPUT:<div id="input"></div>
DISPLAY:<div id="result"></div>
I have a code that uses localStorage and javascript. I tried to add more slots, like slot1, slot2, slot3 up to 5. I just copy and paste then change the variable names like like slot1, slot2, slot3 up to 5. But it won't work. Help will be appreciated so much.
Javascript:
var slot = localStorage.getItem("slot");
if (slot == null) {
slot = 10;
}
document.getElementById("slot").innerText = slot;
function reduceSlot() {
if (slot >= 1) {
slot--;
localStorage.setItem("slot", slot);
if (slot > 0) {
document.getElementById('slot').innerText = slot;
} else {
document.getElementById('slot').innerText = "FULL";
document.getElementById("button1").style.display = "none";
}
}
}
document.getElementById("button1").onclick = reduceSlot;
function clearLocalStorage() {
localStorage.clear();
}
HTML:
<p id="slot">10</p>
Deduct
<button onclick="window.localStorage.clear();">Clear All</button>
Fiddle: http://jsfiddle.net/barmar/K8stQ/3/
not sure but. is this what you want to do?? working demo
i changed your code a bit.. you can change it into your liking later..
<span id="slot0">10</span><input type="button" value="Deduct" onclick="(function(){reduceSlot(0)})()" ><br>
<span id="slot1">10</span><input type="button" value="Deduct" onclick="(function(){reduceSlot(1)})()" ><br>
<span id="slot2">10</span><input type="button" value="Deduct" onclick="(function(){reduceSlot(2)})()" ><br>
<span id="slot3">10</span><input type="button" value="Deduct" onclick="(function(){reduceSlot(3)})()" ><br>
<span id="slot4">10</span><input type="button" value="Deduct" onclick="(function(){reduceSlot(4)})()" ><br>
<p>
<button onclick="clearAll()">Clear All</button>
</p>
and for the js...
ls = localStorage.getItem("slots") ;
if(!ls) { localStorage.setItem("slots", "10,10,10,10,10");
}
var slots = localStorage.getItem("slots").split(',').map(Number);
window.onload = updateSlots;
function updateSlots() { for(var i=0;i<slots.length;i++) {
document.getElementById('slot' + i ).innerHTML = slots[i] ;
}}
var reduceSlot = function(slotId) {
console.log(slots[slotId]) ;
if(slots[slotId] >= 1) {
slots[slotId]--; localStorage.setItem("slots",slots);
document.getElementById('slot' + slotId).innerHTML = slots[slotId];
}
else { document.getElementById('slot'+slotId).innerText = "FULL";
}
};
function clearAll() {
window.localStorage.clear();
slots = [10,10,10,10,10];
updateSlots();
}
Try this,
Script
window.ready = function() {
checkStorage();
}
function checkStorage() {
var slot = localStorage.getItem("slot");
if (slot == null) {
slot = 10;
}
document.getElementById("slot").innerHTML = slot;
}
function reduceSlot() {
var slot = localStorage.getItem("slot");
if (slot == null) {
slot = 10;
}
if (slot >= 1) {
slot--;
localStorage.setItem("slot", slot);
if (slot > 0) {
document.getElementById('slot').innerHTML = slot;
} else {
document.getElementById('slot').innerHTML = "FULL";
document.getElementById("button1").style.display = "none";
}
}
}
document.getElementById("button1").onclick = reduceSlot;
document.getElementById("clear").onclick = clear_me;
function clear_me() {
localStorage.clear();
checkStorage();
}
HTML
<p id="slot">10</p>
Deduct
<button id="clear">Clear All</button>
Demo