I am trying to create some questions where you can choose an option from 1 to 5.
I am doing this using radio buttons, and I also change their ID so that they are not the same entity.
Although I am first creating the first question and after the other one, for some reason all the radio buttons are connected and I can only choose 1 button out of the 10 if I create 2 questions, and not 1 from the first question and 1 from the next one.
Does anyone know how to fix this problem? Check my code below to see the problem. Thanks
This is my code:
const questionnaire = document.getElementById('questionaire');
var numsQN = 0;
questionnaire.onclick = ev => {
if (ev.target.tagName === "BUTTON") {
switch (ev.target.className) {
case "remove-qu":
switch (ev.target.parentNode.className) {
case "numQuestion":
numsQN--;
document.getElementById('numberOfNumQuestions').innerHTML = "Number Questions = " + numsQN;
break;
}
ev.target.parentNode.remove();
break;
case "add-numli":
newNumSubquestion(ev.target.closest(".starQuestion").querySelector('ul'), false)
break;
}
}
else {
switch (ev.target.className) {
case "remove-numli":
ev.target.parentNode.remove();
break;
}
}
}
function newNumQuestion() {
questionnaire.insertAdjacentHTML('beforeend', `
<div class='numQuestion'> <div class="numbers"> <ul></ul> </div>`);
}
function newNumSubquestion(q, subquestionNumber) {
q.insertAdjacentHTML('beforeend', `
<li class="numSubquestion">
<span class="numSubquestionName">Sub-question</span>
<div id='colourRadioButtons'> </div>`);
var element = document.getElementById("colourRadioButtons");
var newName = "colourRadioButtons" + subquestionNumber + "";
element.id = newName;
let lastRadio = false;
const numbers = { "5": false, "4": false, "3": false, "2": false, "1": false, },
radioStatic = {
name: "colour", onchange: (event) => {
if (lastRadio) {
numbers[lastRadio] = false;
}
lastRadio = event.currentTarget.value;
numbers[lastRadio] = event.currentTarget.checked;
}, type: "radio"
}; // radioStatic
for (let key in numbers) {
element.appendChild(
Object.assign(document.createElement("label"), { textContent: key })).appendChild(
Object.assign(document.createElement("input"), radioStatic, { checked: numbers[key], value: key }));
if (numbers[key]) {
lastRadio = key;
}
}
}
function generateNumberQuestion() {
let howManyOptionEachNumsQuestionHas = 2;
for (let i = 0; i < 1; i++) {
newNumQuestion(true);
for (let j = 0; j < howManyOptionEachNumsQuestionHas; j++) {
newNumSubquestion(questionnaire.querySelector("div.numQuestion:last-child ul"), j);
}
}
}
document.getElementById("addNumButton").onclick = function () { generateNumberQuestion(); };
<h1 id="myText" contenteditable="true">Survey Name</h1>
<button type="button" id="addNumButton">Number Rating</button>
<form>
<div id="questionaire"></div>
</form>
Before I start explaining please understand I am relatively new to coding, so please don't rag on me to bad, lol.
I am building a quiz that is multiple choice all of the quiz is working except for the part that is supposed to show the question explanation when the next button is clicked. When I add the code to the output.push() it appears on the screen and loops through it but my buttons stop working. I am not sure why they stop working.
I also need a way to hide the question explanation until the user has clicked an answer. Any help would be appreciated, thanks in advance.
window.onload = function() {
(function() {
// Functions
function buildQuiz() {
// variable to store the HTML output
const output = [];
// for each question...
myQuestions.forEach(
(currentQuestion, questionNumber) => {
// variable to store the list of possible answers
const answers = [];
// and for each available answer...
for (var letter in currentQuestion.answers) {
// ...add an HTML radio button
answers.push(
`<label>
<input type="radio" name="question${questionNumber}"
value="${letter}">
${letter} :
${currentQuestion.answers[letter]}
</label>`
);
}
// add this question and its answers to the output
output.push(
`<div class="slide">
<div class="question"> ${currentQuestion.question}
</div>
<div class="answers"> ${answers.join("")} </div>
</div>`
)
);
// <div
class="explanationOne">${currentQuestion.explanation.correct}
</div>
// <div
class="explanationTwo">${currentQuestion.explanation.explain}
</div>
// <div
class="explanationOne">${currentQuestion.explanation.source}
</div>
document.write(); document.write(output.push($ {
currentQuestion.explanation.correct
}));
}
);
// finally combine our output list into one string of HTML and
put it on the page
quizContainer.innerHTML = output.join('');
}
function showResults() {
// gather answer containers from our quiz
const answerContainers =
quizContainer.querySelectorAll('.answers');
// keep track of user's answers
let numCorrect = 0;
// for each question...
myQuestions.forEach((currentQuestion, questionNumber) => {
// find selected answer
const answerContainer = answerContainers[questionNumber];
const selector =
`input[name=question${questionNumber}]:checked`;
const userAnswer = (answerContainer.querySelector(selector)
|| {}).value;
// if answer is correct
if (userAnswer === currentQuestion.correctAnswer) {
// add to the number of correct answers
numCorrect++;
// color the answers green
answerContainers[questionNumber].style.color =
'lightgreen';
}
// if answer is wrong or blank
else {
// color the answers red
answerContainers[questionNumber].style.color = 'red';
}
});
// show number of correct answers out of total
resultsContainer.innerHTML = 'Your Score:' + ' ' +
`${numCorrect} out of
${myQuestions.length}`;
}
function showSlide(n) {
slides[currentSlide].classList.remove('active-slide');
slides[n].classList.add('active-slide');
currentSlide = n;
if (currentSlide === 0) {
previousButton.style.display = 'inline-block';
nextButton.style.display = 'inline-block';
submitButton.style.display = 'inline-block';
document.getElementById("submit").disabled = true;
document.getElementById("previous").disabled = true;
} else {
submitButton.style.display = 'inline-block';
document.getElementById("submit").disabled = false;
document.getElementById("previous").disabled = false;
}
if (currentSlide === slides.length - 1) {
previousButton.style.display = 'inline-block';
nextButton.style.display = 'none';
submitButton.style.display = 'inline-block';
document.getElementById("submit").disabled = false;
} else {
previousButton.style.display = 'inline-block';
nextButton.style.display = 'inline-block';
submitButton.style.display = 'none';
}
}
function showNextSlide() {
showSlide(currentSlide + 1);
}
function showPreviousSlide() {
showSlide(currentSlide - 1);
}
function showExplanation() {
var x = document.getElementById('explanations');
if (x.style.display === 'none') {
x.style.display = 'block';
} else {
x.style.display = 'none';
}
};
// Variables
const quizContainer = document.getElementById('quiz');
const resultsContainer = document.getElementById('results');
const explainQuestion = document.getElementById('explanation');
const myQuestions = [{
question: "What color is the sky",
answers: {
a: "blue",
b: "green",
c: "yellow",
d: "orange"
},
explanation: {
correct: "Correct answer: A. Yep the sky is blue",
explain: "Everyone knows that.
",
source: "Your brain"
},
correctAnswer: "a"
},
{
question: "What time do you wake up in the morning?",
answers: {
a: "Noon",
b: "6 AM - 8 AM",
c: "9 AM - 11 AM",
d: "After noon"
},
explanation: {
correct: "Correct answer: B. The early bird gets the
worm.",
explain: "If you get up early you more likely to be
successful.
",
source: "life experience!"
},
correctAnswer: "b"
},
];
// Kick things off
buildQuiz();
// Pagination
const previousButton = document.getElementById("previous");
const nextButton = document.getElementById("next");
const submitButton = document.getElementById('submit');
const slides = document.querySelectorAll(".slide");
let currentSlide = 0;
// Show the first slide
showSlide(currentSlide);
// Event listeners
previousButton.addEventListener("click", showPreviousSlide);
nextButton.addEventListener("click", showNextSlide);
submitButton.addEventListener('click', showResults);
// nextButton.addEventListener("click", myQuestions.explanation.correct);
// nextButton.addEventListener("click", myQuestions.explanation.explain);
// nextButton.addEventListener("click", myQuestions.explanation.source);
})();
}
<body>
<!-- START OF QUIZ-->
<div id="border" class="uk-align-center uk-width-1-2">
<div class="quiz-body">
<h1 class="h1-quiz">Test Your Knowledge</h1>
<div class="quiz-container">
<div id="quiz"></div>
</div>
<div id="buttonGroup" class="uk-width-1-1 uk-align-center">
<button id="previous" class="uk-text-center">Previous </button>
<button id="next" class="uk-text-center">Next </button>
<button id="submit" class="uk-text-center">Submit </button>
</div>
<div class="explanationOne"> </div>
<div class="explanationTwo"></div>
<div class="explanationOne"></div>
<div id="results" class="uk-text-center uk-text-large uk-text-bold uk-margin-small-top">
</div>
<div class="uk-text uk-text-small uk-text-center">If you click the previous button once the quiz is complete the questions you answered correctly turn green and the incorrect answers are red.</div>
</div>
</div>
<!--END OF QUIZ-->
<br/>
<script src="code.js"></script>
</body>
just done the basic of showing explanations when clicked on label.
https://codesandbox.io/s/epic-poitras-ldyxk?file=/src/index.js
The code is too big to paste here. Attaching screenshot.
I have a Javascript Q&A Quiz working but I have one issue that must be solved.
I need to make the answer required before going to the next question, I really don't know how to make this work.
I got this code from this source, but I have changed a few things. https://codepen.io/SitePoint/pen/GmPjjL
HTML:
<div class="quiz-container">
<div id="quiz"></div>
</div>
<button id="previous">Previous Question</button>
<button id="next">Next Question</button>
<button id="submit">Submit Quiz</button>
<div id="results"></div>
JS:
(function() {
const myQuestions = [
{
question: "Question 1",
answers: {
a: "answer a",
b: "answer b",
},
correctAnswer: "a"
},
{
question: "question 2",
answers: {
a: "answer a",
b: "answer b",
},
correctAnswer: "a"
}
];
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="slide">
<div class="question"> ${currentQuestion.question} </div>
<div class="answers"> ${answers.join("")} </div>
</div>`
);
});
quizContainer.innerHTML = output.join("");
}
function showResults() {
const answerContainers = quizContainer.querySelectorAll(".answers");
let numCorrect = 0;
myQuestions.forEach((currentQuestion, questionNumber) => {
const answerContainer = answerContainers[questionNumber];
const selector = `input[name=question${questionNumber}]:checked`;
const userAnswer = (answerContainer.querySelector(selector) || {}).value;
if (userAnswer === currentQuestion.correctAnswer) {
numCorrect++;
answerContainers[questionNumber].style.color = "#333333";
} else {
answerContainers[questionNumber].style.color = "#333333";
}
});
var premio;
if(numCorrect == 0)
{
premio = '<div><span style="color: red">RESULT 0</span></div>'; }
else if(numCorrect == 1) { premio = '<div>RESULT 1</div>'; }
document.getElementById("quiz").style.display = "none";
document.getElementById("previous").style.display = "none";
document.getElementById("submit").style.display = "none";
resultsContainer.innerHTML = `RESULT <span class="resultadonum">${numCorrect}</span>` + premio; //de ${myQuestions.length}//
}
function showSlide(n) {
slides[currentSlide].classList.remove("active-slide");
slides[n].classList.add("active-slide");
currentSlide = n;
if (currentSlide === 0) {
previousButton.style.display = "none";
} else {
previousButton.style.display = "inline-block";
}
if (currentSlide === slides.length - 1) {
nextButton.style.display = "none";
submitButton.style.display = "inline-block";
} else {
nextButton.style.display = "inline-block";
submitButton.style.display = "none";
}
}
function showNextSlide() {
showSlide(currentSlide + 1);
}
function showPreviousSlide() {
showSlide(currentSlide - 1);
}
const quizContainer = document.getElementById("quiz");
const resultsContainer = document.getElementById("results");
const submitButton = document.getElementById("submit");
buildQuiz();
const previousButton = document.getElementById("previous");
const nextButton = document.getElementById("next");
const slides = document.querySelectorAll(".slide");
let currentSlide = 0;
showSlide(0);
submitButton.addEventListener("click", showResults);
previousButton.addEventListener("click", showPreviousSlide);
nextButton.addEventListener("click", showNextSlide);
})();
Your best bet is to use the disabled attribute for your button.
Hook the disabled up to a function that checks whether or not the user has entered anything. Review your answers container around line 77 for the relevant code to check if the user has entered anything.
Psudo Code
function checkIfUserEnteredAnything(currentSlide){
//Code to calculate how many questions total the user has answered.
if(currentSlide === numQuestionsUserAnswered){
return true}
return false
Then, you'll set up your button to be disabled if the user hasn't entered anything.
nextButton.setAttribute('disabled',!checkIfUserEnteredAnything(currentSlide))
The exclamation point denotes the "not" function; if your function returns true (the user has entered a value), then it will become false-- telling the next button that it should not be disabled. If your function returns false, then the user has NOT entered a value, and it will tell the button to be disabled.
I am currently making a quiz in Javascript that randomizes questions and answers. I have the questions randomizing but how do I add the answers to go along with a certain question? I also want each answer to be placed in a div of its own, like so: http://imgur.com/a/l9w9j
Here's the code I have so far:
var display = document.getElementById("questions");
var questions = ['What is the weather like?',
'What time of day is it?',
'Whats your favourite music?',
'Which season is your favourite?',
'What colour are your eyes?'];
var questionTracker = [];
var questionAmount = 1;
// Iterate however many times
for (var i = 0; i < questionAmount; i++) {
// Keep creating random numbers until the number is unique
do {
var randomQuestion = Math.floor(Math.random() * questions.length);
} while (existingQuestions());
display.innerHTML += questions[randomQuestion] + '<br>';
// Add the question to the tracker
questionTracker.push(randomQuestion);
}
// If the current random number already exists in the tracker, return true
function existingQuestions() {
for (var i = 0; i < questionTracker.length; i++) {
if (questionTracker[i] === randomQuestion) {
return true;
}
}
return false;
}
And my HTML:
<div id="questions">
</div>
<div id="answers">
<div class="answers-left">
<div class="answer1" tabIndex="1">Sunny</div>
<div class="answer2" tabIndex="2">Raining</div>
</div>
<div class="answers-right">
<div class="answer3" tabIndex="3">Cloudy</div>
<div class="answer4" tabIndex="4">Windy</div>
</div>
<div class="clear"></div>
</div>
Her you can use of object instead of array
var questionData= {
"questions":[
{
"question":"this is hard question to answer",
"answers":[
"yes","no","why not","none"
]
},
{
"question":"this is 2nd hard question to answer",
"answers":[
"yes","no","why not","none"
]
}
]
}
questionData.map(function(question){
//Here you can write the dom structure that you like
})
You can store your questions and answers inside an array of objects
Each object hold a question and an answers property. answers is an array that contains each possible answers.
The following code will take a random question using Math.random() to find a random index. With this index, you can select the object in the array and then select the question and answers.
I added some CSS to add the desired effect. This can be improved with the colors/size/margins/... you want
var questionElement = document.getElementById("questions");
var answersElements = document.getElementsByClassName("answer");
var data = [{
question: 'What is the weather like?',
answers: ['Sunny', 'Raining', 'Cloudy', 'Windy']
}, {
question: 'What time of day is it?',
answers: ['Morning', 'Lunch', 'Evening', 'Night']
}];
var randomIndex = Math.floor(Math.random() * data.length);
questionElement.innerHTML = data[randomIndex].question;
for (let i = 0; i < answersElements.length; i++) {
answersElements[i].innerHTML = data[randomIndex].answers[i];
}
.answer {
display: inline-block;
background-color: #00BCD4;
margin: 1em;
}
<div id="questions">
</div>
<div id="answers">
<div class="answers-left">
<div class="answer" tabIndex="1">Sunny</div>
<div class="answer" tabIndex="2">Raining</div>
</div>
<div class="answers-right">
<div class="answer" tabIndex="3">Cloudy</div>
<div class="answer" tabIndex="4">Windy</div>
</div>
<div class="clear"></div>
</div>
Why not add the answers to the questions in an object array?
var display = document.getElementById("questions");
var answers = document.getElementById("answers");
var answersLeft = document.getElementById("answers-left");
var answersRight = document.getElementById("answers-right");
var questions = [{
"q": "What is the weather like?",
"a": [
"Sunny",
"Raining",
"Cloudy",
"Windy"
]
},
{
"q": "What time of day is it?",
"a": [
"Sunny",
"Raining",
"Cloudy",
"Windy"
]
},
{
"q": "Whats your favourite music?",
"a": [
"Sunny",
"Raining",
"Cloudy",
"Windy"
]
},
{
"q": "Which season is your favourite?",
"a": [
"Sunny",
"Raining",
"Cloudy",
"Windy"
]
},
{
"q": "What colour are your eyes?",
"a": [
"Sunny",
"Raining",
"Cloudy",
"Windy"
]
}
];
var questionTracker = [];
var questionAmount = 1;
// Iterate however many times
for (var i = 0; i < questionAmount; i++) {
// Keep creating random numbers until the number is unique
do {
var randomQuestion = Math.floor(Math.random() * questions.length);
} while (existingQuestions());
display.innerHTML += questions[randomQuestion].q + '<br>';
var answersToQ = questions[randomQuestion].a;
for (var j = 0; j < answersToQ.length; j++) {
var answer = "<p>" + answersToQ[j] + "</p>";
if (j % 2 === 0) {
answersLeft.innerHTML += answer;
} else {
answersRight.innerHTML += answer;
}
}
// Add the question to the tracker
questionTracker.push(randomQuestion);
}
// If the current random number already exists in the tracker, return true
function existingQuestions() {
for (var i = 0; i < questionTracker.length; i++) {
if (questionTracker[i] === randomQuestion) {
return true;
}
}
return false;
}
<style type="text/css">
#answers-left {
position: relative;
float: left;
width: 50%;
}
#answers-right {
position: relative;
float: right;
width: 50%;
}
#answers p {
background-color: blue;
width: 50%;
text-align: center;
color: #fff;
cursor: pointer;
}
</style>
<div id="questions">
</div>
<div id="answers">
<div id="answers-left">
</div>
<div id="answers-right">
</div>
</div>
Here is example that i made for you with following code.
Sorry but i did not have time to make ccs rules, but you can see that questions are mixed and answers for them all mixed all so.
http://devel.vis25.com/test.php
I recommend you to use something like this, for my example you will need Jquery and Jquery templates
Here is link to Jquery download jquery tempaltes
Here is example of you'r tempaltes and html.
<html>
<head>
<script src="https://devel.vis25.com//Vendors/JqueryUI/external/jquery/jquery.js"></script>
<script src="http://devel.vis25.com/Vendors/jquery.tmpl.min.js"></script>
</head>
<body onload="RenderQuestions();">
<div id="Questions"></div>
<script id="Question-Tempalte" type="text/x-jQuery-tmpl">
<div class="Question" id=question-"${ID}">
<div class="Question-text">${QuestionText}</div>
<div class="Question-answer-container" id="Question-answer-container-${ID}"></div>
</div>
</script>
<script id="Answer-Tempalte" type="text/x-jQuery-tmpl">
<div class="answer" id="answer-${ID}">
<div class="answer-text" tabIndex="${ID}">${answerText}</div>
</div>
</script>
</body>
</html>
with javascript do something like this.
//Function that is called in body 'onload' event.
function RenderQuestions(){
//Array of you'r questions as json objects
var questions = [
{ ID : '1', QuestionText : 'What is the weather like?' },
{ ID : '2', QuestionText : 'What time of day is it?' },
{ ID : '3', QuestionText : 'Whats your favourite music?' },
{ ID : '4', QuestionText : 'Which season is your favourite?' },
{ ID : '5', QuestionText : 'What colour are your eyes?' },
];
//Call shuffle function for your questions, so they are mixed randomly.
var ShuffledQuestions = shuffle( questions );
//Loop true all of your questions and render them inside of your questions <div>
//Allso call functions 'RenderAnswers()' by question id value[ 'ID' ].
$.each(ShuffledQuestions, function(index, value){
$( '#Question-Tempalte' ).tmpl( value ).appendTo( '#Questions' );
RenderAnswers( value[ 'ID' ] );
});
}
//Shuffle function return randomly mixed array.
function shuffle( array ) {
var currentIndex = array.length, temporaryValue, randomIndex;
while (0 !== currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
//RenderAnswers function takes QuestionID as argument so we can render answer elements for right questions, and we have right answers.
function RenderAnswers( QuestionID ){
var Answers = [];
//Check which question are we rendering.
//Answers for question ID 1 ( 'What is the weather like?' ).
if( QuestionID == 1){
Answers = [
{ AnswersID : 1 , answerText : 'Sunny' },
{ AnswersID : 2 , answerText : 'Raining'},
{ AnswersID : 3 , answerText : 'Cloudy'},
{ AnswersID : 4 , answerText : 'Windy'},
];
}
//Answers for question ID 2 ( 'What time of day is it?' ).
if( QuestionID == 2){
Answers = [
{ AnswersID : 1 , answerText : '8:00' },
{ AnswersID : 2 , answerText : '12:00'},
{ AnswersID : 3 , answerText : '18:00'},
{ AnswersID : 4 , answerText : '00:00'},
];
}
//Answers for question ID 3 ( 'Whats your favourite music?' ).
if( QuestionID == 3){
Answers = [
{ AnswersID : 1 , answerText : 'Rock' },
{ AnswersID : 2 , answerText : 'pop'},
{ AnswersID : 3 , answerText : 'rap'},
{ AnswersID : 4 , answerText : 'EDM'},
];
}
//Answers for question ID 4 ( 'Which season is your favourite?' ).
if( QuestionID == 4){
Answers = [
{ AnswersID : 1 , answerText : 'Summer' },
{ AnswersID : 2 , answerText : 'Winter'},
{ AnswersID : 3 , answerText : ''},
{ AnswersID : 4 , answerText : ''},
];
}
//Answers for question ID 5 ( 'What colour are your eyes?' ).
if( QuestionID == 4){
Answers = [
{ AnswersID : 1 , answerText : 'blue' },
{ AnswersID : 2 , answerText : 'brown'},
{ AnswersID : 3 , answerText : 'green'},
{ AnswersID : 4 , answerText : ''},
];
}
//Shuffle answers.
var ShuffledAnswers = shuffle( Answers );
//Renders answer elements for question.
$( '#Answer-Tempalte' ).tmpl( ShuffledAnswers ).appendTo( '#Question-answer-container-'+QuestionID );
}
Hope i was able to help you, and feel free to ask anything is i did not understand your question right !
Best regards,
Vis25
I don't know why my code will stop work if i add a if statment to my last function var checkAnswer = function(). If i delete the statment the code will work again fine. What's the problem with it? It's kinda wierd and I don't get it.
Array.prototype.random = function(length) {
return this[Math.floor(Math.random() * length)];
};
var country = [{
name: "romaniei",
capital: "bucuresti"
}, {
name: "bulgariei",
capital: "sofia"
}],
questions = [
"What is the capital of ",
" is the capital of what country?"
]
document.querySelector('input').onclick = function() {
var q,
chosen_country = country.random(country.length),
chosen_question = questions.random(questions.length);
if (chosen_question == questions[0]) {
q = chosen_question + chosen_country.name + "?";
} else if (chosen_question == questions[1]) {
q = chosen_country.capital + chosen_question;
}
document.querySelector('#que').innerHTML = q;
}
var checkAnswer = function() {
var answer = document.myform.answ.value;
if () {}
}
<form name="myform">
<input type="button" value="Generate question">
<div id="que">Intrebare:</div>
<input type="text" id="answ">
<input type="button" value="ok">
</form>
if () {} isn't a valid if statement - the condition body has to be an expression.
Source: ECMAScript 5 spec
For example, any of these are valid:
if (true) {}
if (1 < 2) {}
if("") {}