Javascript Integer increment does not work unless called from function - javascript

I was going to post this as a question to a problem but i later found a 'solution' (if that is what it is) and now this is more like an attempt to understand the situation.
I have a javascript code that displays the number 0 on the screen and then when a button is clicked, the number is supposed to increase according to the amount of times the button is clicked.
This was the code i used initially:
var number = 0;
$ (document).ready (function() {
document.getElementById("display").innerHTML = "Number of clicks: " + number;
$("#submit").bind ('click', function(event) {
document.getElementById("display").innerHTML = "Number of clicks: " + number++;
});
});
Problem was the button click event only worked AFTER the second click.Meaning i had to click the button twice before the incrementation worked.
So i created a function:
function increment () {
number++;
return number;
}
and then changed the last line of the initial code to:
document.getElementById("display").innerHTML = "Number of clicks: " + increment();
Now the number increases the first time i click on the button.
I just need to know why the first method didn't work.

Use ++number instead of number++
number++ increases the value of number afterwards.

You code is running fine, even in the first time. But the value displayed is1 less than the number of the clicks.
You are using prefix increment operator (++counter). In prefix increment operation first the value is evaluated or returned and then incremented.
But in postfix increment operation (counter++) first the value will be incremented and then returned
Use the existing code and initialize the number as 1 and execute the code.
You will get the expected result.
Should you want to maintain the initialization as 0, use postfix increment operator to get the desired result.
My recommendation would be not to use either of them but the below one
number += 1;

This is pretty common in a lot of languages.
var i = 0;
1 + i++
returns 1
var i = 0;
1 + ++i
returns 2
The difference is whether the variable is incremented before or after being evaluated in the expression.

Use this
$('#target').click(function() {
$('#output').html(function(i, val) { return val*1+1 });
});
HTML is
<button id="target" type="button">Click Me</button>
<div id="output">10</div>
SEE DEMO HERE

The answer is simple, why your first code did not work for you, as expected.
var number = 0;
$ (document).ready (function() {
document.getElementById("display").innerHTML = "Number of clicks: " + number;
$("#submit").bind ('click', function(event) {
document.getElementById("display").innerHTML = "Number of clicks: " + number++;
});
});
>>> This first time when DOM element load, The Value get printed as :
output : Number of clicks: 0 // because you have initialize number as 0.
Now when you click "Click Button", you have POST-INCREMENTED the Value, means
the value get's incremented after the action is completed. So in this case,
when you click first time, the number is still 0 and get printed again as
"Number of clicks": 0 and then the value get's incremented by Post-increment
and become's 1. When you click for second time,
the output :"Number of click": 1 get's printed.

Related

Setting formatted value breaks function

