Can't get counter to work inside function in Javascript - javascript

I am trying to create the proverbial quiz in Javascript as my first 'from scratch' exercise. This is my fiddle, which has all the other code.
This is my question:
var allQuestions = [{
"question": "Who was Luke's gunner in the battle at Hoth?",
"choices": ["Dak", "Biggs", "Wedge", "fx-7"],
"correctAnswer": 0
}];
Here in this function, I included the loop which should go over the radio buttons vs. the users selection. See below.
function answerFwd() {
var answerOutput = " ";
var itemAnswers = allQuestions;
var answer = 0;
var playerTally = 0;
var playerFeedback = "";
var playerMessage = document.getElementById("playerMessage");
Right now I am stuck with this;
Matching the correct answer in the array, with what a user would select in the radio buttons and then dynamically displaying a score.
Right now, I can get the 0 to display, but no increment.
var radioValue = $("input[type='radio'].radioButtons:checked").val();
if (currentAnswer <= itemAnswers.length) {
currentAnswer++;
}
createRadioButtonFromArray(itemAnswers[currentQuestion].choices);
for(i = 0; i < radioValue.length; i++) {
if(radioValue[i].checked) {
if(radioValue[i].value == itemAnswers.correctAnswer) {
playerTally++;
break;
}
}
}
playerFeedback += "<h4>" + playerTally + "</h4> <br/>";
playerMessage.innerHTML = playerFeedback;
}
I am not opposed to a solution with jQuery, but would prefer a vanilla JS alternative, just so I can really see what is going on!
Thank you all in advance!

Before you progress to the next question, you can figure out if an answer is correct with
if (document.querySelectorAll("#responses input")[allQuestions[currentQuestion].correctAnswer].checked)

The complete solution is
fiddle
var radios = document.querySelectorAll("#responses input");
var correct = allQuestions[currentAnswer].correctAnswer;
if (radios[correct].checked) {
playerTally++;
playerFeedback += "<h5>" + playerTally + "</h5> <br/>";
playerMessage.innerHTML = playerFeedback;
}
if (currentAnswer <= itemAnswers.length) {
currentAnswer++;
}
And now I look closely it is the same as Mr. Me's

Related

How to fix [objectHTMLButtonElement] problem in JavaScript

Sorry to bother all of you. I know, this question has been asked multiple times. However, I just couldn't fix my problem.
So, I've been trying to create a tennis scoring system that shows the score when you click one of two buttons, the win button or the lose button. I have a button where they can add their name to the scoring system. When one player wins two sets the match is over. I then try to print their name saying, ____ won the match. When I try using the variable that printed their name before I get something that says: [objectHTMLButtonElement]. I've been trying for a long time to fix this and I don't know how to.
Here is the code:
document.getElementById("youName").onclick = function() {
var youName = prompt("Enter your name");
document.getElementById("youOutput").innerHTML = youName + ":";
}
let points = 0;
function win() {
points += 1;
document.getElementById("points").innerHTML = points;
if (points == 2) {
document.getElementById("finish").innerHTML = youName + " won the match";
}
}
<button id="youName">Your name</button>
<p id="youOutput"></p>
<button onclick="win()">Won the point</button>
<p id="points"></p>
<p id="finish"></p>
Thanks in advance.
Try to declare yourName in a global context
let yourName = null;
document.getElementById("youName").onclick = function () {
yourName = prompt("Enter your name");
document.getElementById("youOutput").textContent = `${yourName}`;
};
let points = 0;
function win() {
points += 1;
document.getElementById("points").innerHTML = points;
if (points == 2) {
document.getElementById(
"finish"
).textContent = `${yourName} won the match`;
}
}

How do I limit the amount of checkbox checked with JavaScript(no jquery please)

