Creating a JS keypad, function undefined? - javascript

I had this keypad working but I'm not sure why now it says that the functions are undefined when you click one of the buttons. It's an odd issue and my brain is mush looking at it and trying different things for an hour. Appreciate any help.
http://jsfiddle.net/S47e9/1/
function number_write(x) {
var text_box = document.getElementById("numbText");
if (x >= 0 && x <= 9) {
if (isNaN(text_box.value)) text_box.value = NULL;
text_box.value = (text_box.value * 10) + x;
}
console.log(x);
}
function number_clear() {
document.getElementById("numbText").value = "";
}

Your functions are loading before the page, causing the handlers to not know about the functions. In the fiddle, on the left hand side, change the 2nd dropdown from OnLoad to no wrap <in head> -- http://jsfiddle.net/S47e9/2/

Related

Image shows if condition is met

I am making a cookie clicker-esque game and i am making an upgrade bar. One icon starts off invisible and once you have 1 cursor it becomes visible. The problem is it isn't.
I have looked thoroughly and still can't find the bug.
This is in JSFiddle.
Here it is-https://jsfiddle.net/wizviper/mq0qwnvr/
Main Code-
document.getElementById("reinforcedFingerShop").addEventListener(cursorAmount >= 1, function() {
if (reinforcedFingerActive = 0) {
$(this).show();
}
});
addEventListener listens to events but you are assigning a condition to it "cursorAmount >= 1".
I guess you probably want to know when (cursorAmount >= 1) and also (reinforcedFingerActive == 0), please provide the related part of your code, so that we will be able to help you better
UPDATE
You are changing cursorAmount inside "cursorShop" function so the best place to check "reinforcedFingerActive == 0" condition is there.
document.getElementById("cursorShop").onclick = function() {
if (cookies >= cursorPrice) {
cookies = cookies - cursorPrice;
cursorPrice = cursorPrice * 1.15;
cps = cps + 0.1;
updateValue();
cursorAmount = cursorAmount + 1;
if (reinforcedFingerActive == 0) {
$(this).show();
}
}
}
I have not tested but it should work.
I think the problem come from :
if (reinforcedFingerActive = 0) {
Maybe did you forgot the second = ?
Read official MDN addEventListener documentation on how to use this function. First argument is type
A string representing the event type to listen for.
in your code your first argument is cursorAmount >= 1

Recursive function to print numbers in JavaScript

I'm trying to make a recursive function to print 1 to 10 in JavaScript, my current code is:
function rec10(x)
{
if (x < 10)
{
$('#text').val(x+1);
x = x+1;
rec10(x);
}
}
The problem is, everytime I activate this function, the text box only shows "10" directly, i want the code to move from 0 to 1, to 2... until 10. Showing each one of them in the text box.
I tried to use setInterval and setTimeout but I didn't figure it out how to work with that. Thank you very much
instead of:
rec10(x);
call
setTimeout(function() { rec10(x); }, 1000);
With setInterval you can using code below:
function rec10(x) {
var interval = setInterval(function() {
if (x >= 10) clearInterval(interval);
$('#text').val(x++);
}, 1000);
}
JavaScript is single threaded, which means while your code runs, the changes you make to the DOM won't be seen on the browser until your code finish.
You need to give control to the browser for couple of seconds, it can be done with setTimeout:
function rec10(x){
if (x < 10){
$('#text').val(++x);
setTimeout(function(){
rec10(x);
},20);
}
}
Did you resort to setInterval/setTimeout only because you can't make a working recursive function?
If that's the case, how about this recursive function below without using setInterval/setTimeout:
function rec10(x) {
if (x <= 10) {
if (x <= 0) x = 1;
//append?
$('#text').val(x);
rec10(x + 1);
}
}
rec10(1);
But the problem with the code above is it will happen so fast you won't notice the printing of numbers 1 up to 9.
If you want to see the those numbers then I suggest you just append the value to your placeholder $('#text').
But if you really wanna see the numbers being printed and then being replaced by the next number, then you can refer to the answers posted by other users which uses setInterval/setTimeout.

Simple arithmetic challenge function with limited attempts

Recently began studying Javascript, trying to read out of Javascript: The Definitive Guide and Eloquent Javascript, while going off on my own to experiment with things in order to really etch them in my memory. I thought a good way to get my head around arithmetic operations and conditional statements, I'd build a series of little games based around each Math operator, and began with addition.
function beginAdditionChallenge() {
var x = Math.ceiling(Math.random()*100);
alert(x);
for (var i = 0; i < 3; i++) {
var a = Number(prompt("Provide the first addend.", ""));
var b = Number(prompt("Provide the second addend.", ""));
if (a + b === x) {
alert("Well done!");
break;
}
else if (a + b !== x && i < 3) {
alert("Please try again.");
}
else {
alert("Fail.");
}
}
}
function initChallenge() {
var button = document.getElementById("challengeButton");
button.addEventListener("click", beginAdditionChallenge);
}
window.addEventListener("load", initChallenge);
You can see the whole thing thus far on JSFiddle, here. The idea is that clicking the button generates a random number between 1 and 100, displays it to the user, then prompts them to provide two addends, giving them 3 attempts. If the sum of these addends is equal to the RNG number, it congratulates the user and ends the program. If they do not provide suitable addends, the loop prompts them to try again, until they've hit 3 attempts, at which point the program snarks at them and ends.
I know the event listener is not the failure point here, as when I change beginAdditionChallenge to simply display a test alert, it works, but I don't know what exactly is wrong with the loop I've created.
You did it correctly. However, Math.ceiling isn't a function and should be Math.ceil. In addition, your code (in jsfiddle) should be set to wrap in head. Why? Because right now you call initChallenge when the page loads. However, in your jsfiddle example, the code runs onLoad so the load event never gets called. Essentially, you're adding a load event after the page has loaded.
http://jsfiddle.net/rNn32/
Edit: In addition, you have a for loop that goes up to three. Therefore
else if (a + b !== x && i < 3) {
alert("Please try again.");
}
should be
else if (a + b !== x && i < 2) {
alert("Please try again.");
}
because when i === 2, the user's last chance has ended.
Everything is fine. Just change:-
var x = Math.ceiling(Math.random()*100);
to:-
var x = Math.ceil(Math.random()*100);

Why does this JQuery only work if I console.log a bad variable? [duplicate]

This question already has answers here:
Why does this append only work if I console log a bad variable
(2 answers)
Closed 9 years ago.
I am relatively new with jquery, and am trying to change an up and down arrow on a js accordion on each click, unfortunately, I have run into an error where it only works if I console.log a bad variable. Does anyone have any guidance as to what I might be doing wrong when I onclick="embiggen(1)" for example if its accordion id one?
There are some other issues surrounding the html, but specifically why is this only working if I console.log;?
function arrowup(id){
$('#downarrow'+id).remove();
$('#dropdown'+id).append('</a>');
$('#dropdown'+id).append('<i id="uparrow'+ id +'" class="icon-1 icon-chevron-up">');
}
function arrowdown(id){
$('#uparrow'+id).remove();
$('#dropdown'+id).append('</a>');
$('#dropdown'+id).append('<i id="downarrow'+ id +'" class="icon-1 icon-chevron-down">');
}
//Switches the arrows
function embiggen(id){
var up = $('#uparrow'+id).length;
if (up == 1){
arrowdown(id);
console.log(i see you);
}
var down = $('#downarrow'+id).length;
if (down == 1){
arrowup(id);
}
}
The bad console.log() makes it "work" because the error breaks the script execution before entering the second if statement.
Fixing the real issue
down == 1 is always true. You should use an else statement:
if ($('#uparrow'+id).length){
arrowdown(id);
} else if ($('#downarrow'+id).length){
arrowup(id);
}
Understanding it
down == 1 is always true independently of up == 1. Here's your logic explained in pseudo-code in both scenarios:
var up = 1, down = 0;
if (up) { down = 1; up = 0; } //enters this block, down now is 1
if (down) { down = 0; up = 1; } //enters this block as down == 1
var up = 0, down = 1;
if (up) { down = 1; up = 0; } //doesn't enter this block
if (down) { down = 0; up = 1; } //enters this block as down == 1
You just have put an else in there so the execution flow does not enter the second if statement in case the first one succeeds.
if (up) {}
else if (down) {}
Truthy/Falsy values
To explain why I'm using .length isolated inside the conditional statement: in JavaScript, the number 0 is a falsy value and 1 is truthy, hence these can be used directly inside the if statement and it will be interpreted based on the internal ToBoolean algorithm logic. Obviously you can == 1 if you feel like, that's more clear though slightly redundant.
A possibly simpler way around
Going a little off-topic, but your goal can most likely be achieved in an easier way. I may be oversimplifying your logic, but depending on your intents you may just toggle between those two classes:
function embiggen(id) {
$('#arrow'+id).toggleClass('icon-chevron-up icon-chevron-down');
}
Then, you'd no longer have to create a new #downarrow/#uparrow element each time the function is called. If said arrow has JS behavior attached, you can check which logic to execute through an if statement using hasClass().
It works because when an error occurs, JavaScript skips the rest of your function body.
The problem in your case is that the function arrowdown() creates #downarrow+id, making the next condition truthy and calling the function arrowup().
You either need an alternative branch, using Fabricio's answer, or return immediately after making changes to the DOM that would otherwise change the state:
function embiggen(id) {
if ($('#uparrow'+id).length) {
return arrowdown(id);
}
if ($('#downarrow'+id).length) {
return arrowup(id);
}
// ehm, something else happened?
}

Javascript alert box shows up before executing previous statement

I am having a strange issue, but it is not surprising as I am a bit of a JavaScript newbie. Basically I am creating a simple high-low card game. (Draw two cards, highest card wins). Anyways, the code is below.
The basic flow of the program is pretty simple. I choose 2 random numbers (1-52). These numbers are mapped to a corresponding card. (i.e. number 1 is the ace of spades, number 37 is the jack of clubs, etc.). Anyways, after drawing the cards, the program is to display the corresponding card and determine the winner. At the end of all of this, i have an alert that comes up and and tells the winner of the draw and asks if the user wants to play again.
The problem I am having is this: Even though the program should have already displayed the image of the card and output the results to a text area, the alert box shows up before any of that actually occurs and never displays the cards or the results. Any ideas? I am posting all of the code so far and any help would be appreciated. Thanks in advance.
function drawCards() {
var oppCard = randNumber();
var customerCard = randNumber();
while (oppCard == customerCard) {
customerCard = randNumber();
}
var oppCardName = displayCard(oppCard, "oppImage");
var customerCardName = displayCard(customerCard, "custImage");
var result2 = "Your card was: " + customerCardName;
var result1 = "The opponent's card was: " + oppCardName;
var result3 = determineWinner(oppCard, customerCard);
var result4 = result3 + '\n' + result1 + '\n' + result2;
$("#textareaRes").text(result4);
playAgain(result3);
}
function determineWinner(oppsCard, customersCard) {
var oppValue = oppsCard % 13;
var customerValue = oppsCard % 13;
var winnerString = "";
if (oppValue == 0) {
oppValue = 13;
}
if (customerValue == 0) {
customerValue = 13;
}
if (oppValue == customerValue) {
winnerString = "You Tied.";
}
else if (oppValue > customerValue) {
winnerString = "You Lose.";
}
else if (oppValue < customerValue) {
winnerString = "You Win!!";
}
return winnerString;
}
function randNumber() {
var min = 1;
var max = 52;
var random = Math.floor(Math.random() * (max - min + 1)) + min;
return random;
}
function playAgain(resultString) {
if (resultString == "You Lose." || resultString == "You Win!!") {
alert(resultString);
var conf = confirm("Play Again?");
if (conf == true) {
$("#textareaRes").text("");
document.getElementById("custImage").src="./cardImages/default.png";
document.getElementById("oppImage").src="./cardImages/default.png";
}
else {
window.location = "#mainMenuPage";
}
}
else {
alert(resultString);
alert("Try Again.");
$("#textareaRes").text("");
document.getElementById("custImage").src="./cardImages/default.png";
document.getElementById("oppImage").src="./cardImages/default.png";
}
}
So I did not place the code in here for the display card function, just because for testing it is exceptionally long. It is just a giant switch case for all 52 random numbers. The finished product will actually be pulling from an XML file, but I used this just for testing purposes. (If, for some reason, you need to see the display cards function, let me know and I can post it.) Anyway, to recap, the last call made in the drawCards() function is the playAgain function. Upon running this code the results nor the card images are displayed. It just jumps straight to the alert that is called for by the playAgain function. This is probably a pretty noobish question, but I am a little perplexed by it. So any help you guys can offer would be GREATLY appreciated. Thanks.
EDIT: It actually performs correctly in a computer's browser. However, the problem happens on a mobile device like a phone or tablet. So this is probably something that I am doing incorrectly here. Any help is greatly appreciated.
Changes in the browser doesn't show up as long as your Javascript code is running.
The browser is event driven, so changing an element in the DOM doesn't show the change immediately, instead an event is triggered to redraw the element. When your function has finished running, the browser will handle any pending events and show the changes.
So, when building an application, you have to use the same approach so that the browser has a chance to show the changes.
For anyone who finds this looking for the solution to the problem, the solution can be found in this answer: https://stackoverflow.com/a/13338585/870729
Here is a working fiddle of a simple example:
jQuery(function($) {
$.when($('#empty-me').html('')).done(function() {
alert('I did it!');
});
});
"./cardImages/default.png"
im not sure ... but try "../cardImages/default.png" ... i always use 2 dots for come to a higher level

Categories

Resources