I've got this function to modify a string to a USD-like format
function formatAmount(el){
var val = el.value;
//Only Numbers
val = val.replace(/[^0-9]/gi, '');
// Pad with Zeros
val = val.padStart(3,0);
// Value with Period
val = val.slice(0, -2) + '.' + val.slice(-2);
// Append $
val = '$' + val;
console.log( val );
//el.value = val; // Breaks??
}
<input type="text" onkeyup="formatAmount(this);" />
When formatting the value, it works just fine: Typing 12345 into the input will log $123.45. As soon as I change the value with el.value = val;, the function seems to get a little weird, and I can't quite figure out why. 12345 now returns $0123.45 if you type fast or $00123.45 if you type slowly. Why is is appending the 0's to the string when changing the field value, but not when logging it without changing?
Edit:
Based on what #Dennis mentioned, wrapping it in a typing-timeout function seems to work, as long as the timeout is sufficiently high. 10ms doesn't work, but 100ms seems to? This doesn't seem very elegant, however:
var formatTimeout = null;
function formatAmount(el){
clearTimeout(formatTimeout);
formatTimeout = setTimeout(function(){
var val = el.value;
//Only Numbers
val = val.replace(/[^0-9]/gi, '');
// Pad with Zeros
val = val.padStart(3,0);
// Value with Period
val = val.slice(0, -2) + '.' + val.slice(-2);
// Append $
val = '$' + val;
//console.log( val );
el.value = val; // Breaks??
}, 100);
}
The function gets triggered at every key press.
If you type in 12345, it will get triggered 5 times.
Here's what your value will look like if typing sufficiently slowly:
1, the function will change it to $0.01
2, it gets added at the end of the existing string to make it $0.012, which gets formatted by the function as $00.12
3, the initial string will be $00.123, and it will get formatted as $001.23.
...
The final result will be $00123.45.
There are a few ways to deal with this problem. The simplest solution would be to trim the initial 0s to keep your number clean, right before padding with zeros.
This difference between results while console.log and actually assigning the value is because the input to the formatAmount function is different each time.
When you set the value of the input field, this is what happens;
-> User enter `1`
-> formatAmount takes the value, converts it to $0.01 and *sets the value* to the input box
-> user enter `2`
-> formatAmount takes the value ($0.012), converts it to $00.12 and *sets the value* to the input box
This continues until you finish 12345 and get $00123.45. This happens because the two 0s you added in the start never vanish after the first 1 is typed.
Also, console.log works fine because everytime, the value received is 1, 12,...12345. The logic works fine for these. Only fails when you set the value back
A keyup action in javascript seems to work fine. Tested with various speeds and works like a charm. Also, try pasting numbers and use regex to remove leading 0's like
var textInput = document.getElementById('hello');
textInput.onkeyup = function (e) {
formatAmount(textInput.value);
};
function formatAmount(el){
var val = el;
//Only Numbers
val = val.replace(/[^0-9]/gi, '');
// Pad with Zeros
val = val.padStart(3,0);
// replace leading 0's
val = val.replace(/^0+/, '');
// Value with Period
val = val.slice(0, -2) + '.' + val.slice(-2);
// Append $
val = '$' + val;
textInput.value = val;
}
<input type="text" id="hello" />
Just to show an alternative starting point using Intl.NumberFormat.prototype.format(). Feel free to adjust to your requirements.
function formatAmount(el){
el.value = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumIntegerDigits: 3 }).format(parseFloat(el.value.indexOf('$') === 0 ? el.value.substr(1) : el.value));
}
<input type="text" onblur="formatAmount(this);" />
My guess is that your function is being executed multiple times at the same time, the first execution is not even finished before the next one starts. You need to check if the function is already running.

Calculate Quantity * Price = Total | Total / Price = Quantity

