JavaScript Quiz Validating with onClick Function? - javascript

I am trying to create a JavaScript Quiz.
The function will check the user's input value.
If it is correct; it will change the question.
Exact Code See JSFiddle
There are probably many more efficient and conventional ways to achieve what I am trying to do. Current issue is the function runs from the top every time it runs(obviously)
function checkAnswer() {
var question = document.getElementById("ques").innerHTML;
var userAnswer = document.getElementById("answer").value;
if (userAnswer === "New York City") {
alert("correct!");
question = "What is the best college football team?";
if (userAnswer === "Alabama") {
alert("Correct!");
question = "Next question will go here and so on..."
}
}
}

In no way would I suggest doing things this way, but here's how to get your jsfiddle to work:
function check() {
var question = document.getElementById('question').innerHTML
var userAnswer = document.getElementById("answer").value;
//Makes answer lowercase
userAnswer = userAnswer.toLowerCase();
//question one
if (question === "Write One, Two, Three..") {
if (userAnswer === "one two three") {
alert('correct');
}
else {
alert('Sorry Wrong!');
}
//question two
document.getElementById('question').innerHTML = "Write 4, 5, 6";
}
else {
if (userAnswer === "4 5 6") {
alert("correct!");
}
else {
alert('Sorry Wrong!');
}
}
}
One simple way to do what you want is to put your questions in an array:
var QandA = [
["question1...", "answer1...."],
["question2...", "answer2...."],
["question3...", "answer3...."],
["question4...", "answer4...."]
];
function check()
{
// No more questions?
if (0 === QandA.length) return;
// Check answer
var userAnswer = document.getElementById("answer").value.toLowerCase();
if (userAnswer === QandA[0][1]) {
alert("Correct");
}
else {
alert("Incorrect");
}
// Delete that question
QandA.shift();
// And move to next
if (0 != QandA.length) {
document.getElementById('question').innerHTML = QandA[0][0];
}
}

If you have a number of questions that you need validating I would take the following approach. It allows you as many questions as you like without repeating code.
First, store your questions in an array:
var arr = ["one two three", "4 5 6"];
Set a counter to zero, and a total (to measure the user performance):
var count = 0;
var total = 0;
Cache the elements:
var questionEl = document.getElementById('question');
var userAnswerEl = document.getElementById("answer");
Separate out the code that writes the question into a new function. It writes the question based on the counter:
function writeQuestion() {
if (count < arr.length) {
questionEl.innerHTML = "Write " + arr[count];
} else {
alert('No more questions. You have scored ' + total);
}
}
function check() {
userAnswer = userAnswerEl.value.toLowerCase();
if (userAnswer === arr[count]) {
alert('correct');
count++;
total++;
writeQuestion();
} else {
alert('Sorry Wrong!');
count++;
writeQuestion();
}
}
DEMO

if (userAnswer === "New York City") {
alert("correct!");
question = "What is the best college football team?";
if (userAnswer === "Alabama") {
alert("Correct!");
question = "Next question will go here and so on..."
}
}
This block only runs if userAnswer is "New York City", but inside it, you test whether userAnswer is "Alabama" - that will never be true. You probably want to move the second if outside of the first if block.
You seem to be assigning to question but not using the value. If you think you are updating the question text by assigning a value to question that isn't going to work. I think you are trying to do this:
question = document.getElementById("ques");
// later on...
question.innerHTML = "this is another question";
// even later...
question.innerHTML = "and here is a new question";
That would update the page for you because question would point to a DOM node and you can set .innerHTML on that, but the way you wrote it, you're setting question to a string value initially, and then other string values later, but not using any of them in anyway.

Related

Check incoming answer with answer in array object