I'm making a Node Express multiple choice test, and each question has different amount of correct answers. I have my answers coming from a database auto-populate in PUG. However my Function doesn't work right, when I click over the limit of correct answers, the alert pops up but then the answer is checked anyways. What am I doing wrong?
I tried making a function that tracks how many answers checked, but can't get it to stop after it reaches the limit.
block content
header.header USA Government Test
main.q-card
p.q-promt #{question}
small (Please choose #{mcLimit} answers)
hr
each answer in answers
label.container
| #{answer.Answer_prompt}
input(type='checkbox' name='answer' onclick="ckLimit()")
span.checkmark
hr
script.
function ckLimit() {
var limit = #{mcLimit};
var total = 0;
var inputTag = document.getElementsByTagName('input');
var x = inputTag.length;
for (var i = 0; i < x; i++) {
if (inputTag[i].checked) {
total += 1;
}
if (total > limit) {
alert(`Please select only ${limit}`);
this.checked = false;
return;
}
}
}
everything works accept the: this.checked = false;
It continues to check answers. This what my code looks like now:
header.header USA Government Test
main.q-card
p.q-promt #{question}
small (Please choose #{mcLimit} answers)
hr
each answer in answers
label.container
| #{answer.Answer_prompt}
input(type='checkbox' name='answer' onclick="return ckLimit()")
span.checkmark
hr
script.
function ckLimit() {
var limit = #{mcLimit};
var total = 0;
var inputTag = document.getElementsByTagName('input');
var x = inputTag.length;
for (var i = 0; i < x; i++) {
if (inputTag[i].checked) {
total += 1;
}
if (total > limit) {
alert(`Please select only ${limit}`);
this.checked = false;
return;
}
}
}
Add return keyword to the below statement.
input(type='checkbox' name='answer' onclick="ckLimit()")
thus becoming
input(type='checkbox' name='answer' onclick="return ckLimit()")
Without return, onclick proceeds on allowing the default action of checking. Once onclick gets false value, it stops the action.
Edit:
In function ckLimit, return should return false.
if (total > limit) {
alert(`Please select only ${limit}`);
this.checked = false;
return false;
}

Why is my function to hide image not working properly?

My code was working properly until I decided to make a small change, and I guess I accidentally deleted something because my console is saying hide image is not defined at decrement when I already defined hide image. I can't find my error everything worked fine :'(. I went over my hide image function and it seems like everything is correct. When I load it on html the error seems to appear when a user does not make a selection is runs the function decrement, so when time reaches zero it displays an image with the correct answer, and it used to clear it out and display the next question with the available choices, but now it just stays on the if time = 0 screen and doesn't move on to the next question.
$(document).ready(function () {
//set up object-array for questions
var trivia = [
{
question: "On Drake & Josh, what's Megan favorite phrase?'",
choices: ["Boobz", "Idiots", "Oh, really?", "Damn! Where are my
apples?"],
rightChoice: 0,
image: "assets/images/boobs.gif",
background: "<img src='assets/images/90back.jpg'>"
},
{
question: "What color lipstick does Spongebob use when he kisses
Mr. Krabs fake Millionth dollar?",
choices: ["Magenta", "Stardust", "Coral Blue #Oof", "Blorange"],
rightChoice: 2,
image: "assets/images/spongebob-coral-blue.gif",
background: "<img src='assets/images/90cart.jpg'>"
},
{
question: "What thottie accessory was popular in the 90's, that
is currently popular today?",
choices: ["chokers", "bandaids", "airpods", "tidepods"],
rightChoice: 0,
image: "assets/images/chokers.gif",
background: "<img src='assets/images/90back.jpg'>"
},
{
question: "During sleepovers, Mystery Date allowed girls to date
which sexy actor?",
choices: ["Port", "James Franco", "Paul Rudd", "Chris Evans, Mr.
America"],
rightChoice: 3,
image: "assets/images/chris-evans.gif",
background: "<img src='assets/images/90cart.jpg'>"
},
{
question: "What was the SPICIEST band in the 90's?",
choices: ["Madonna", "Hillary Clinton", "BackStreet Boyz", "The
Spice Girls"],
rightChoice: 3,
image: "assets/images/zig-a-zig-ha.gif",
background: "<img src='assets/images/90back.jpg'>"
}
];
var rightAnswer = 0;
var wrongAnswer = 0;
var unansweredCount = 0;
var time = 15;
var intervalId;
var userSelection = "";
var selected = false;
var running = false;
var totalCount = trivia.length;
var chosenOne;
var triviaRand;
var newArray = [];
var placeHolder = [];
//hide resetBtn until called
$("#resetBtn").hide();
//click startBtn button to start game
$("#startBtn").on("click", function () {
$(this).hide();
displayTrivia();
runTime();
for (var i = 0; i < trivia.length; i++) {
placeHolder.push(trivia[i]);
};
})
//time: run
function runTime() {
if (!running) {
intervalId = setInterval(decrement, 1000);
running = true;
}
}
//time--
function decrement() {
$("#timeLeft").html("<h4>πŸ‘» Madonna, we're running out of time πŸ‘» "
+ time + " πŸ‘€</h4>");
time--;
//stop time if reach 0
if (time === 0) {
unansweredCount++;
stop();
$("#choicesDiv").html("<p>Oh no! You ran out of time πŸ˜‚. The
correct choice is: " + chosenOne.choices[chosenOne.rightChoice] + "
</p>");
hideimage();
}
}
//time stop
function stop() {
running = false;
clearInterval(intervalId);
}
play question and loop though and display possible answers
function displayTrivia() {
//generate random triviaRand in array
triviaRand = Math.floor(Math.random() * trivia.length);
//console.log(triviaRand);
chosenOne = trivia[triviaRand];
console.log(chosenOne);
$("#questionDiv").html("<h2>" + chosenOne.question + "</h2>");
for (var i = 0; i < chosenOne.choices.length; i++) {
var newUserChoice = $("<div>");
newUserChoice.addClass("answerChoices");
newUserChoice.html(chosenOne.choices[i]);
//assign array position to it so can check rightChoice
newUserChoice.attr("userChoices", i);
$("#choicesDiv").append(newUserChoice);
}
//click function to select rightChoice
$(".answerChoices").click(function () {
//parseInt() function parses a string argument and returns an
integer of the specified radix
//locate array based on userChoice
userSelection = parseInt($(this).attr("userChoices"));
console.log(userSelection);
if (userSelection === chosenOne.rightChoice) {
console.log(chosenOne.choices[chosenOne.rightChoice]);
stop();
selected = true;
rightAnswer++;
userSelection = "";
$("#choicesDiv").html("<p>Damn, boi πŸ±β€πŸ‰πŸ‘Œ</p>");
hideimage();
console.log(rightAnswer);
} else {
stop();
selected = true;
wrongAnswer++;
userSelection = "";
$("#choicesDiv").html("<p>πŸ€”That is incorrect! The correct
choice is: " + chosenOne.choices[chosenOne.rightChoice] + "</p>");
hideimage();
console.log(wrongAnswer);
}
})
function hideimage() {
$("#choicesDiv").append("<img src=" + chosenOne.image + ">");
newArray.push(chosenOne);
trivia.splice(triviaRand, 1);
var hideimg = setTimeout(function () {
$("#choicesDiv").empty();
time = 15;
//run the score screen if all questions answered
if ((wrongAnswer + rightAnswer + unansweredCount) ===
totalCount) {
//clearbck();
$("#questionDiv").empty();
$("#questionDiv").html("<h3>🧐 Game Over! Let's see
your score 😱: </h3>");
$("#choicesDiv").append("<h4> πŸ€ͺ Correct: " +
rightAnswer + "</h4>");
$("#choicesDiv").append("<h4> 🀬 Incorrect: " +
wrongAnswer + "</h4>");
$("#choicesDiv").append("<h4> 🀯 Unanswered: " +
unansweredCount + "</h4>");
$("#resetBtn").show();
rightAnswer = 0;
wrongAnswer = 0;
unansweredCount = 0;
} else {
runTime();
displayTrivia();
}
}, 2000);
}
$("#resetBtn").on("click", function () {
$(this).hide();
$("#choicesDiv").empty();
$("#questionDiv").empty();
for (var i = 0; i < placeHolder.length; i++) {
trivia.push(placeHolder[i]);
}
runTime();
displayTrivia();
})
}
})`
Just as a syntax error correction! You should use single or double quotation in src attribute of img tag in hideimage function:
$("#choicesDiv").append("<img src=' " + chosenOne.image + " '>");

Comparing values of 2 dimensional array to single dimensional array

I am creating a trivia game for a class and I am struggling to compare all of the values of a single index of a 2-dimensional array to a single value of a single index of another array. From my limited experience, I am using and if statement to compare these values. I must be missing a step but I am unsure how to solve it. The line of code for which I think the mistake lies is $(".choice").on('click', function() {});
Thank you for any help in advanced.
JS:
window.onload = function() {
$('#start').html('<div class="text-center"><button type="button" class="btn btn-default">Start</button></div>');
};
var questionArray = ["This bands second album went platinum 5 times in the UK and double Platinum in the US.", "This band was formed in Australia and their first album, which had you Walking On A Dream, has sold over 3 million copies."];
var optionArray = [["Radio Head", "Gorillaz", "Coldplay", "Arctic Monkeys"], ["Empire Of The Sun", "M83", "MGMT", "Two Door Cinema Club"]];
var answerArray= ["Gorillaz", "Empire Of The Sun"];
var imageArray= ["http://cdn3.pitchfork.com/artists/1767/m.65d9c64d.jpg", "http://crowningmusic.com/storage/rA7GUFFoBCtT8Jg4L1tv.png", "", "", ""];
var count = 0;
var question = 0;
$("#start").on('click', function() {
$(this).css("display","none");
timer(
30000,
function(timeleft) {
$('#timer').html(timeleft);
},
function() {
// What happens after //
}
);
$("#question").html(questionArray[question]);
for (var j = 0; j < 4; j++) {
$("#options").append('<button class="choice">' + optionArray[question][j] + "</button>" + "<br>");
}
$(".choice").on('click', function() {
console.log('click');
console.log(answerArray[question])
if (optionArray[question] == answerArray[question]) {
console.log("Working");
}
});
// $("#holder").html("<img src=" + questionArray[count] + ">");
});
function nextQuestion() {
count++;
}
// Timer Function //
function timer(time,update,complete) {
var start = new Date().getTime();
var interval = setInterval(function() {
var now = time-(new Date().getTime()-start);
if( now <= 0) {
clearInterval(interval);
complete();
}
else update(Math.floor(now/1000));
},100); // the smaller this number, the more accurate the timer will be
}
When you are comparing the answers to the question with the correct answer, you need to include the index of the user selected choice. Try something like this:
$("#question").html(questionArray[question]);
for (var j = 0; j < 4; j++) {
// Include an ID in the choice button
$("#options").append('<button class="choice" id="choice_' + j + '">' + optionArray[question][j] + "</button>" + "<br>");
}
$(".choice").on('click', function() {
console.log('click');
console.log(answerArray[question]);
// Get the index of the selected answer through the ID attribute
var selectedAnswerIndex = $(this).attr('id').substring("choice_".length);
if (optionArray[question][selectedAnswerIndex] === answerArray[question]) {
console.log("Working");
}
});
Another options that doesn't deal with answer index might look like this:
$(".choice").on('click', function() {
console.log('click');
console.log(answerArray[question])
// Use the text content of the button to check the answer
if ($(this).text() === answerArray[question]) {
console.log("Working");
}
});
Note: This relies on the fact that the button only contains the possible answer value between the tags. If you put anything else inside the button, this solution would not work.

Animate array from user input like typewriter (javascript)

I suppose my question is a bit similar to this one, but I can't really work out how to do my specific need from it. I'm building a very basic text adventure, and I'd like the returned text - after the user has entered a command - to be returned in a typewriter style. Here's a snippet of my commands so far (there'll be a lot more, I don't mind that this will be built in a bit of a tedious way)
<script>
textIn = document.getElementById("input-textbox");
textOut = document.getElementById("output-textbox");
function process(input) {
if (input == "hi") { textOut.innerHTML += "Hello to you too!<br><br>"; }
else if (input == "exit") { textOut.innerHTML += "No."; }
}
function go() {
var input = textIn.value;
textIn.value = "";
var output = process(input);
textOut.value += output + "\n";
}
</script>
and the HTML
<div id="output-textbox">
Returned text goes here.
</div>
<form onSubmit="go();return false;">
<input id="input-textbox" name="command" value="" autofocus="autofocus"/>
</form>
Thank you so much for your help in advance! This solution doesn't need to be beautiful, code wise, nor very nifty. It just has to work, I have no standards at all with this!
Based on William B's answer, here is a more condensed version:
https://jsfiddle.net/sators/4wra3y1p/1/
HTML
<div id="output-typewriter"></div>
Javascript
function typewriterText(text) {
var outEl = document.querySelector('#output-typewriter');
var interval = 50; // ms between characters appearing
outEl.innerHTML = '';
text.split('').forEach(function(char, i){
setTimeout(function () {
outEl.innerHTML += char;
}, i * interval);
});
}
typewriterText('this is an example');
Create a timeout for each character inside a loop, with each timeout being a bit later than the last. See: https://jsfiddle.net/fswam77j/1/
var outputEl = document.querySelector('#output-textbox');
var charInterval = 50; // ms between characters appearing
function showOutput(text) {
outputEl.innerHTML = '';
for(var i = 0; i < text.length; i++) {
showChar(text, i);
}
}
function showChar(text, i) {
setTimeout(function () {
outputEl.innerHTML += text[i];
}, i * charInterval);
}
showOutput('this is an example');
process the input:
function process(input) {
if (input == "hi") {
showOutput("Hello to you too!");
}
else if (input == "exit") {
showOutput("No.");
}
}

Categories