Attempting to dynamcially append innerText to label elements from array - javascript

I am working on my second ever Javascript project. As you can imagine, since I am still finding my feet with building projects, there are quite a few errors which I am running into (and learning from).
Let me just quickly explain what stage I am at in building the family quiz and what the problem is. I have created an array of objects which stores questions, choices and answers within each index of the array.
When the quiz starts up, there is an intro screen displaying the rules etc. The user then clicks on a "start quiz" button which transitions the screen to the first question.
The user then selects the correct answer and clicks next question. This is the stage I am at currently.
What I am trying to simply do is append the next 'choices' into the label elements. But when I click it nothing happens. Obviously I am doing something wrong.
Please can someone assist?
Many thanks!
EDIT I have been informed by a response that there was a syntax error in my forEach loop which appends the next 'choices' to the label elements. I have corrected that. However, what I am finding now is that it is only appending the first index value of every 'choices' array to every label button.
$(document).ready(function(){
var azeem = [
{
question: "What is Azeem's favourte color?",
choices: ["blue", "yellow", "red", "green"],
answer: 0
},
{
question: "What is Azeem's favourte movie?",
choices: ["Scarface", "The Terminator", "Shawshank Redemption", "The Dark Knight"],
answer: 3
},
{
question: "What was Azeem's first ever job role?",
choices: ["Cleaner", "Store Assistant", "Sales", "Admin"],
answer: 1
},
{
question: "What is Azeem's favourite dish?",
choices: ["Pasta", "Pizza", "Chips", "Curry"],
answer: 0
},
{
question: "What subject did Azeem enjoy the most in school?",
choices: ["Drama", "Science", "P.E", "History"],
answer: 0
},
{
question: "What subject did Azeem least enjoy in school?",
choices: ["Geography", "Maths", "History", "I.T"],
answer: 1
},
{
question: "Which one of these cities has Azeem travelled to?",
choices: ["Madrid", "Lisbon", "Istanbul", "Dublin"],
answer: 1
},
{
question: "Which college did Azeem study in?",
choices: ["NewVic", "Redbridge", "East Ham", "Barking"],
answer: 3
},
{
question: "Who is Azeem's favourite sports icon?",
choices: ["Eric Cantona", "Muhammad Ali", "Cristiano Ronaldo", "Prince Naseem"],
answer: 1
},
{
question: "Who is Azeem's favourite music artist?",
choices: ["Michael Jackson", "Eminem", "Drake", "Linkin Park"],
answer: 1
},
];
var currentQuestion = 0;
var questionNumberCounter = 1;
var questionNumber = document.getElementById("questionCount");
var choices = document.getElementById("choicesSection");
var questions = document.getElementById("ques");
questions.innerText = azeem[currentQuestion].question;
// The following event listener will transition from the instructions to the first question of the quiz
document.getElementById("startquiz").addEventListener("click",function(){
$(".quiz-intro").fadeOut(600);
$(".quiz-section").delay(600).slideDown("slow");
questionNumber.innerText = questionNumberCounter;
azeem[currentQuestion].choices.forEach(function(value){
var radio = document.createElement("input");
var label = document.createElement("label");
var div = document.createElement("div");
$(div).addClass("choice");
radio.setAttribute("type", "radio");
radio.setAttribute("name", "answer");
radio.setAttribute("value", value);
var radioID = 'question-'+currentQuestion;
radio.setAttribute('id', radioID) ;
label.setAttribute("for", radioID);
label.innerHTML = value +"<br>";
choices.appendChild(div);
div.appendChild(radio);
div.appendChild(label);
})
})
document.getElementById("submitanswer").addEventListener("click",function(){
questionNumberCounter++;
questionNumber.innerText = questionNumberCounter;
currentQuestion++
questions.innerText = azeem[currentQuestion].question;
azeem[currentQuestion].choices.forEach(function(value){
var labels = document.getElementsByTagName("label");
var labelCounter = 0;
while (labelCounter < 5){
labels[labelCounter].innerText = value;
labelCounter++;
}
}
})
});
HTML:
<div class="container">
<h1 class="text-center">FAMILY QUIZ</h1>
<h4 class="text-center">YOU HAVE CHOSEN AZEEM!</h4>
<div class="row text-center quizSection">
<div class="col-md-4 image-section">
<img src="images/3.jpg" id="azeem" class="img-responsive img-thumbnail">
</div>
<div class="col-md-8 quiz-intro">
<h2>INSTRUCTIONS</h2>
<ul id="instructions">
<li>This is a multiple choice quiz</li>
<li>There is only one correct answer per question</li>
<li>At the end of the quiz you will be shown your total score which will reflect the amount of questions answered correctly</li>
<li>There are no hints available during the process of the quiz</li>
<li>Click the 'Start Quiz' button to begin</li>
</ul>
<button id="startquiz" class="btn-small btn-success">START QUIZ</button>
</div>
<div class="col-md-8 quiz-section">
<h5>Question <span id="questionCount">1</span> of 15</h5>
<p class="text-center" id="ques"></p>
<div id="choicesSection">
</div>
<input type="submit" id="submitanswer" value="Submit Answer" class="btn-small btn-success">
</div>
</div>

Okay so first things first, you were missing a closing parens )
The bigger issue with your code lay within two things. First, this for loop is causing an issue where every choice you iterate over you are renaming every label that name. Why? The code below goes through each choice, sure, but it then loops over every label and redefines the label's text as that choice. Take a look:
azeem[currentQuestion].choices.forEach(function(value) {
var labels = document.getElementsByTagName("label");
var labelCounter = 0;
while (labelCounter < 5) {
labels[labelCounter].innerText = value;
labelCounter++;
}
});
Another thing you'll notice above is that you are specifically saying 5 when really the operand should be checking for an amount that's less than labels.length (this will throw an error, so once we change it we can carry on)
azeem[currentQuestion].choices.forEach(function(value) {
var labels = document.getElementsByTagName("label");
var labelCounter = 0;
while (labelCounter < labels.length) {
labels[labelCounter].innerText = value;
labelCounter++;
}
});
Now you'll see the questions populate with the same possible answer over and over. How do we fix this? Well, first it would pay to get our labels ahead of the loop since the elements themselves aren't being moved or deleted(we're just changing their text property) otherwise we're wasting resources grabbing the same elements over and over again.
Secondly forEach comes with a handy parameter called index that is automatically supplied to the callback function. a.e. forEach(item, indexOFItem) - this means that we can eliminate your while loop entirely and just change the label corresponding to the index of the choice.
var labels = document.getElementsByTagName("label");
azeem[currentQuestion].choices.forEach(function(value, ind) {
labels[ind].innerText = value;
});
Edit As pointed out in the comments, you're also going to want to check if the current question exists before loading it. A quick and dirty test for this with your current code is to simply check if the question exists in your object. There are better ways to make sure. You want to avoid static values when it comes to dynamic objects/arrays. As an example the labels issue above where you had set it to check if it was < 5 (less than 5). We changed this to labels.length to dynamically check the length instead of assuming it would always be 5. In the case of the question number, you have 15 questions stated, but that's not dynamic. A better way would be to check against azeem.length if you know that every object within azeem is a question. However, as I'm not sure, a quick fix is the following:
if (azeem[currentQuestion]) {
questions.innerText = azeem[currentQuestion].question;
var labels = document.getElementsByTagName("label");
azeem[currentQuestion].choices.forEach(function(value, ind) {
labels[ind].innerText = value;
});
} else {
alert("no more questions");
}
If you change these things the code will run as follows:
$(document).ready(function() {
var azeem = [{
question: "What is Azeem's favourte color?",
choices: ["blue", "yellow", "red", "green"],
answer: 0
}, {
question: "What is Azeem's favourte movie?",
choices: ["Scarface", "The Terminator", "Shawshank Redemption", "The Dark Knight"],
answer: 3
}, {
question: "What was Azeem's first ever job role?",
choices: ["Cleaner", "Store Assistant", "Sales", "Admin"],
answer: 1
}, {
question: "What is Azeem's favourite dish?",
choices: ["Pasta", "Pizza", "Chips", "Curry"],
answer: 0
}, {
question: "What subject did Azeem enjoy the most in school?",
choices: ["Drama", "Science", "P.E", "History"],
answer: 0
}, {
question: "What subject did Azeem least enjoy in school?",
choices: ["Geography", "Maths", "History", "I.T"],
answer: 1
}, {
question: "Which one of these cities has Azeem travelled to?",
choices: ["Madrid", "Lisbon", "Istanbul", "Dublin"],
answer: 1
}, {
question: "Which college did Azeem study in?",
choices: ["NewVic", "Redbridge", "East Ham", "Barking"],
answer: 3
}, {
question: "Who is Azeem's favourite sports icon?",
choices: ["Eric Cantona", "Muhammad Ali", "Cristiano Ronaldo", "Prince Naseem"],
answer: 1
}, {
question: "Who is Azeem's favourite music artist?",
choices: ["Michael Jackson", "Eminem", "Drake", "Linkin Park"],
answer: 1
}, ];
var currentQuestion = 0;
var questionNumberCounter = 1;
var questionNumber = document.getElementById("questionCount");
var choices = document.getElementById("choicesSection");
var questions = document.getElementById("ques");
questions.innerText = azeem[currentQuestion].question;
// The following event listener will transition from the instructions to the first question of the quiz
document.getElementById("startquiz").addEventListener("click", function() {
$(".quiz-intro").fadeOut(600);
$(".quiz-section").delay(600).slideDown("slow");
questionNumber.innerText = questionNumberCounter;
azeem[currentQuestion].choices.forEach(function(value) {
var radio = document.createElement("input");
var label = document.createElement("label");
var div = document.createElement("div");
$(div).addClass("choice");
radio.setAttribute("type", "radio");
radio.setAttribute("name", "answer");
radio.setAttribute("value", value);
var radioID = 'question-' + currentQuestion;
radio.setAttribute('id', radioID);
label.setAttribute("for", radioID);
label.innerHTML = value + "<br>";
choices.appendChild(div);
div.appendChild(radio);
div.appendChild(label);
})
})
document.getElementById("submitanswer").addEventListener("click", function() {
questionNumberCounter++;
questionNumber.innerText = questionNumberCounter;
currentQuestion++;
if (azeem[currentQuestion]) {
questions.innerText = azeem[currentQuestion].question;
var labels = document.getElementsByTagName("label");
azeem[currentQuestion].choices.forEach(function(value, ind) {
labels[ind].innerText = value;
});
} else {
alert("no more questions");
}
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<h1 class="text-center">FAMILY QUIZ</h1>
<h4 class="text-center">YOU HAVE CHOSEN AZEEM!</h4>
<div class="row text-center quizSection">
<div class="col-md-4 image-section">
<img src="images/3.jpg" id="azeem" class="img-responsive img-thumbnail">
</div>
<div class="col-md-8 quiz-intro">
<h2>INSTRUCTIONS</h2>
<ul id="instructions">
<li>This is a multiple choice quiz</li>
<li>There is only one correct answer per question</li>
<li>At the end of the quiz you will be shown your total score which will reflect the amount of questions answered correctly</li>
<li>There are no hints available during the process of the quiz</li>
<li>Click the 'Start Quiz' button to begin</li>
</ul>
<button id="startquiz" class="btn-small btn-success">START QUIZ</button>
</div>
<div class="col-md-8 quiz-section">
<h5>Question <span id="questionCount">1</span> of 15</h5>
<p class="text-center" id="ques"></p>
<div id="choicesSection">
</div>
<input type="submit" id="submitanswer" value="Submit Answer" class="btn-small btn-success">
</div>
</div>

Related

Chart.js using the value of certain data in external json file

I'm working on this self exploration which I want to show a chart that shows how many anime that have comedy genre or fantasy genre. The data for my chart is going to be an external json file (anime.json) on my computer and it's not yet contain the total of how many anime that have comedy or fantasy genre, so I need to do some loop to know that. I try this to make it happen by trying with this code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<canvas id="myChart"></canvas>
</div>
<script>
let data;
$.getJSON("anime.json", function(json){
data = json;
});
let comedy = 0;
let fantasy= 0;
for (i = 0; i < data.length; i++)
{
let genres = data[i]['genres']
for (j = 0; j < genress.length; j++)
{
let value = genres[j].trim()
if (value.toLowerCase() == 'comedy')
{
comedy = comedy +1;
}
if (value.toLowerCase() == 'fantasy')
{
fantasy = fantasy + 1;
}
}
}
let myChart = document.getElementById('myChart').getContext('2d');
let massPopChart = new Chart(myChart, {
type: 'bar',
data: {
labels:['Comedy', 'Super Natural'],
datasets:[{
label : 'Genre',
data: [
comedy,
superNatural
],
}]
},
options : {},
});
</script>
</body>
</html>
But when I open this html on my browser, It came up empty so I'm wondering what is the correct way to do it. And this is my json file (and I have like 25 or 30 of them):
[
{
"cover_title": "Haikyuu!! TO THE TOP",
"cover_studio": "Production I.G",
"cover_img": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx106625-UR22wB2NuNVi.png",
"format": "TV",
"duration": "84%",
"description": "The fourth season of Haikyuu!!\n\nThe Karasuno High School Volleyball Club finally won their way into the nationals after an intense battle for the Miyagi Prefecture Spring Tournament qualifiers. As they were preparing for the nationals, Kageyama is invited to go to All-Japan Youth Training Camp. At the same time, Tsukishima is invited to go to a special rookie select training camp for first-years in Miyagi Prefecture. Hinata feels panic that he\u2019s being left behind as one of the first-years and then decides to show up at the Miyagi Prefecture rookie select training camp anyway...\n\n(Source: Crunchyroll)",
"genres": [
"Comedy ",
" Drama ",
" Sports"
]
},
{
"cover_title": "Eizouken ni wa Te wo Dasu na!",
"cover_studio": "Science SARU",
"cover_img": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx109298-YvjfI88hX76T.png",
"format": "TV",
"duration": "79%",
"description": "First year high schooler Midori Asakusa loves anime so much, she insists that \"concept is everything\" in animation. Though she draws a variety of ideas in her sketchbook, she hasn't taken the first step to creating anime, insisting that she can't do it alone. The producer-type Sayaka Kanamori is the first to notice Asakusa's genius. Then, when it becomes clear that their classmate, charismatic fashion model Tsubame Mizusaki, really wants to be an animator, they create an animation club to realize the \"ultimate world\" that exists in their minds.\n\n(Source: Crunchyroll)",
"genres": [
"Adventure ",
" Comedy"
]
},
{
"cover_title": "Made in Abyss: Fukaki Tamashii no Reimei",
"cover_studio": "Kinema Citrus",
"cover_img": "https://s4.anilist.co/file/anilistcdn/media/anime/cover/large/bx100643-fPH9OgEKKvcI.jpg",
"format": "Movie",
"duration": "78%",
"description": "Dawn of the Deep Soul continues the epic adventure of plucky Riko and Reg who are joined by their new friend Nanachi. Together they descend into the Abyss\u2019 treacherous fifth layer, the Sea of Corpses, and encounter the mysterious Bondrewd, a legendary White Whistle whose shadow looms over Nanachi\u2019s troubled past. Bondrewd is ingratiatingly hospitable, but the brave adventurers know things are not always as they seem in the enigmatic Abyss...\n\n(Source: Sentai Filmworks)",
"genres": [
"Adventure ",
" Fantasy ",
" Sci-Fi ",
" Drama"
]
}]
Thank you!
Your code seems to be fine, the only thing I can see is you are not handling the callback properly. The code you have written after $.getJSON should be placed inside the callback function. As because of the async behavior your data is set after other codes are executed. If you open console you may see error as cannot read property length of undefined as initially, the data is undefined.
Below snippet should fix your problem.
<script>
$.getJSON("anime.json", function (json) {
const data = json;
let comedy = 0;
let fantasy = 0;
for (i = 0; i < data.length; i++) {
let genres = data[i]["genres"];
for (j = 0; j < genress.length; j++) {
let value = genres[j].trim();
if (value.toLowerCase() == "comedy") {
comedy = comedy + 1;
}
if (value.toLowerCase() == "fantasy") {
fantasy = fantasy + 1;
}
}
}
let myChart = document.getElementById("myChart").getContext("2d");
let massPopChart = new Chart(myChart, {
type: "bar",
data: {
labels: ["Comedy", "Super Natural"],
datasets: [
{
label: "Genre",
data: [comedy, superNatural],
},
],
},
options: {},
});
});
</script>

Display javascript quiz after clicking button

I would like to display this quiz after a button is clicked (onclick). At this moment it appears directly into the website. I am sure is pretty simple but I am stuck here. Do you know how should I add the button code?
Here the HTML:
<div id="quiz"></div>
Here the JavaScript quiz:
(function() {
function buildQuiz() {
const output = [];
myQuestions.forEach((currentQuestion, questionNumber) => {
const answers = [];
for (letter in currentQuestion.answers) {
answers.push(
`<label>
<input type="radio" name="question${questionNumber}" value="${letter}">
${letter} :
${currentQuestion.answers[letter]}
</label>`
);
}
output.push(
`<div class="question"> ${currentQuestion.question} </div>
<div class="answers"> ${answers.join("")} </div>`
);
});
quizContainer.innerHTML = output.join("");
}
const quizContainer = document.getElementById("quiz");
const myQuestions = [{
question: "Who is the strongest?",
answers: {
a: "Superman",
b: "The Terminator",
c: "Waluigi, obviously"
},
correctAnswer: "c"
},
{
question: "What is the best site ever created?",
answers: {
a: "SitePoint",
b: "Simple Steps Code",
c: "Trick question; they're both the best"
},
correctAnswer: "c"
}
];
There are a couple things you can do to get what you want accomplished. Here is what I think is the best way.
Make buildQuiz a 1st order function by taking it out of the nameless function call. This will give other functions the ability to call on it.
Create an event listener that houses all the javascript you want to utilyze that runs after the DOM content is loaded. That looks like this:
document.addEventListener("DOMContentLoaded", function(event){
//code to be run after DOM is ready
}
This will allow your code to run only when the DOM is ready and allow you to organize how your code is run.
Place an event listener for the button that you want to control the creation of you quiz within the previously mentioned event listener. Within this callback will be the call to create your quiz.
Heres a codepen that illustrates how this would work. Also in your real thing it would be important to includes a noscript tag incase the person doesn't have javascript enabled on their browser. Cheers!
I added a button and even listener for click on button. I think this helps
(function() {
function buildQuiz() {
document.getElementById("showQuiz").style.visibility = "hidden"
const output = [];
myQuestions.forEach((currentQuestion, questionNumber) => {
const answers = [];
for (letter in currentQuestion.answers) {
answers.push(
`<label>
<input type="radio" name="question${questionNumber}" value="${letter}">
${letter} :
${currentQuestion.answers[letter]}
</label>`
);
}
output.push(
`<div class="question"> ${currentQuestion.question} </div>
<div class="answers"> ${answers.join("")} </div>`
);
});
quizContainer.innerHTML = output.join("");
}
var quizContainer = document.getElementById("quiz");
var myQuestions = [{
question: "Who is the strongest?",
answers: {
a: "Superman",
b: "The Terminator",
c: "Waluigi, obviously"
},
correctAnswer: "c"
},
{
question: "What is the best site ever created?",
answers: {
a: "SitePoint",
b: "Simple Steps Code",
c: "Trick question; they're both the best"
},
correctAnswer: "c"
}
];
document.getElementById('showQuiz').addEventListener('click',buildQuiz);
}());
<button id="showQuiz">Show Quiz</button>
<div id="quiz"></div>

Tab Index JavaScript function unknown/unspecified error?

NOTICE
I already asked this question on my alt account David Vex; but that account is glitched out and I can't sign into it, with a StackOverflow server error with gibberish talking about ERROR:0x12084123 followed by server gibberish; so the only way to follow up with it is reasking it. Please Excuse any inconvienence.
Quote from Question (Alt Account)
WORKABLE CODE
Better than JSFiddle!
I'm trying to make a table with a tabindex for each element which onClick, it will activate the imageSelector function (unnamed). I got the code from my last question, which was given with no named function. It worked with the 'alert' variant, but I fit it for the function that I need to check the answer which, if the if(answer1.innerHTML == "Correct Answer"){document.getElementById("correctAnswer").addAttribute("display", "inline")} is active, it will know that the answer is the set correct one, and will set the image with the id="correctAnswer" to display, but then after 3 seconds it should go back to display="hidden" and re-activate the whole randomize sequence, if the button isn't already selected, which doesn't seem to work. I tried using a setTimeout() function to make it when the answer is correct/incorrect, it will set a delay to call the function that would make the image invisible and re-randomize the answers. I'll show the code, and re-explain each part after the code.
HTML
<div id="randomizer">
<div id="wordOutput">
<div id="button">
<!-- This is the button that calls the getRandom() function to create the word. --><button id="myBtn">Randomize!</button><br>
<caption>Click this button to generate a random word!
</caption>
<!-- This is apart of the Randomizer tool, which can be changed to fit the words. It will output the answers based on -->
</button>
</div>
</div>
<div id="answers" class="answers">
<table>
<p id="outputNumber" class="outputNumber">Your word will go here; Click the Randomize Button!</p>
<tr>
<td class="output" id="output1" tabindex="1"></td>
<td class="output" id="output2" tabindex="1"></td>
<td class="output" id="output3" tabindex="1"></td>
</tr>
<tr>
<td class="output" id="output4" tabindex="1"></td>
<td class="output" id="output5" tabindex="1"></td>
<td class="output" id="output6" tabindex="1"></td>
</tr>
<tr>
<td class="output" id="output7" tabindex="1"></td>
<td class="output" id="output8" tabindex="1"></td>
<td class="output" id="output9" tabindex="1"></td>
</tr>
</table>
</div>
<div id="checkAnswer">
<img id="correctAnswer" src="http://png-1.findicons.com/files/icons/1965/colorcons_smoke/128/checkmark.png" alt="correct" style="position: absolute; left: 100px; display: none;">
<img id="incorrectAnswer" src="http://png-4.findicons.com/files/icons/1008/quiet/128/no.png" alt="incorrect" style="position: absolute; right: 100px; display: none;">
</div>
</div>
This lays out the whole sequence. outputNumber is where the number will be generated then converted to a word. The button div is simple; it's where the button is. The answers div holds the table, and each element is fitted with the id for the targetting, with the tabindex for making it clickable. The checkAnswer div holds the two hidden images.
CSS
Not really important; all it contains is Daneden's animate.css (3150 lines) of code plus 10 more lines for the coloring of the page...
JavaScript
/* Has the words and their respectful answers. */
var words = [
{ word: "Fruits A-B", array: ["Apple", "Apricot", "Avacado", "Banana", "Breadfruit", "Bilberry", "Blackberry", "Blackcurrant", "Blueberry"] },
{ word: "Fruits B-C", array: ["Boysenberry", "Cantaloupe", "Currant", "Cherry", "Cherimoya", "Cloudberry", "Coconut", "Cranberry", "Cucumber"] },
{ word: "Fruits D-G", array: ["Damson", "Date", "Dragonfruit", "Durian", "Eggplant", "Elderberry", "Feijoa", "Fig", "Goji berry"] },
{ word: "Fruits G-K", array: ["Gooseberry", "Grape", "Grapefruit", "Guava", "Huckleberry", "Honeydew", "Jackfruit", "Jambul", "Kiwi fruit"] },
{ word: "Fruits K-M", array: ["Kumquat", "Lemon", "Lime", "Loquat", "Lychee", "Mango", "Marion berry", "Melon", "Miracle fruit"] },
{ word: "Fruits M-P", array: ["Mulberry", "Nectarine", "Nut", "Olive", "Orange", "Papaya", "Passionfruit", "Peach", "Pepper"] },
{ word: "Fruits P-Q", array: ["Pear", "Persimmon", "Physalis", "Plum", "Pineapple", "Pomegranate", "Pomelo", "Purple Mangosteen", "Quince"] },
{ word: "Fruits R-T", array: ["Raspberry", "Rambutan", "Salal berry", "Salmon berry", "Satsuma", "Star fruit", "Strawberry", "Tomarillo", "Tomato"] },
{ word: "Fruits U-Z", array: ["Ugli fruit", "Watermelon", "Bell pepper", "Chili pepper", "Clementine", "Mandarine", "Tangerine", "Blood Orange", "Rock Melon"] }
];
/* This function grabs the word that is outputted, then changes the answers based on that word. Change to your liking! */
function grabWord() {
var word = document.getElementById("outputNumber").innerHTML;
var wordIndex;
for (var i = 0; i < words.length; i++) {
if (words[i].word === word) {
wordIndex = i;
break;
}
}
for (var i = 1; i <= 9; i++) {
document.getElementById("output" + i).innerHTML = words[wordIndex].array[i-1];
}
}
/* This function SHOULD be working, which it does if the function is something like alert(message) but with the function I need for the image visibility and such, it doesn't work; it doesn't even give me an answer. */
var cells = document.getElementsByTagName("td");
for (var i = 0; i < cells.length; i++) {
cells[i].addEventListener("click", function () {
var word = document.getElementById("outputNumber").innerHTML;
var answer1 = document.getElementById("output1");
var answer2 = document.getElementById("output2");
var answer3 = document.getElementById("output3");
var answer4 = document.getElementById("output4");
var answer5 = document.getElementById("output5");
var answer6 = document.getElementById("output6");
var answer7 = document.getElementById("output7");
var answer8 = document.getElementById("output8");
var answer9 = document.getElementById("output9");
if(word == "Fruits U-Z") {
if(answer1.innerHTML == "Ugli Fruit") {
document.getElementById("correctAnswer").setAttribute("display", "inline")
}
else {
document.getElementById("incorrectAnswer").setAttribute("display", "inline")
}
}
})
}
I have it condensed as MUCH as possible, but for the grabWord() function, I have to keep it that long, so that each word can have answers changed manually. It's set to what it is now for example purposes.
ERROR/PROBLEM
When I click on the answer that would match the last part that would check if its right or not, it does nothing. So I check the dev console (F12 in-browser) and see no error.
Any ideas?
KEEP IN MIND
I AM USUALLY BAD AT INCLUDING DETAILS/INFORMATION. IF YOU NEED MORE DETAILS, PLEASE COMMENT POLITELY, I WILL ADD AS MUCH INFO NEEDED POSSIBLE.
Took a look at your code ... it is working. However, you are setting the attribute "display" to "inline"; if you inspect the element for correct or incorrect answer this is NOT in the style ... adjustment below.
Also, you are only given a correct or incorrect when on Fruits U-Z and there is NO correct answer ... you, in this case, are comparing "Ugli fruit" in the array with "Ugli Fruit" as a string.
var cells = document.getElementsByTagName("td");
for (var i = 0; i < cells.length; i++) {
cells[i].addEventListener("click", function () {
var word = document.getElementById("outputNumber").innerHTML;
var answer1 = document.getElementById("output1");
var answer2 = document.getElementById("output2");
var answer3 = document.getElementById("output3");
var answer4 = document.getElementById("output4");
var answer5 = document.getElementById("output5");
var answer6 = document.getElementById("output6");
var answer7 = document.getElementById("output7");
var answer8 = document.getElementById("output8");
var answer9 = document.getElementById("output9");
console.log(word, answer1.innerHTML);
if(word == "Fruits U-Z") {
if(answer1.innerHTML == "Ugli Fruit") {
document.getElementById("correctAnswer").setAttribute("style", "display:inline; position:absolute; left:100px;");
document.getElementById("incorrectAnswer").setAttribute("style", "display:none; position:absolute; right:100px;");
}
else {
document.getElementById("correctAnswer").setAttribute("style", "display:none; position:absolute; left:100px;");
document.getElementById("incorrectAnswer").setAttribute("style", "display:inline; position:absolute; right:100px;");
}
}
});
}

Making a quiz with Javascript. Getting array values from and object.

Im trying to create a simple quiz with Javascript. I am struggling to grasp the concept of how to iterate over the values of an array from an object. I eventually want to display a radio button with its value as the choice of answers. If someone could point me in the right direction i would really appreciate it.
Fiddle: http://jsfiddle.net/Renay/eprxgxhu/
Here is my code:
HTML
<h1> General Knowledge Quiz </h1>
<h2 id='questionTitle'> </h2>
<ul id ='selectionList'> </ul>
<p> Click the next button to go to the next question! </p>
<button type="button" id = nextButton> Next </button>
</div>
Javascript
var allQuestions = [{
question: 'What is the capital city of Australia?',
choices: ['Sydney', 'Melbourne', 'Canberra', 'London'],
correctAnswer: 2
},
{
question: 'Who won the 2014 FIFA World Cup?',
choices: ['Brazil', 'England', 'Germany', 'Spain'],
correctAnswer: 2
},
{
question: 'What book series is authored by J.K Rowling?',
choices: ['Game of Thrones', 'Hunger Games', 'Twilight', 'Harry Potter'],
correctAnswer: 3
},
{
question: 'The Eiffel Tower is located in which following country?',
choices: ['Italy', 'France', 'Iceland', 'Mexico'],
correctAnswer: 1
}];
//Reference to tags
var questionTitle = document.getElementById('questionTitle');
var selectionList = document.getElementById('selectionList');
var nextButton = document.getElementById('nextButton');
//Initiating some variables
var i = 0;
var length1 = allQuestions.length;
var correctAnswer = 0;
function populateQuestion() {}
Firstly attach click event to next button and give call to populateQuestion() using counter to iterate through allQuestions array and use i as counter variable.
nextButton.onclick = function() {
/*itterate through questions*/
if(i>allQuestions.length -1){/*go to first when reached last*/
i=0;
}
populateQuestion(i);
i++;
};
Iterate through allQuestions array for question title and choices as:
function populateQuestion(qNum) {
var individualQuestion = allQuestions[i];
questionTitle.innerText = individualQuestion.question;
selectionList.innerHTML = ""; //reset choices list
for(key in individualQuestion.choices){
var radioBtnName = "question"+i+"_choice";
var choiceText = individualQuestion.choices[key];
selectionList.appendChild(createLi(radioBtnName,choiceText));
}
}
Write dynamic li and radio button creation function as:
function createLi(name, choiceText) {
var e = document.createElement('li');
var radioHtml = '<input type="radio" name="' + name + '"';
radioHtml += '/>';
radioHtml += choiceText;
e.innerHTML = radioHtml;
return e;
}
Please refer to this fiddle for same.
You need to associate an onClick event with your button to call the relevant part of the JavaScript. Go through the example here
On another note, using JavaScript for a quiz might not be a good idea as one can see the answers using view-source. I would suggest using PHP to fetch results from a database.

Adding detailed input forms to quiz results with Javascript

I currently have an online quiz in the making. The current code works fine, but I would like to see who scored what. I am still extremely new to Javascript, and I have been building this quiz for a friend. I have learned quite a bit just getting this thing to work.
Could someone please point me in the right direction on how to add a simple text input or two that will show up when the results page is called at the end of the questions array
I would like to be able to have the user input their name, and submit it along with the results using the php mailer.
I tried to add a simple html input field like below in the HTML area, but it never produced any results.
<input name="Name" type="text" value="" size="80">
Here is my fiddle to see my setup:
var allQuestions = [{
question: "Anger can be thought of as a like other feelings and emotions.",
choices: ["Emotion", "Wave length", "Continuum", "Exercise"],
correctAnswer: 2
}, {
question: "Strong, silent type of personality will usually when things finally overwhelm him.",
choices: ["Explode", "Implode", "Leave", "Cry"],
correctAnswer: 0
}, {
question: "People that complain about everything, and see themselves as victims, fit the personality type called.",
choices: ["Prosecutor", "Grouch", "Exterminator", "Terminator"],
correctAnswer: 1
}, {
question: "When someone wants to point out the faults in others, in order to shift blame off of himself, he is probably a",
choices: ["Displacer", "Intimidator", "Prosecutor", "grouch"],
correctAnswer: 2
},
{
question: "The type of personality takes his anger out on people or things he views as “less threatening” than the person he is actually mad at.",
choices: ["Grouch", "Displacer", "Prosecutor", "Coward"],
correctAnswer: 1
},
{
question: "The easiest type of anger personality to spot is usually the. Often these types come from abusive backgrounds.",
choices: ["Intimidator", "Grouch", "Displacer", "Prosecutor"],
correctAnswer: 0
},
{
question: "Anger has a medical definition, saying it is an state that ranges from to intense fury and rage.",
choices: ["Mental State Embarrassment", "Emotional State Mild Irritation", "Exhausted State Yawning", "Typical State Relaxing"],
correctAnswer: 1
},
{
question: "Anger is often compared to a",
choices: ["Flock of Geese", "Chord of Wood", "Pressure Cooker", "Bag of Ice"],
correctAnswer: 2
},
{
question: "Anger and rage can become a form of . These people are known as rageaholics.",
choices: ["Addiction", "Skin Disease", "Problem", "Comfort Zone"],
correctAnswer: 0
},
{
question: "First rule When you are don’t say anything!",
choices: ["Right", "Wrong", "Angry", "Confused"],
correctAnswer: 2
},
{
question: "Many times, we feel angry because a situation seems negative, and seems to clash with our.",
choices: ["Belief System", "Current Plans", "Family Members", "Schedule"],
correctAnswer: 0
},
{
question: "Many people carry beliefs, that keep them feeling victimized all of the time.",
choices: ["Stoic", "Unusual", "Irrational", "Western"],
correctAnswer: 2
},
{
question: "To contain anger, all we have to do is learn to view life from a perspective.",
choices: ["Personal", "Different", "Closed", "Unknown"],
correctAnswer: 1
},
];
//you can access checkbox name through an array
//match array number to number in allQuestions array
var questionNum = 0;
var scoreNum = 0;
var makeQuestions = "";
var failedQuestions = [];
$(document).ready(function () {
makeQuestions = function () {
if (questionNum === allQuestions.length) {
$("input[value=SUBMIT]").remove();
$("#questions").text(" All Complete!") .append("<br> Please click the button below to submit your results.") .append("<br>Your score is" + " " + scoreNum);
$("#questions").append("<br><input type='button' id='submit_answers' value='SUBMIT'><br><br>");
$("#answers_correct").val(scoreNum);
$("#questions").append("Failed questions: " + failedQuestions.join());
} else {
$("#questions").text(allQuestions[questionNum].question);
for (var i = 0; i < allQuestions[questionNum]['choices'].length; i++) {
$('#words').append('<input type="radio" name="buttons">' + allQuestions[questionNum]['choices'][i] + '</input');
}
}
}
makeQuestions();
$('#submit_answers').on('click', function () {
$('#answer_submission_form').submit();
});
});
var checkQuestions = function () {
var lenG = document.getElementsByName("buttons").length;
console.log(lenG);
var rightAnswer = allQuestions[questionNum]['correctAnswer'];
for (var i = 0; i < lenG; i++) {
if (document.getElementsByName("buttons")[i].checked === true) {
console.log(i);
console.log(document.getElementsByName("buttons")[i].checked);
//compare value to what was inputted
if (i === rightAnswer) {
scoreNum += 1;
alert("Correct! Your score is" + " " + scoreNum);
} else {
failedQuestions.push(questionNum);
alert("False! Your score is still" + " " + scoreNum);
}
}
}
questionNum = questionNum + 1;
$("#words").empty();
makeQuestions();
}
I'm not sure if this is what you need but I have added a fiddle:
http://jsfiddle.net/5Jjam/40/
I have added a div with the id='name'. This contains an input field for entering your text. This will be shown when all the answers have been submitted.

Categories