document.querySelectorAll Weird Behaviour - javascript

I have a simple HTML like below and corresponding java script code.
The issue is :
For .clear and .result buttons , two event listeners are getting attached and called
(storeInput as well as their actual listener). Actually , storeInput should not be get called in this case
To debug issue , I commented out below two lines :
//document.querySelector(".clear").addEventListener('click',clear);
//document.querySelector(".result").addEventListener('click',calculate);
So there are no event listeners for .clear and .result buttons
But still , storeInput listener gets called if they are clicked
Question is :
why document.querySelectorAll(".digit") and document.querySelectorAll(".operator") are adding event listeners to .clear and .result buttons as well ?
function storeInput() {
console.log('storeInput');
}
function clear() {
console.log('clear');
}
function calculate() {
console.log('calculate');
}
const digits = document.querySelectorAll(".digit");
digits.forEach(function() {
this.addEventListener('click', storeInput);
});
const operators = document.querySelectorAll(".operator");
operators.forEach(function() {
this.addEventListener('click', storeInput);
})
document.querySelector(".clear").addEventListener('click', clear);
document.querySelector(".result").addEventListener('click', calculate);
<input type="text" />
<br/>
<input type="button" class="digit" value="0" />
<input type="button" class="digit" value="1" />
<input type="button" class="digit" value="2" />
<input type="button" class="digit" value="3" />
<br/>
<input type="button" class="digit" value="4" />
<input type="button" class="digit" value="5" />
<input type="button" class="digit" value="6" />
<input type="button" class="digit" value="7" />
<br/>
<input type="button" class="digit" value="8" />
<input type="button" class="digit" value="9" />
<br/>
<input type="button" class="clear" value="C" />
<br/>
<input type="button" class="operator" value="+" />
<input type="button" class="operator" value="-" />
<input type="button" class="operator" value="/" />
<input type="button" class="operator" value="*" />
<br/>
<input type="button" class="result" value="=" />

In forEach, this has no special meaning, so what you're really doing is attaching those handlers to window, since this defaults to window in loose mode. (You may have seen jQuery code using each; jQuery sets this to each element in an each callback, but forEach doesn't work that way.)
To use the element within the forEach callback, accept the element as a parameter and use that parameter, see *** comments:
function storeInput() {
console.log('storeInput');
}
function clear() {
console.log('clear');
}
function calculate() {
console.log('calculate');
}
const digits = document.querySelectorAll(".digit");
digits.forEach(function(el) { // *** Note the parameter `el`
el.addEventListener('click', storeInput);
// ^ note using the parameter
});
const operators = document.querySelectorAll(".operator");
operators.forEach(function(el) { // *** Note the parameter `el`
el.addEventListener('click', storeInput);
// ^ note using the parameter
})
document.querySelector(".clear").addEventListener('click', clear);
document.querySelector(".result").addEventListener('click', calculate);
<input type="text" />
<br/>
<input type="button" class="digit" value="0" />
<input type="button" class="digit" value="1" />
<input type="button" class="digit" value="2" />
<input type="button" class="digit" value="3" />
<br/>
<input type="button" class="digit" value="4" />
<input type="button" class="digit" value="5" />
<input type="button" class="digit" value="6" />
<input type="button" class="digit" value="7" />
<br/>
<input type="button" class="digit" value="8" />
<input type="button" class="digit" value="9" />
<br/>
<input type="button" class="clear" value="C" />
<br/>
<input type="button" class="operator" value="+" />
<input type="button" class="operator" value="-" />
<input type="button" class="operator" value="/" />
<input type="button" class="operator" value="*" />
<br/>
<input type="button" class="result" value="=" />
Another option is to put a container around the digits, and another container around the operators, and just handle clicks on those containers, using the target property of the event object to see which digit or operator was clicked.
function storeInput(e) {
console.log('storeInput: ' + e.target.value);
}
function clear() {
console.log('clear');
}
function calculate() {
console.log('calculate');
}
document.querySelector(".digits").addEventListener('click', storeInput);
document.querySelector(".operators").addEventListener('click', storeInput);
document.querySelector(".clear").addEventListener('click', clear);
document.querySelector(".result").addEventListener('click', calculate);
<input type="text" />
<div class="digits">
<input type="button" class="digit" value="0" />
<input type="button" class="digit" value="1" />
<input type="button" class="digit" value="2" />
<input type="button" class="digit" value="3" />
<br/>
<input type="button" class="digit" value="4" />
<input type="button" class="digit" value="5" />
<input type="button" class="digit" value="6" />
<input type="button" class="digit" value="7" />
<br/>
<input type="button" class="digit" value="8" />
<input type="button" class="digit" value="9" />
</div>
<input type="button" class="clear" value="C" />
<div class="operators">
<input type="button" class="operator" value="+" />
<input type="button" class="operator" value="-" />
<input type="button" class="operator" value="/" />
<input type="button" class="operator" value="*" />
</div>
<input type="button" class="result" value="=" />