I created a function to check my answer. However, When I click on the correct answer, the display message say it is the wrong answer. I have been at this for hours. Can someone please tell me where I'm going wrong?
function to check answer:
function checkAnswer(answer) {
let correctAnswer = questionArray[currentQuestion].answer;
if (answer !== correctAnswer) {
notCorrect();
} else {
isCorrect();
}
count = 0;
if (currentQuestion < lastQuestion) {
currentQuestion++;
showQuestion();
} else {
clearInterval(startTime);
quizScore();
}
}
function to call based on answer:
function isCorrect() {
score++;
displayMessage.textContent = 'Correct';
document.querySelector('.btn-option').style.backgroundColor = 'green';
}
function notCorrect() {
displayMessage.textContent = 'Wrong';
document.querySelector('.btn-option').style.backgroundColor = 'red';
}
The error may occur in
function checkAnswer(answer) {
let correctAnswer = questionArray[currentQuestion].answer;
if (answer !== correctAnswer) {
notCorrect();
And may be caused by a discrepancy in questionArray between what questionArray[currentQuestion] is and what you want it to be.
This is just a supposition, since we can't see the contents of questionArray. However,
suppose:
questionArray contains {"what's the airspeed velocity of an unladen swallow?", "what is the capital of Assyria?", "what is your favorite color?"}
and the answers are {"blue", "African or European?", "Ashur", "yellow"} .
It appears you must be incrementing currentQuestion, most likely in a for loop- correct? If so, the value may be off or the arrays may be misaligned.
suppose:
currentQuestion is 0, so "what's the airspeed velocity of an unladen swallow?" is displayed. You answer, "African or European?", but questionArray[currentQuestion].answer may retrieve the answer "blue", blue being the first answer ([0]) in the hypothetical array of answers.
I agree with Cole Henrich. My own test below shows that the code is working properly when answer !== correctAnswer is false (when the answer is correct).
var questionArray=[{'answer':'one'},{'answer':'two'}];
var currentQuestion=0;
function checkAnswer(answer) {
let correctAnswer = questionArray[currentQuestion].answer;
if (answer !== correctAnswer) {
console.log('notCorrect();');
} else {
console.log('isCorrect();');
}
}
checkAnswer('one');

Javascript for survey

Background
I'm working on a survey in javascript which contains ten "yes" or "no" questions. I'd like to code the "yes" responses to = 1 and the "no" responses to = 0. I'm using the html tag so they can only choose one or the other.
Then I'd like to have the sum of their responses added up and divided by the total number of questions to yield a percentage. Depending on their percentage, I would then like to output some HTML text to a field below it with some helpful tips and advice relevant to their score.
To be clear, though I'm learning javascript now, I don't expect anyone to code the thing for me, but I'd just like to know where I should be looking for answers to make this happen. I'm thinking I need to use the if/else conditions to account for the yes/no responses and then maybe I need another function() to do the rest of the calculations.
I've tried a number of different variations of if/else statements but I'm just confused about how to 1) code the yes/no responses; 2) integrate them into if/else statements.
I'll add an abbreviated snippet of code with two sample questions that I'm trying to get working now.
function calc (form) {
var score1;
var score2;
var Result = form.Result.value;
if (form.Question1.options[form.Question1.selectedIndex].value = "Yes") { score1 = 1;
} else {
score1 = 0;
}
if (form.Question2.options[form.Question2.selectedIndex].value = "Yes") { score2 = 1;
} else {
score2 = 0;
}
Result = (((score1 + score2) / 10) * 100);
if (Result == 80) {
document.getElementById("recommendation").innerHTML = "<h4>Heading here</h4> <p>Advice goes here based on their result</p>"
}
}
To be fair, I believe you need to rethink your approach. Having an if-then-else approach for each question & answer can be quite tedious in maintaining or when you want to change the answers.
If you would create a data structure for your questions, you could use for-loops or saving indexes of the current question to handle an answer. The correct answer would then also be part of your data structure (but that is up to you, it could be a client/server request as well).
You already got some answers why your current approach doesn't work due to missing up assignment with equality operators, but I thought I would give you an alternative solution.
This solution will create a dynamic ui, and handle answers on questions when the next button is clicked. The questionaire here is unidirectional, you can only go forward :)
It is mainly to give you an idea how to approach it differently. I don't imagine you actually using this code as is.
The code has quite some inline comments, and is based on the usage of a generator function (which are not supported by Internet Explorer, but should be fine in any other browser)
Upon completion, the score would be displayed in a message box.
// data structure that takes question / answer / which is correct and the points attributed
const questions = [
{
question: 'What platform are you on?',
answers: ['Stackoverflow', 'codereview'],
correct: 0,
points: 5
},
{
question: 'What is the answer to everything',
answers: [42, 'I don\'t have a clue'],
correct: 0,
points: 1
},
{
question: 'How much is 7*6',
answers: ['I am not good with maths', 42],
correct: 1,
points: 10
}
];
// a simple generator that is used in the questionaire
function *questionsGenerator( questions ) {
yield* questions;
}
// creates a questionaire, with forward only options (due to the use of the generator function)
// all variables are locally scoped, when all questions were answered, the onCompleted callback would be called
// it returns an object with nextQuestion function though it could call nextButton internally, and you just have to call the function once if you would want to change it
const questionaire = ( query, nextButton, target, onCompleted ) => {
let score = 0;
let iterator = questionsGenerator( query );
let question = null;
let selectedAnswer = -1;
nextButton.addEventListener('click', nextQuestion);
function evaluateAnswer() {
if (!question) {
// no question yet
return;
}
if (selectedAnswer < 0) {
return;
}
if (question.correct === selectedAnswer) {
score += question.points;
}
return;
}
function nextQuestion() {
evaluateAnswer();
question = iterator.next();
// this is a bit of a hack to check if we just had the last question or not
if (question.done) {
nextButton.removeEventListener('click', nextQuestion);
onCompleted( score );
return;
}
question = question.value;
drawUI();
}
function drawUI() {
// disable next button
nextButton.setAttribute('disabled', true);
selectedAnswer = -1;
// remove existing items
Array.from( target.childNodes ).forEach( child => target.removeChild( child ) );
// create new questions (if available)
const title = document.createElement('h1');
title.innerHTML = question.question;
target.appendChild( title );
question.answers.map( (answer, i) => {
const el = document.createElement('input');
el.type = 'radio';
el.name = 'answer';
el.value = i;
el.id = 'answer' + i;
el.addEventListener('change', () => {
selectedAnswer = i;
nextButton.removeAttribute('disabled');
} );
const label = document.createElement('label');
label.setAttribute('for', el.id );
label.innerHTML = answer;
const container = document.createElement('div');
container.appendChild(el);
container.appendChild(label);
return container;
} ).forEach( a => target.appendChild( a ) );
}
return {
nextQuestion
}
};
// create a questionaire and start the first question
questionaire(
questions,
document.querySelector('#btnNext'),
document.querySelector('#questionaire'),
score => alert('You scored ' + score )
).nextQuestion();
<div id="questionaire">
</div>
<div class="toolstrip">
<button id="btnNext" type="button">Next</button>
</div>
If you want to check for equality use == or ===. == will check if the values are the same,
=== will also check if the types are the same.
For example:
0 == "0" => true
0 === "0" => false.

