So I had this working last night, its a 10 questions quiz. I did a few revisions today, and now when I click to check the answer, I've lost the functionality that would display in the jumbotron if the answer was correct or not. The continue to next question still deletes and repopulates the list. Just the button to check the question answer is broken. Here's the jsFiddle link:
https://goo.gl/1cfgBO
The issue has to do with your i value not being valid in the listener callback block. You can resolve this by using your currentQuestion value instead, like so:
$('#submit').on('click', function() {
var answer = $('input[name="1"]:checked').val();
if (answer == questionsArray[currentQuestion]['answer']) {
correctAnswers++;
$('.jumbotron').html(answer + "?<br><br> That's correct! You have " + correctAnswers + " out of 10 correct!");
} else {
$('.jumbotron').html(answer + "? <br><br> Oh dear, that's so so wrong! You have " + correctAnswers + " out of 10 correct");
}
return false;
});
Related
I am a noob here in JS and I am doing my homework making a simple color guessing game. So far everything works as far as the criteria goes.
My only problem is that I can't figure out how to make it so that the background changes instantly upon user input (Right after clicking [OK] at the Prompt). As of now with the code below, the background changes only after clicking [OK] in the Congrats alert..I am pretty sure it's possible because my prof showed in the lecture an example he did where the background color changed right after guessing the correct color!
Also, it would be nice if any pros out there could give me suggestions on polishing my code. I have a feeling that it is messy and too complex than what its trying to achieve..Heh..
PS: I know that js logic should be separated in the page but my prof insisted we do this exercise with the script inline!
Thank you!
<body onload="doGame()">
<script>
var myBody = document.getElementsByTagName("body")[0];
var target;
var answer;
var guessInputText;
var guessInput;
var finished = false;
var guessAmount = 0;
var colors = ['Salmon', 'Tomato', 'Moccasin', 'Peru', 'Olive', 'Teal', 'Navy', 'Thistle', 'Beige', 'Gray'];
var colorsSorted = colors.sort();
var colorsSortedString = colors.join(', ');
function doGame() {
var randomColorNum = Math.random() * 10;
var randomColorNumInt = Math.floor(randomColorNum);
target = colors[randomColorNumInt + 1];
answer = target.charAt(0).toLowerCase() + target.slice(1).toLowerCase(); //makes sure answer is in lowercase
alert("The answer is " + target + " or " + answer); //for debugging
while(!finished) {
guessInputText = prompt('I am thinking of one of these colors:\n\n' +
colorsSortedString + '\n\n' +
'What color am I thinking of?');
guessInput = guessInputText.charAt(0).toLowerCase() + guessInputText.slice(1).toLowerCase(); //converts whatever input into lowercase
guessAmount += 1;
finished = checkGuess(); //checks to see if user input is correct
}
}
function checkGuess() {
if ((colors.indexOf(guessInputText.charAt(0).toUpperCase() + guessInputText.slice(1).toLowerCase()) > -1) == false) {
alert("Sorry, I don't recognize your color.\n\n" +
"Please try again!");
return false;
}
if (guessInput > answer) {
alert("Sorry, Your guess is incorrect!\n\n" +
"Hint: Your color is alphabetically higher than mine.\n\n" +
"Please try again!");
return false;
}
if (guessInput < answer) {
alert("Sorry, Your guess is incorrect!\n\n" +
"Hint: Your color is alphabetically lower than mine.\n\n" +
"Please try again!");
return false;
}
myBody.style.background = answer;
alert("Congratulations! You have guessed the color!\n\n" +
"It took you " + guessAmount + " guesses to finish the game!\n\n" +
"You can see the color in the background.");
return true;
}
</script>
</body>
If you want to modify the background before the [OK] on congrats prints, you just have to move this line
myBody.style.background = answer;
But.. Testing your snippet, the background change right after I press OK on the guess color prompt.
So what do you want exactly ? Can you give us an example step by step ?
I'm trying to make clicking the battle button print "You have slain" + selected option + What I have now works for the first option, but if you select a different option in the dropdown and click battle it still says Fly.
Fiddle
var mon = document.getElementById('monsters');
var monster =mon.options[mon.selectedIndex].text;
$('#battle').click(function() {
document.getElementById('dam').innerHTML = "You have hit the " + monster + " for 5 damage";
});
In your solution, you have declared the values of the selected value globally which is set only once during the document load. In order to calculate the right value, you have to declare them locally during the button click.
$('#battle').click(function() {
var mon = document.getElementById('monsters');
var monster =mon.options[mon.selectedIndex].text;
document.getElementById('dam').innerHTML = "You have hit the " + monster + " for 5 damage";
});
Working example : https://jsfiddle.net/DinoMyte/4dyph8jh/5/
Updated fiddle
Because you're using jQuery it could be simply :
$('#battle').click(function() {
$('#dam').text("You have hit the " + $('#monsters option:selected').text() + " for 5 damage");
});
Hope this helps.
I have just begun to learn how to use jQuery I need to validate an input field and test the range of numbers entered. I have written what I believe would be the correct way to do it but it doesn't work, in fact if you do enter a number between the range nothing occurs in the game. I would also like to have the input box turn "red" if the number entered isn't in the range, as well as put the output message I have included in my code if it doesn't fit.
This is my code:
<head>
<script src="http://code.jquery.com/jquery-1.10.2.min.js">
</script>
<link rel="stylesheet" type="text/css" href="dice.css">
<title>Dice Game</title>
</head>
<body>
<script type="text/javascript">
$(document).ready(function () {
$('#guess').focus();
$('#roll').click(function () {});
$("#guess").validate({
rules: {
guess: {
required: true,
range: [2, 12]
}
}, //end of rules
message: {
guess: {
required: "Please enter a number.",
range: "You must enter a number between 2 and 12."
}
}
}); //end of validate()
var count = 3;
function startover() {
count = 3;
alert("Make a guess and click the Roll button.");
}
function roll(guess) {
if (count == 0) {
alert("Click the Play Again button.");
return;
}
var die1 = Math.floor(1 + 6 * Math.random());
var die2 = Math.floor(1 + 6 * Math.random());
var sum = die1 + die2;
if (guess == sum) {
alert("You rolled a " + die1 + " and a " + die2 +
" which adds up to " + sum + ". Your guess is " +
guess + ". Congratulations, you win!");
count = 0;
} else {
--count;
if (count == 0) {
alert("You rolled a " + die1 + " and a " + die2 +
" which adds up to " + sum + ". Your guess is " +
guess + ". You have no rolls left. " +
"Sorry... the computer won.");
} else {
alert("You rolled a " + die1 + " and a " + die2 +
" which adds up to " + sum + ". Your guess is " +
guess + ". You have " + count + " rolls left. " +
"Click Roll to try again.");
}
}
}
}); // end ready </script>
<form id="game">
<h1>Welcome to the dice game!</h1>
<p>Here's how it works! If you roll two dice and add up the values, you will get a minimum of 2 and a maximum of 12.</p>
<p>Enter a number between 2 and 12:
<input type="text" name="guess" id="guess" min="2" max="12" />
<br>The computer will roll the dice for you up to three times. If the dice match your guess, you win!</p>
<input type="button" value="Roll" onclick="roll(guess.value);" />
<input type="button" value="Play Again" onclick="startover();" />
</p>
</form>
</body>
</html>
There are these problems with your code:
javascript functions for button event handler should NOT be placed inside $(document).ready();
jQuery validate plugin should be run on your form element ($("#game").validate), NOT on your input text element ($("#guess").validate).
In order for invalid input to be highlighted, you need to add 'error' and 'valid' css styles.
In order to stop the game from proceeding, you can disable submit buttons when form validation fails, using:
onkeyup: function (element, event ) {
if(!$("#game").valid()) {
$(":button").attr("disabled", "disabled");
} else {
$(":button").removeAttr("disabled", "disabled");
}
}
Please see Plunker with working code.
Note: I haven't looked at your game logic, and haven't modified it, I have fixed the validation part.
validate is not a method in the jQuery core API and you are not linking to any other jQuery plugins. Looks like you are missing a SCRIPT tag for your validation plugin
You can do this with JavaScript. There's no need to specifically use jQuery for this.
With JavaScript, all you need to do is handle the 'roll' button click event:
var btnButton = document.getElementById('roll');
btnButton.addEventListener("click", function () {
var txtValue = document.getElementById('guess').value;
if (txtValue.length > 0) {
if (!isNaN(+txtValue)) {
if (txtValue > 2 && txtValue < 12) {
document.getElementById('spanValidationMsg').className = "hide";
//WRITE YOUR CUSTOM CODE HERE
//WRITE YOUR CUSTOM CODE HERE
}
else {
document.getElementById('spanValidationMsg').innerHTML = "You must enter a number between 2 and 12.";
}
}
}
else
{
document.getElementById('spanValidationMsg').innerHTML = "Please enter a number";
document.getElementById('spanValidationMsg').className = "show";
}
});
See this here: http://jsfiddle.net/jL26k/2/
EDIT: There was a small error. Check the link now.
The problem is your selector is wrong, you should be selecting the form element not the guess element.
e.g. it should be $('#game').validate({ ...
To get the form inputs to change color read the documentation here: http://jqueryvalidation.org/validate#errorclass
I need the values of the name, address, size, and topping fields to appear in a text box. Without problems the name and address appears correctly. However I can't seen to get the size function to work. It is a radio button, and thus I need only one size to appear. I haven't even tried an if else for the checkbox yet. Here is my code
<html>
<head>
<script>
function pizza() {
document.pizzaboy.comments.value = "Name:" + " " + pizzaboy.name.value + "\n" + "Address:" + " " + pizzaboy.address.value + "\n" + document.getElementById("small").value + document.getElementById("medium").value + document.getElementById("large").value + "\n" + pizzaboy.toppings.value;
{
var rslt = "";
if (document.pizzaboy.size[0].checked) {
rslt = rslt + "Size=Small\n";
} else if (document.pizzaboy.size[1].checked) {
rslt = rslt + "Size=Medium\n";
} else rslt = rslt + "Size=Large\n";
return rslt;
}
}
</head>
The second Javascript bracket might be throwing you an error, keeping your code from running correctly.
In this post, several (more general) ways to get values of radio buttons are explained:
Checking Value of Radio Button Group via JavaScript?
The first answer is using jQuery, but the following answers will help you i think.
You should try this. Answer here if you need further assistance.
I've been trying to figure this out for a while, and I'm totally stumped.
I'm writing a program that is supposed to display a basic series of multiple-choice questions. You see a question, you click one of the answers, and you move on to the next question.
The problem is, I can't figure out how to display one question, then display the next question when the user clicks one of the buttons. Nothing happens when I click a button. What's going wrong?
// progress meter
var progress = new Array();
for (var i = 0; i < questions.length; i++) progress.push("0");
var i = 0;
display(0);
// display questions
function display(i) {
var prg_string;
for (var j = 0; j < progress.length; j++) prg_string += progress[j];
document.write(
"<div id = 'background'>"
+ "<div id = 'progress'>" + progress + "</div>"
+ "<div id = 'title'>-JogNog Test v1-<br></br>" + tower + "</div>"
+ "<div id = 'question'>" + questions[i].text + "</div>"
+ "<div id = 'stats'>Level " + level + "/" + total_levels + " Question " + (i + 1) + "/" + questions.length + "</div>"
+ "</div>"
);
document.write("<button id = 'answer1' onclick = 'next(questions[i].answers[0].correct)'>" + questions[i].answers[0].text + "</button>");
if (questions[i].answers.length > 0)
document.write("<button id = 'answer2' onclick = 'next(questions[i].answers[1].correct)'>" + questions[i].answers[1].text + "</button>");
if (questions[i].answers.length > 1)
document.write("<button id = 'answer3' onclick = 'next(questions[i].answers[2].correct)'>" + questions[i].answers[2].text + "</button>");
if (questions[i].answers.length > 2)
document.write("<button id = 'answer4' onclick = 'next(questions[i].answers[3].correct)'>" + questions[i].answers[3].text + "</button>");
}
// go to next question, marking whether answer was right or wrong
function next(correct) {
if(correct) progress[i] = "T";
else progress[i] = "F";
i += 1;
display(i);
}
I haven't read through your code, (you might want to work on posting SSCCEs by focusing just on the part that handles the loop) but I get the feeling a loop is not what you want here. Loops are great if you need to automatically iterate through something. But really, you want to display only a single question at a time.
The easiest way to do this, assuming you have a means of handling each question independently, is just to keep track of which question the user is up to. Display that question. When the user submits an answer, call whatever function renders a question using the counter, plus one. Make sure to check that you haven't hit the end of the quiz so that you don't reference a question that doesn't exist.
Here's some pseudocode:
var questionNumber, questions; //assume these already have values
function printQuestion(questionNumber){ ... }
function nextQuestion(){
if(questionNumber < questions){
questionNumber++;
printQuestion(questionNumber);
}
else{
showResults();
}
}
I agree with #ngmiceli that a loop isn't what you want here. You want to display one question, and then create click event handlers that will move on to the next question when the user selects an answer to the previous question.
I went ahead and created a different setup to demonstrate. You can see a demo here:
-- jsFiddle DEMO --
But I'll walk through the process. First, I set up a basic HTML document:
<body>
<h1>-Test v1-</h1>
<h2>Simple Math</h2>
<div id="container">
<div><span id="numRight">0</span> of <span id="numQuestions">0</span></div>
<div id="question"></div>
<div id="answers"></div>
</div>
</body>
Then, I created a questions array, each element in the array being an object. Each question object contains the question itself, an array of possible answers, and an "answerIdx" property that indicates the array index of the correct answer.
questions = [
{
question: 'What is 0 / 6 ?',
options: ['0','1','2'],
answerIdx: 0
},
{
question: 'What is 2 + 2 ?',
options: ['72','4','3.5'],
answerIdx: 1
}
]
I also created some other variables that point to the HTML elements I am going to want to manipulate:
numRight = 0,
numQuestions = 0,
answerDiv = document.getElementById('answers'),
questionDiv = document.getElementById('question'),
numRightSpan = document.getElementById('numRight'),
numQuestionsSpan = document.getElementById('numQuestions');
Next, I created a 'displayQuestion' function which takes a single question object as a parameter:
function displayQuestion(q) {
// insert the question text into the appropriate HTML element
questionDiv.innerHTML = q.question;
// remove any pre-existing answer buttons
answerDiv.innerHTML = '';
// for each option in the 'options' array, create a button
// attach an 'onclick' event handler that will update
// the question counts and display the next question in the array
for(i = 0; i < q.options.length; i++) {
btn = document.createElement('button');
btn.innerHTML = q.options[i];
btn.setAttribute('id',i);
// event handler for each answer button
btn.onclick = function() {
var id = parseInt(this.getAttribute('id'),10);
numQuestionsSpan.innerHTML = ++numQuestions;
// if this is the right answer, increment numRight
if(id === q.answerIdx) {
numRightSpan.innerHTML = ++numRight;
}
// if there is another question to be asked, run the function again
// otherwise, complete the test however you see fit
if(questions.length) {
displayQuestion(questions.shift());
} else {
alert('Done! You got '+numRight+' of '+numQuestions+' right!');
}
}
answerDiv.appendChild(btn);
}
}
Finally, I displayed the first question:
displayQuestion(questions.shift());