Related

Virtual keyboard with multiple inputs and auto jump to next input after reaching maxlength?

i need to create a virtual keyboard with multiple inputs and auto jump to next input after reaching maxlength (1)... on my code there are 2 inputs that i should fill but i can only fill the first input and not the second one. and auto jump to the next field should work too, can anybody help me with this ?
(there are 2 actif inputs and the others are (readonly) and the user needs to tap the digit and it should fill the first actif input with 1 number and automatically jump to the next actif input and tap again on another digit and it should write another number and that's all)
Here is my code.
<body onload="load();">
<div class="firma-box-resultado" style="display: flex; justify-content: center; align-items: center;">
<input type="text" id="" class="num-coordenada" readonly="">
<input type="text" id="tbInput" class="num-coordenada active completo" maxlength="1">
<input type="text" id="tbInput" class="num-coordenada active completo" maxlength="1">
<input type="text" id="" class="num-coordenada" readonly="">
<input type="text" id="" class="num-coordenada" readonly="">
<input type="text" id="" class="num-coordenada" readonly=""></div>
</div>
<div id="VirtualKey">
<input class="clave" id="btn1" type="button" onclick="input(this);" value="3" style="margin-right:1px;" />
<input class="clave" id="btn2" type="button" onclick="input(this);" value="8" style="margin-right:1px;" />
<input class="clave" id="btn3" type="button" onclick="input(this);" value="7" style="margin-right:1px;" />
<input class="clave" id="btn4" type="button" onclick="input(this);" value="0" style="margin-right:1px;" />
<input class="clave" id="btn5" type="button" onclick="input(this);" value="2" style="margin-bottom:5px;" />
<br />
<input class="clave" id="btn6" type="button" onclick="input(this);" value="1" style="margin-right:1px;" />
<input class="clave" id="btn7" type="button" onclick="input(this);" value="9" style="margin-right:1px;" />
<input class="clave" id="btn8" type="button" onclick="input(this);" value="4" style="margin-right:1px;" />
<input class="clave" id="btn9" type="button" onclick="input(this);" value="5" style="margin-right:1px;" />
<input class="clave" id="btn0" type="button" onclick="input(this);" value="6" style="margin-right:1px;" />
<br />
<br />
<input id="btnDel" type="button" value="Borrar" onclick="del();" />
</div>
<script type="text/javascript">
function input(e) {
var tbInput = document.getElementById("tbInput");
tbInput.value = tbInput.value + e.value;
tbInput2.value = tbInput2.value + e.value;
}
function del() {
var tbInput = document.getElementById("tbInput");
tbInput.value = tbInput.value.substr(0, tbInput.value.length - 1);
}
function load() {
var array = new Array();
while (array.length < 10) {
var temp = Math.round(Math.random() * 9);
if (!contain(array, temp)) {
array.push(temp);
}
}
for (i = 0; i < 10; i++) {
var btn = document.getElementById("btn" + i);
btn.value = array[i];
}
}
let $inputs = $('.firma-box-resultado input').on('input', e => {
let $input = $(e.target);
let index = $inputs.index($input);
if ($input.val().length >= $input.prop('maxlength')) {
$inputs.eq(index + 1).prop('enabled', false).focus();
}
});
</script>
</body>
Can you try this :
To expand the number of inputs, check the length of the input by order if the first is 0 (empty) the fill it if not check the next one ...
if (tbInput.val().length == 0) {
tbInput.val(e.value);
}
else if (tbInput2.val().length == 0)
tbInput2.val(e.value);
else {
tbInput3.val(e.value);
}
function input(e) {
var tbInput = $("#tbInput");
var tbInput2 = $("#tbInput2");
var tbInput3 = $("#tbInput3");
if (tbInput.val().length == 0) {
tbInput.val(e.value);
}
else if (tbInput2.val().length == 0)
tbInput2.val(e.value);
else {
tbInput3.val(e.value);
}
}
function del() {
var tbInput = $(".num-coordenada");
tbInput.val('');
}
function load() {
var array = new Array();
while (array.length < 10) {
var temp = Math.round(Math.random() * 9);
if (!contain(array, temp)) {
array.push(temp);
}
}
for (i = 0; i < 10; i++) {
var btn = document.getElementById("btn" + i);
btn.value = array[i];
}
}
let $inputs = $('.firma-box-resultado input').on('input', e => {
let $input = $(e.target);
let index = $inputs.index($input);
if ($input.val().length >= $input.prop('maxlength')) {
$inputs.eq(index + 1).prop('enabled', false).focus();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body onload="load();">
<div class="firma-box-resultado" >
<input type="text" id="tbInput" class="num-coordenada active completo" maxlength="1">
<input type="text" id="tbInput2" class="num-coordenada active completo" maxlength="1">
<input type="text" id="tbInput3" class="num-coordenada" readonly="">
<input type="text" class="num-coordenada" readonly="">
<input type="text" class="num-coordenada" readonly="">
</div>
<div id="VirtualKey">
<input class="clave" id="btn1" type="button" onclick="input(this);" value="3" style="margin-right:1px;" />
<input class="clave" id="btn2" type="button" onclick="input(this);" value="8" style="margin-right:1px;" />
<input class="clave" id="btn3" type="button" onclick="input(this);" value="7" style="margin-right:1px;" />
<input class="clave" id="btn4" type="button" onclick="input(this);" value="0" style="margin-right:1px;" />
<input class="clave" id="btn5" type="button" onclick="input(this);" value="2" style="margin-bottom:5px;" />
<br />
<input class="clave" id="btn6" type="button" onclick="input(this);" value="1" style="margin-right:1px;" />
<input class="clave" id="btn7" type="button" onclick="input(this);" value="9" style="margin-right:1px;" />
<input class="clave" id="btn8" type="button" onclick="input(this);" value="4" style="margin-right:1px;" />
<input class="clave" id="btn9" type="button" onclick="input(this);" value="5" style="margin-right:1px;" />
<input class="clave" id="btn0" type="button" onclick="input(this);" value="6" style="margin-right:1px;" />
<br />
<br />
<input id="btnDel" type="button" value="Borrar" onclick="del();" />
</div>
</body>

Maxlength not working when using Javascript number inputs

I have a slight problem with inserting numbers in the input box.
To be more specific.I use the custom made keypad that shows on the screen,and the numbers can only be written in the input box by using that same keypad,with the max of 5 numbers that can be written.But the HTML maxlength atrribute in this case doesn't work.It works when I try to write the number using the actual keyboard,but when inserting with a custom keypad it won't work.
The question is how can I make it to work?
<script>
function addNumber(element) {
document.getElementById('child').value = document.getElementById('child').value + element.value;
}
function deleteNumber(){
document.getElementById('child').value='';
}
</script>
<div class='form-group'>
<div id="staticParent">
<div class='col-md-6'>
<input class='form-control' id='child' name="username" type='text' maxlength="5" readonly='readonly' />
<input type="button" class="fbutton" name="1" value="1" id="1" onClick=addNumber(this); />
<input type="button" class="fbutton" name="2" value="2" id="2" onClick=addNumber(this); />
<input type="button" class="fbutton" name="3" value="3" id="3" onClick=addNumber(this); />
<input type="button" class="fbutton" name="4" value="4" id="4" onClick=addNumber(this); />
<input type="button" class="fbutton" name="5" value="5" id="5" onClick=addNumber(this); />
<input type="button" class="fbutton" name="6" value="6" id="6" onClick=addNumber(this); />
<input type="button" class="fbutton" name="7" value="7" id="7" onClick=addNumber(this); />
<input type="button" class="fbutton" name="8" value="8" id="8" onClick=addNumber(this); />
<input type="button" class="fbutton" name="9" value="9" id="9" onClick=addNumber(this); />
<input type="button" class="fbutton" name="0" value="0" id="0" onClick=addNumber(this); />
<input type='button' class='fbutton' name='delete' value='Delete' onClick=deleteNumber(this); />
</div>
</div>
you can replace your addNumber function with below one, That will solve your problem.
function addNumber(element) {
var value1 = document.getElementById('child').value + element.value;
if(value1.length > 5) return false;
document.getElementById('child').value = value1;
}
you can try this maxlength=5.you will remove ""
<input class='form-control' id='child' name="username" type='text' maxlength=5 readonly='readonly' />
Since maxlength only works if the user actually uses the real keyboard and not for programatically changing the value, you can't do it like that.
To get around it simply apply a check in your addNumber function:
function addNumber() {
var input = document.getElementById('child');
if (input.value.length > 5) {
return false;
}
else {
// Do stuff
}
}
This won't add a new number unless the input length is less or equal to 5.
Also you shouldn't call things with the onclick attribute. Instead add your event listeners with addEventListener:
var addBtns = document.getElementsByClassName('fbutton');
for (var i = 0; i < addBtns.length; i++) {
addBtns[i].addEventListener('click', addNumber);
}
Note that you have to use a loop to add the event listeners since addBtns is an array.

jAuery selection button

I have table like this
And I need do selection 7 buttons and more. with min and max.
Like type="checkbox" or type="radio" but with type="button" (to do style button with css/css3)
<div class="button">
<table>
<tr>
<td>
<input type="button" id="button1" name="1" value="01" />
<input type="button" id="button1" name="2" value="02" />
<input type="button" id="button1" name="3" value="03" />
<input type="button" id="button1" name="4" value="04" />
<input type="button" id="button1" name="5" value="05" />
<input type="button" id="button1" name="6" value="06" />
<input type="button" id="button1" name="7" value="07" />
<input type="button" id="button1" name="8" value="08" />
<input type="button" id="button1" name="9" value="09" />
<input type="button" id="button1" name="10" value="10" />
</td>
</tr>
<tr>
<td>
<input type="button" id="button1" name="11" value="11" />
<input type="button" id="button1" name="12" value="12" />
<input type="button" id="button1" name="13" value="13" />
<input type="button" id="button1" name="14" value="14" />
<input type="button" id="button1" name="15" value="15" />
<input type="button" id="button1" name="16" value="16" />
<input type="button" id="button1" name="17" value="17" />
<input type="button" id="button1" name="18" value="18" />
<input type="button" id="button1" name="19" value="19" />
<input type="button" id="button1" name="20" value="20" />
</td>
</tr>
<tr>
<td>
<input type="button" id="button1" name="21" value="21" />
<input type="button" id="button1" name="22" value="22" />
<input type="button" id="button1" name="23" value="23" />
<input type="button" id="button1" name="24" value="24" />
<input type="button" id="button1" name="25" value="25" />
<input type="button" id="button1" name="26" value="26" />
<input type="button" id="button1" name="27" value="27" />
<input type="button" id="button1" name="28" value="28" />
<input type="button" id="button1" name="29" value="29" />
<input type="button" id="button1" name="30" value="30" />
</td>
</tr>
<tr>
<td>
<input type="button" id="button1" name="31" value="31" />
<input type="button" id="button1" name="32" value="32" />
<input type="button" id="button1" name="33" value="33" />
<input type="button" id="button1" name="34" value="34" />
<input type="button" id="button1" name="35" value="35" />
<input type="button" id="button1" name="36" value="36" />
<input type="button" id="button1" name="37" value="37" />
<input type="button" id="button1" name="38" value="38" />
<input type="button" id="button1" name="39" value="39" />
<input type="button" id="button1" name="40" value="40" />
</td>
</tr>
<tr>
<td>
<input type="button" id="button1" name="41" value="41" />
<input type="button" id="button1" name="42" value="42" />
<input type="button" id="button1" name="43" value="43" />
<input type="button" id="button1" name="44" value="44" />
<input type="button" id="button1" name="45" value="45" />
<input type="button" id="button1" name="46" value="46" />
<input type="button" id="button1" name="47" value="47" />
<input type="button" id="button1" name="48" value="48" />
<input type="button" id="button1" name="49" value="49" />
<input type="button" id="button1" name="50" value="50" />
</td>
</tr>
<tr>
<td>
<input type="button" id="button1" name="51" value="51" />
<input type="button" id="button1" name="52" value="52" />
<input type="button" id="button1" name="53" value="53" />
<input type="button" id="button1" name="54" value="54" />
<input type="button" id="button1" name="55" value="55" />
<input type="button" id="button1" name="56" value="56" />
<input type="button" id="button1" name="57" value="57" />
<input type="button" id="button1" name="58" value="58" />
<input type="button" id="button1" name="59" value="59" />
<input type="button" id="button1" name="60" value="60" />
</td>
</tr>
<tr>
<td>
<input type="button" id="button1" name="61" value="61" />
<input type="button" id="button1" name="62" value="62" />
<input type="button" id="button1" name="63" value="63" />
<input type="button" id="button1" name="64" value="64" />
<input type="button" id="button1" name="65" value="65" />
<input type="button" id="button1" name="66" value="66" />
<input type="button" id="button1" name="67" value="67" />
<input type="button" id="button1" name="68" value="68" />
<input type="button" id="button1" name="69" value="69" />
<input type="button" id="button1" name="70" value="70" />
</td>
</tr>
</table>
</div>
Here is example http://jsfiddle.net/n2RAh/ (now i can select only one)
If you want to work with the inputs, use JavaScript not CSS.
With jQuery, you can add "focus" class.
$(".button input[type=button]").click(function () {
$(this).toggleClass("focus");
});
$("#HS").click(function () { // Add an input
var array = []
$(".button input[type=button].focus").each(function () {
array.push($(this).val());
});
console.log(array.join(", "));
});
See : http://jsfiddle.net/Dp8tR/
Old solution :
$("input[type=button]").click(function () {
$(this).toggleClass("focus");
});
See : http://jsfiddle.net/TTL8d/
Use checkbox and style them as you feel like (button). And also style the :checked state.
add class to all buttons for example: "markble".
jQuery:
$( ".markble" ).click(function() {
$( this ).toggleClass( "activ-now" );
});
CSS:
.activ-now {
border-color: black;
border-style: solid;
background: yellow;
}
you can detect all selected by class "activ-now".
demo: http://jsfiddle.net/n2RAh/3/

Javascript calculator keeps concatenating calculation results with first number entered for next calculation

<body>
<FORM NAME="Calculator">
<TABLE BORDER=4>
<TR>
<TD>
<input type="text" name="Input" Size="22" value="">
<br>
</TD>
</TR>
<TR>
<TD>
<INPUT TYPE="button" NAME="one" VALUE="1" class ="digit" >
<INPUT TYPE="button" NAME="two" VALUE="2" class ="digit" >
<INPUT TYPE="button" NAME="three" VALUE="3" class ="digit" >
<INPUT TYPE="button" NAME="plus" VALUE="+" class ="operand">
<br>
<INPUT TYPE="button" NAME="four" VALUE="4" class ="digit">
<INPUT TYPE="button" NAME="five" VALUE="5" class ="digit">
<INPUT TYPE="button" NAME="six" VALUE="6" class ="digit">
<INPUT TYPE="button" NAME="minus" VALUE="-" class="operand">
<br>
<INPUT TYPE="button" NAME="seven" VALUE="7" class ="digit">
<INPUT TYPE="button" NAME="eight" VALUE="8" class ="digit">
<INPUT TYPE="button" NAME="nine" VALUE="9" class ="digit">
<INPUT TYPE="button" NAME="times" VALUE="*" class ="operand">
<br>
<INPUT TYPE="button" NAME="clear" VALUE="c" class ="special">
<INPUT TYPE="button" NAME="zero" VALUE="0" class ="digit">
<INPUT TYPE="button" NAME="Execute" VALUE="=" class ="solve">
<INPUT TYPE="button" NAME="div" VALUE="/" class ="operand">
<br>
</TD>
</TR>
</TABLE>
</FORM>
<script type = "text/javascript" src="C:\Users\Quonn\Desktop\QBJS\calculatorjs.js">
</script>
</body>
I am building a configurable calculator but I am having some with my logic/getting it to behave exactly how i want. I have two questions.
Question # 1: How can I change my logic so that I can replace "evil eval"?
var timer;
document.onclick = function(x) {
var info = x.target;
clearTimeout(timer);
timer= setTimeout(function(){addDigit(x);},200);
}
Question #2: How can change my logic in this function so that after a calculation result is displayed, the first number entered for the next calculation isn't just concatenated to the previous calculation's result?
function addDigit(x){
if (x.target.className === "digit" || x.target.className ==="operand") {
document.Calculator.Input.value += "" + x.target.value;
}
else if (x.target.className === "solve") {
result = eval(document.Calculator.Input.value);
document.Calculator.Input.value = result;
}
else {
document.Calculator.Input.value = "";
}
}
You are concatenating strings. You should have a look at parseInt / parseFloat; watch out for the radix, otherwise JavaScript will try to guess it...

Writing numeric words with onkeypress

How can I write numeric numbers into an input field by pressing a button?
Suppose I have a button:
<input type="button" value="1">
Then I want, that when numeric pad button 1 is pressed it adds numeric words just like Windows Calculator.
I'm not sure what you are asking, but this code will add numbers to an input box (using jQuery).
HTML
<input id="data" type="text" />
<br />
<br />
<input type="button" value="1" />
<input type="button" value="2" />
<input type="button" value="3" /><br />
<input type="button" value="4" />
<input type="button" value="5" />
<input type="button" value="6" /><br />
<input type="button" value="7" />
<input type="button" value="8" />
<input type="button" value="9" />
Script
$(document).ready(function(){
$(':button').click(function(){
$('#data').val( $('#data').val() + $(this).val() );
})
})

Categories

Resources