Javascript coding quiz not adding up

I'm trying to do a simple quiz where it should sum the correct answers and incorrect answers. The thing is although I put two out of three correct answers, I keep getting the same result for the correct and incorrect array: 0. So there must be something wrong at the end, in the evaluate function. Thanks in advance
var responsesArray= [];
var correct=[];
var incorrect= [];
function question2() {
var firstQuestion = prompt('Does null === 0 ? (Yes or No)')
// why do you need to convert the answer to lowercase?
if (firstQuestion.toLowerCase() === 'yes') {
firstQuestion = true
} else if (firstQuestion.toLowerCase() === 'no') {
firstQuestion = false
} else {
// what if the user writes something other than yes or no?
// they will have to answer the question again
alert("Please answer either Yes or No");
return question2();
}
responsesArray.push(firstQuestion); // add the true or false value to the responses array
}
question2();
function question3() {
var js = prompt('What was the original name for JavaScript: Java, LiveScript, JavaLive, or ScriptyScript?');
js = js.toLowerCase();
switch (js) {
// your own answers
case "livescript":
console.log("Correct!");
break;
case "Java":
console.log("wrong");
break;
case "JavaLive":
console.log("wrong");
break;
case "ScriptyScript":
console.log("wrong");
break;
default:
console.log("Sorry the answer is LiveScript");
}
responsesArray.push(js);
var mine = prompt('What coding language is exclusively related to the back-end: Ruby, JavaScript, HTML?');
mine= mine.toLowerCase();
switch (mine) {
// your own answers
case "ruby":
console.log("Yeah!");
break;
case "html":
console.log("ouuu I'm sorry for you");
break;
case "javascript":
console.log("Yeah but so so");
break;
}
responsesArray.push(mine);
}
question3();
function evaluate(responsesArray)
{
for (var i = 0; i < responsesArray.length; i++)
{
if (responsesArray[i] === true|| "livescript" || "ruby")
{
correct++;
} else{
if (responsesArray[i] !== true|| "livescript" || "ruby") {
incorrect++;
}
}
}
Define an array to store the correct answer and then compare correct and user response and easily can identify whether it is correct or not.
Please check below snippet.
var responsesArray= [];
var correct=0;
var incorrect= 0;
//Correct answer key initialize
var index = 0;
//Initialize array to store correct answer.
var correctAnswers = [];
function question2() {
//Save correct answer.
correctAnswers[index++] = "yes";
var firstQuestion = prompt('Does null === 0 ? (Yes or No)')
// why do you need to convert the answer to lowercase?
if (firstQuestion.toLowerCase() === 'yes') {
console.log("correct");
firstQuestion = 'yes'
} else if (firstQuestion.toLowerCase() === 'no') {
console.log("in-correct");
firstQuestion = 'no'
} else {
// what if the user writes something other than yes or no?
// they will have to answer the question again
alert("Please answer either Yes or No");
return question2();
}
responsesArray.push(firstQuestion); // add the true or false value to the responses array
}
question2();
function question3() {
//Save correct answer.
correctAnswers[index++] = "livescript";
var js = prompt('What was the original name for JavaScript: Java, LiveScript, JavaLive, or ScriptyScript?');
js = js.toLowerCase();
switch (js) {
// your own answers
case "livescript":
console.log("Correct!");
break;
case "Java":
console.log("wrong");
break;
case "JavaLive":
console.log("wrong");
break;
case "ScriptyScript":
console.log("wrong");
break;
default:
console.log("Sorry the answer is LiveScript");
}
responsesArray.push(js);
//Save correct answer.
correctAnswers[index++] = "ruby";
var mine = prompt('What coding language is exclusively related to the back-end: Ruby, JavaScript, HTML?');
mine= mine.toLowerCase();
switch (mine) {
// your own answers
case "ruby":
console.log("Yeah!");
break;
case "html":
console.log("ouuu I'm sorry for you");
break;
case "javascript":
console.log("Yeah but so so");
break;
}
responsesArray.push(mine);
//Call function to evaluate correct or incorrect answer
evaluate(responsesArray,correctAnswers)
}
question3();
function evaluate(responsesArray,correctAnswers)
{
for (var i = 0; i < responsesArray.length; i++)
{
//Match response with correct answer.
if (responsesArray[i] === correctAnswers[i])
{
correct++;
} else{
if (responsesArray[i] !== correctAnswers[i]) {
incorrect++;
}
}
}
alert("Correct : "+correct+" and Incorrect : "+incorrect);
}
The way you test for correct answers is wrong. Instead define an array with the correct answers and verify them as follows:
var correct = incorrect = 0; // better initialise your variables
function evaluate(responsesArray) {
var correctAnswers = [true,"livescript","ruby"];
for (var i = 0; i < responsesArray.length; i++) {
if (responsesArray[i] === correctAnswers[i]) {
correct++;
} else {
incorrect++;
}
}
}
What you had was:
if (responsesArray[i] === true|| "livescript" || "ruby"){
But this means:
if the answer was true, or .... "livescript" is true, or ... "ruby" is true, then
As JavaScript considers strings to be truthy, the if condition would always be true.
Note also that there is no need to do a second if, since the else part is only executed if the first if condition was false, which means you already have filtered for the cases where the answer was wrong.
Finally, your counter variables should be defined before you start incrementing them. It works without this definition, but if one of the two variables is not incremented, it will still be undefined after your call to evaluate. Better always define your variables.

Why wont the randomization in this code work?

Thank you for answering my original question, and the reason i am simply editing this post for my second question about this code is because the site wont let me make very many questions. my question is why isnt makesjump1 randomly true or false? it always seems to come out true. please help #Yhlas and #codeConcussion
var isjumping1 = true;
while(isjumping1) {
var makesjump1 = Math.random()
if(makesjump1 => .51) {
makesjump1 = true }
else if(makesjump1 <= .50) {
makesjump1 = false }
var jump1 = prompt("Do you choose to JUMP, or let the fairies help you FLY").toUpperCase()
switch(jump1) {
case 'JUMP':
if(makesjump1 = true) {
console.log("You made the jump on your own, so the fairies reward you with a steel sword(9 DMG)")
damage = 9;
weapon = 'steel sword(9 DMG)'; }
else if(makesjump1 = false) {
console.log("You attempt the jump but miss it, and are hanging on by a thread")
console.log("The fairies rescue you, but you got scratched up, doing 3 damge to you.")
health = health - 3; }
isjumping1 = false;
break;
case 'FLY':
console.log("The fairies help you over the pit")
isjumping1 = false;
break;
default:
alert("That was not a choice!")
break; }
}
You're assigning it to true with every loop. Use == instead or just...
while(isjumping1)
while(isjumping1==1) - comparison
while(isjumping1=1) - assignment(always returns true)
The way that you're assigning the random value to makesjump1 is incorrect. It would fail if Math.random() returned a value in the range (0.50,0.51). Instead, try this:
var makesjump1 = Math.random()<0.5;

Use function return as the content for a conditional statement

i'd like to use the return value of a specific function as the condition of an if statement. Is that possible ?
I'm basically building a string inside a function that takes an array (the conditionArray) and concatenates it to a statement.
Then it returns this condition as a string.
After that, i wanted to use this string as the condition of my if-statement.
My current problem looks something like that.
var answer = prompt("Tell me the name of a typical domestic animal");
var conditionArray = new Array("Dog", "Turtle", "Cat", "Mouse")
function getCondition(conditionArray) {
for (i = 0; i < conditionArray.length; i++) {
if (i != conditionArray.length) {
condition += 'answer === ' + conditionArray[i] + ' || ';
} else {
condition += 'answer === ' + conditionArray[i];
}
return condition;
}
}
if (getCondition(conditionArray)) {
alert("That is correct !");
} else {
alert("That is not a domestic animal !");
}
For this type of test use Array.prototype.indexOf, x = arr.indexOf(item)
x === -1 means item is not in arr
Otherwise x is the index of arr that the first occurrence of item is located
var options = ["Dog", "Turtle", "Cat", "Mouse"],
answer = prompt("Tell me the name of a typical domestic animal");
// some transformation of `answer` here, i.e. casing etc
if (options.indexOf(answer) !== -1) {
alert("That is correct !");
} else {
alert("That is not a domestic animal !");
}
The best way to do this kind of test is to use Array.prototype.indexOf. See Paul's answer for more details on how to use it.
--
If you really really want to return a condition, you can use eval() to evaluate the condition string. Keep in mind that eval() is dangerous though. It's usage isn't recommended. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Don%27t_use_eval_needlessly!
if (eval(getCondition(conditionArray))) {
alert("That is correct !");
} else {
alert("That is not a domestic animal !");
}

Categories