I need some help.
I want the "Total" to be calculated by the "quantity * price = total" (so far it's ok). The problem is that I also need "Quantity" to be calculated by "total / price = quantity" ie if one field is changed the other will automatically change.
I made a very simple example code: JSFiddle
//Value of Price (Hidden)
$('#price').val(31245);
//Calculation
var qty=$("#qty");
qty.keyup(function(){
var total=isNaN(parseInt(qty.val()* $("#price").val())) ? 0 :(qty.val()* $("#price").val())
$("#total").val(total);
});
var total=$("#total");
total.keyup(function(){
var qty=isNaN(parseInt(total.val()/ $("#price").val())) ? 0 :(total.val()/ $("#price").val())
$("#qty").val(qty);
});
//Mask Total input
var originalVal = $.fn.val;
$.fn.val = function(value) {
if (typeof value == 'undefined') {
return originalVal.call(this);
} else {
setTimeout(function() {
this.trigger('mask.maskMoney');
}.bind(this), 100);
return originalVal.call(this, value);
}
};
$('#total').maskMoney();
$('#total').on('click mousedown mouseup focus blur keydown change input', function(event) {
console.log('This Happened:'+ event.type);
});
In it the first part "quantity * price = total" works ok and is updated automatically. However, when in the second part "total / price = quantity" is the problem appears.
When the number entered in the Total input is too large (Example: 9,876.23) the quantity is not calculated automatically and returns 0. But if the number is for example 893.23 the quantity works as it should.
Could any of you help me? (sorry for my bad english)
Ps: I needed the value of the quantity field not to exceed 8 decimals (example: 0.00000000). But in all the attempts I had the calculation does not work.
The easiest way to debug this is to breakpoint the appropriate spot and see what's happening. For instance, in Chrome, pull up your Dev Tools, find the result panel, and set a breakpoint:
Then, in the console, start evaluating parts of the expression. Here, I've evaluated total.val(). So what's happening?
The key thing to realize is that total.val() returns a string! So what happens when you use something like "9,873.76" as a number? That's right, JavaScript doesn't know what to do with the comma and punts, returning NaN.
Why did it show up when you had a number in the thousands? Because smaller numbers don't have commas.
So, as a result, you're getting zero.
The thousands separator made automatically by the mask is not understood in the calculation, so you should remove it first from the input
var qty=isNaN(parseInt(total.val().replace(",", "")/ $("#price").val())) ? 0 :(total.val().replace(",", "")/ $("#price").val())
however, the problem will appear if more than one thousands separator appears (1,000,000), so you you can globally remove all thousands separators:
var my_total = total.val().replace(/,/, "");

Javascript prompt and alert inputting a number and it will loop and you will input numbers to get the average of it

I have below javascript code with loop but I can't get the average of it. I'm not sure what's wrong with my code. It's like the first prompt you will input a number and it will loop and you input numbers like how much you entered and you will get the sum of all the numbers and get the average of it after it's done. Here's the code that I have.
function show_prompt()
{
var n=prompt("Input a number: ", "Number here");
if (n==n)
{
var i=1;
do
{
var g=prompt("Input grade: " );
var grade=parseInt(g);
var total=grade+grade;
i++;
}
while(i<=n);
}
var average=(total)/n;
document.write("Average is: " +average);
}
Thanks in advance!
You are overriding your "total" variable in each interval with double the grade value.
var grade=parseInt(g);
var total=grade+grade;
should be changed to
var grade=parseInt(g);
total=total+grade;
Also, you need to initialize the "total" variable in the beginning of your code.
See demo code: http://jsfiddle.net/56ouvan3/1/
I would also recommend some input validation (such as checking that the number of grades requested to average are greater than 0, all grades are positive, etc.)
I think you wanted to accomplish something like that:
http://jsfiddle.net/3L8dL228/1/
Just replace the console.log with your own document.write.
Now, despite I totally hate using prompts and I'm not very used to them, here are you what I think you're missing in your script:
CONTROL: your "n" and "g" variables HAS to be an integers, so force the user to insert an integer.
Variables declaration: you're declaring total every single time you loop, therefore you're not storing anything at all.
To fix these, the very first piece of your code becomes this:
var n = prompt("Input a number: ", "Number here");
while (!parseInt(n) )
{
n=prompt("Input a number: ", "Number here");
}
In this way, you're asking the user to give you a NUMBER, but the script won't procede until it will effectively be able to parse an integer value.
Therefore, inputs like "hey", "hello", "foo", "bar", "baz" won't be accepted.
The second part of your code then becomes this one:
var i=1;
var total = 0;
do
{
var g = prompt("Input grade: " );
while (!parseInt(g)) {
g = prompt("Input grade: " );
}
var grade = parseInt(g);
total += grade;
i++;
}
while(i<=n);
var average=(total)/n;
console.log("Average is: " +average);
and console.log needs to be document.write in your case, but for testing purposes and because jsfiddle (of course) doesn't allow document.write you need to check your console to see the correct value.
What changes from your script to this one is that we are declaring total as a global variable, not as a local variable inside the do loop that will be reset each time you loop.
Next, we're using the same logic as the first prompt for the second one, because you want, again, an integer value, not a possible string like "hey".
After that, we're ADDING that value to the total variable, by not redeclaring it.
Finally, after the loop, we're dividing that global variable total by the global variable n, getting the average.
Try below code to get the average of the entered number.
numGrades = prompt("Enter number of grades to be entered: ");
//number of grades to be entered LOOP
for (index = 1; index <= numGrades; index++) {
numberGrades = prompt("Enter Grade " + index);
}
//Calculation
gradePointAverage = numberGrades / numGrades;
document.write("Your GPA is " + gradePointAverage );

Adding an integer to a JavaScript variable

I have a variable declared here:
var quizScore = 0;
And I want to add a number to it each time the correctAnswer() function runs:
function correctAnswer(){
quizScore+1;
console.log ( 'correct answer selected: quizscore = ' + quizScore );
}
I added a console log for debugging. It works, so the function is being called, but it is not adding the score. Do I need to parse this to an integer? I can't work out what the +1 needs to be to work correctly.
You can go here and you will see that clicking "Lightning Bolt" for question 1 shows "correct answer" in the console, but doesn't add to the score variable.
Do it like this:
function correctAnswer(){
console.log ( 'correct answer selected: quizscore = ' + (++quizScore) );
}
You just need to assign the +1 to quizScore variable. This may be the fastest way to add 1 and display it in one line
You're adding one to whatever value is in quizScore, and doing nothing with the result.
You need quizScore = quizScore + 1.
Keep quizscore as global variable.
And secondly change the line no.1 of your correctAnswer() function to
quizScore = quizScore + 1;
You can use self-memorizing function not to pollute global environment with variables like so:
function correctAnswer() {
correctAnswer.quizScore = (correctAnswer.quizScore || 0) + 1;
console.log("QuizScore : " + correctAnswer.quizScore);
}
for (var i = 0; i < 10; i++) {
correctAnswer(); // output 1 2 3 4 5 6 7 8 9 10
}
Right now, when you do this:
quizscore+1;
You add one to it but it doesn't assign the change to the variable. One reason for this is that sometimes you may want to add a number to the variable long enough to perform an operation but you don't want it to change.
// quiz score is left alone
var nextscore = quizscore + 1
Here are the different ways to actually assign it:
// temporarily adds 1 to quizscore, then saves it to quizscore
quizscore = quizscore + 1
// adds one to quizscore after it's used in an expression
quizscore++
// adds one to quizscore before it's used in an expression
++quizscore
So if you did something like this:
var nextscore = ++quizscore + 1;
You would both increment the current score and predict the next score.
Read more: Expressions and Operators

Incrementing a number with JavaScript returns an error

var count = {
digit: 0,
increment: function() {
setInterval(function() {
count.digit++;
}, 500);
if (count == 10) {
count.increment = null;
}
}
};
document.write("The number is " + count.digit);
count.increment();
The result is: "The number is 0" but it does not increment. Why?
"A string" + "another string" == "A new string"
… and a new string is not a live updating version of the combination of the two strings that formed it in the first place.
Even if it was, then document.write takes a string, expresses it as HTML, then adds it to the document — so that wouldn't live update it either.
You would need to use DOM methods to modify the HTML document instead of the string. The WSC has a good introduction to manipulating HTML with DOM: http://dev.opera.com/articles/view/creating-and-modifying-html/
You have another problem in that setting count.interval to null wouldn't stop the function incrementing the counter every half second since:
You aren't overwriting the function that is being called every half second
Replacing a reference to a function with something else, doesn't stop that function from existing unless all references to it are overwritten, and setInterval would maintain the reference.
You need to keep the return value from setInterval and use it to clearInterval.
You need to have your if statement inside the setInterval also count.digit == 0
This is a bit cleaner IMO
var count = {
digit: 0,
increment: function() {
var interval = setInterval(function() {
if (++count.digit == 10)
clearInterval(interval);
document.write("The number is " + count.digit);
}, 500);
}
};
count.increment();

Categories