0

I've created a simple js quiz app. But I want to show a certain number questions per quiz session from all questions. For example, I will add 20 questions in my question array. But in all session, it will show any 10 results only randonmy from all questions. How can I do it ?

Here's my code snippet:

var total_seconds = 1220 * 1;
var c_minutes = parseInt(total_seconds / 60);
var c_seconds = parseInt(total_seconds % 60);
var timer;

function CheckTime() {
  document.getElementById("quiz-time-left1").innerHTML = '<i class="fa fa-clock-o"></i>&nbsp;' +c_minutes +'m'+':'+ c_seconds+'s' ;

  if (total_seconds <= 0) {
    score();
  } else {
    total_seconds = total_seconds - 1;
    c_minutes = parseInt(total_seconds / 60);
    c_seconds = parseInt(total_seconds % 60);
    timer = setTimeout(CheckTime, 1000);
  }
}

timer = setTimeout(CheckTime, 1000);

const quizData = [{
    question: "Which language runs in a web browser?",
    a: "Java",
    b: "C",
    c: "Python",
    d: "JavaScript",
    correct: "d",
}, {
    question: "What does CSS stand for?",
    a: "Central Style Sheets",
    b: "Cascading Style Sheets",
    c: "Cascading Simple Sheets",
    d: "Cars SUVs Sailboats",
    correct: "b",
}, {
    question: "What does HTML stand for?",
    a: "Hypertext Markup Language",
    b: "Hypertext Markdown Language",
    c: "Hyperloop Machine Language",
    d: "Helicopters Terminals Motorboats Lamborginis",
    correct: "a",
}, {
    question: "What year was JavaScript launched?",
    a: "1996",
    b: "1995",
    c: "1994",
    d: "none of the above",
    correct: "b",
}, ];

const quiz = document.getElementById("quiz");
const answerElements = document.querySelectorAll(".answer");
const questionElement = document.getElementById("question");
const a_text = document.getElementById("a_text");
const b_text = document.getElementById("b_text");
const c_text = document.getElementById("c_text");
const d_text = document.getElementById("d_text");
const submitButton = document.getElementById("submit");

let currentQuiz = 0;
let score = 0;
const deselectAnswers = () => {
    answerElements.forEach((answer) => (answer.checked = false));
};
const getSelected = () => {
    let answer;
    answerElements.forEach((answerElement) => {
        if (answerElement.checked) answer = answerElement.id;
    });
    return answer;
};
const loadQuiz = () => {
    deselectAnswers();
    const currentQuizData = quizData[currentQuiz];
    questionElement.innerText = currentQuizData.question;
    a_text.innerText = currentQuizData.a;
    b_text.innerText = currentQuizData.b;
    c_text.innerText = currentQuizData.c;
    d_text.innerText = currentQuizData.d;
};


loadQuiz();
submitButton.addEventListener("click", () => {
    const answer = getSelected();
    if (answer) {
        if (answer === quizData[currentQuiz].correct) score++;
        currentQuiz++;
        
let asd =  quizData.length - score;
let ssrate = (1220 - Math.floor(total_seconds));
let ggg = "";

 if (ssrate < 12)
   ggg = "good morning";
else if (ssrate < 16)
   ggg = "ghfgdfgh ning";
else if (ssrate < 24)
   ggg = "asaasasasa   ng";
  
let avg =  Math.round( score * 100 / quizData.length);    

    document.getElementById("myProgress").value = avg ;    
        
        if (currentQuiz < quizData.length) loadQuiz();
        else {
     
        
   // stop timer
clearInterval(timer);     

            quiz.innerHTML = "<h2>Total Question : " + quizData.length +  "<br>" + "Correct Ans : " + score + " <br> Wrong Ans : " + asd  + " <br> Average : " + avg + " %  <br> Time Usage : " + ssrate + " Seconds <br> Average : " + ggg + " %  <br><br>  <br><br> <button onclick='location.reload()'>Play Again</button></h2>"

        }
    }
});
* {
    box-sizing: border-box;
}

body {
    background-color: #b8c6db;
    background-image: linear-gradient(315deg, #b8c6db 0%, #f5f7fa 100%);
    font-family: "Poppins", sans-serif;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    overflow: hidden;
    margin: 0;
}

.quiz-container {
    background-color: #fff;
    border-radius: 10px;
    box-shadow: 0 0 10px 2px rgba(100, 100, 100, 0.1);
    width: 600px;
    max-width: 95vw;
    overflow: hidden;
}

.quiz-header {
    padding: 4rem;
}

h2 {
    padding: 1rem;
    text-align: center;
    margin: 0;
}

ul {
    list-style-type: none;
    padding: 0;
}

ul li {
    font-size: 1.2rem;
    margin: 1rem 0;
}

ul li label {
    cursor: pointer;
}

button {
    background-color: #8e44ad;
    color: #fff;
    border: none;
    display: block;
    width: 100%;
    cursor: pointer;
    font-size: 1.1rem;
    font-family: inherit;
    padding: 1.3rem;
}

button:hover {
    background-color: #732d91;
}

button:focus {
    outline: none;
    background-color: #5e3370;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"/>

                  <div id="quiz-time-left1" ></div>
    <div class="quiz-container" id="quiz">
        <div class="quiz-header">
            <h2 id="question">Question is loading...</h2>
            <ul>
                <li> <input type="radio" name="answer" id="a" class="answer" /> <label for="a" id="a_text">Answer...</label> </li>
                <li> <input type="radio" name="answer" id="b" class="answer" /> <label for="b" id="b_text">Answer...</label> </li>
                <li> <input type="radio" name="answer" id="c" class="answer" /> <label for="c" id="c_text">Answer...</label> </li>
                <li> <input type="radio" name="answer" id="d" class="answer" /> <label for="d" id="d_text">Answer...</label> </li>
            </ul>
        </div> <button id="submit">Submit</button>
    </div>

<progress id='myProgress' value='' max='100'>

Look at this one: This is my quiz code where is almost 4 questions. But when I run or play this code, it show all questions. But I want to show only any 2 questions randomly among all. How can I do it ?

  • Lookup JS Math.rand and find an index to choose a question from your array. Make another array which doesn't include that question and repeat for however many times you want. – A Haworth Jan 20 '23 at 16:00
  • How can I do it ? – Asma Binta Younus Jan 20 '23 at 16:01
  • Have a go at coding it and if still stuck put your code into your question with a description of what isn't working. Have you looked up Math.random and how to copy an array and how to remove an item from it? – A Haworth Jan 20 '23 at 16:25

1 Answers1

1

Figure out how to randomly sort an array: How to randomize (shuffle) a JavaScript array? I went with this answer for a fast sorting algorithm.

Your goal here is the shuffle the source array, and pull the initial 10 off of it. This can be done by sorting a copy of the original array and slicing it to 10 items.

Now, add:

const randomizedQuestions = shuffle(quizData).slice(0, 10);

Change all references to quizData with randomizedQuestions.

Note: I also changed currentQuiz to currentQuestion (index), because the variable was confusing.

Full example

const
  rand = n => Math.floor(Math.random() * n),
  swap = (t, i, j) => { let q = t[i]; t[i] = t[j]; t[j] = q; return t; },
  shuffle = (arr = []) => {
    let copy = arr.slice(), last = copy.length, n;
    while (last > 0) { n = rand(last); swap(copy, n, --last); }
    return copy;
  };

var total_seconds = 1220 * 1;
var c_minutes = parseInt(total_seconds / 60);
var c_seconds = parseInt(total_seconds % 60);
var timer;

function CheckTime() {
  document.getElementById("quiz-time-left1").innerHTML = '<i class="fa fa-clock-o"></i>&nbsp;' + c_minutes + 'm' + ':' + c_seconds + 's';

  if (total_seconds <= 0) {
    score();
  } else {
    total_seconds = total_seconds - 1;
    c_minutes = parseInt(total_seconds / 60);
    c_seconds = parseInt(total_seconds % 60);
    timer = setTimeout(CheckTime, 1000);
  }
}

timer = setTimeout(CheckTime, 1000);

const quizData = [{
  question: "Which language runs in a web browser?",
  a: "Java",
  b: "C",
  c: "Python",
  d: "JavaScript",
  correct: "d",
}, {
  question: "What does CSS stand for?",
  a: "Central Style Sheets",
  b: "Cascading Style Sheets",
  c: "Cascading Simple Sheets",
  d: "Cars SUVs Sailboats",
  correct: "b",
}, {
  question: "What does HTML stand for?",
  a: "Hypertext Markup Language",
  b: "Hypertext Markdown Language",
  c: "Hyperloop Machine Language",
  d: "Helicopters Terminals Motorboats Lamborginis",
  correct: "a",
}, {
  question: "What year was JavaScript launched?",
  a: "1996",
  b: "1995",
  c: "1994",
  d: "none of the above",
  correct: "b",
}, ];

const quiz = document.getElementById("quiz");
const answerElements = document.querySelectorAll(".answer");
const questionElement = document.getElementById("question");
const a_text = document.getElementById("a_text");
const b_text = document.getElementById("b_text");
const c_text = document.getElementById("c_text");
const d_text = document.getElementById("d_text");
const submitButton = document.getElementById("submit");

const randomizedQuestions = shuffle(quizData).slice(0, 10);
let currentQuestion = 0;
let score = 0;
const deselectAnswers = () => {
  answerElements.forEach((answer) => (answer.checked = false));
};
const getSelected = () => {
  let answer;
  answerElements.forEach((answerElement) => {
    if (answerElement.checked) answer = answerElement.id;
  });
  return answer;
};
const loadQuestion = () => {
  deselectAnswers();
  const currentQuestionData = randomizedQuestions[currentQuestion];
  questionElement.innerText = currentQuestionData.question;
  a_text.innerText = currentQuestionData.a;
  b_text.innerText = currentQuestionData.b;
  c_text.innerText = currentQuestionData.c;
  d_text.innerText = currentQuestionData.d;
};


loadQuestion();
submitButton.addEventListener("click", () => {
  const answer = getSelected();
  if (answer) {
    if (answer === randomizedQuestions[currentQuestion].correct) score++;
    currentQuestion++;

    let asd = randomizedQuestions.length - score;
    let ssrate = (1220 - Math.floor(total_seconds));
    let ggg = "";

    if (ssrate < 12) ggg = "good morning";
    else if (ssrate < 16) ggg = "ghfgdfgh ning";
    else if (ssrate < 24) ggg = "asaasasasa   ng";

    let avg = Math.round(score * 100 / randomizedQuestions.length);

    document.getElementById("myProgress").value = avg;

    if (currentQuestion < randomizedQuestions.length) loadQuestion();
    else {
      // stop timer
      clearInterval(timer);

      quiz.innerHTML = "<h2>Total Question : " + quizData.length + "<br>" + "Correct Ans : " + score + " <br> Wrong Ans : " + asd + " <br> Average : " + avg + " %  <br> Time Usage : " + ssrate + " Seconds <br> Average : " + ggg + " %  <br><br>  <br><br> <button onclick='location.reload()'>Play Again</button></h2>"

    }
  }
});
* {
  box-sizing: border-box;
}

body {
  background-color: #b8c6db;
  background-image: linear-gradient(315deg, #b8c6db 0%, #f5f7fa 100%);
  font-family: "Poppins", sans-serif;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  overflow: hidden;
  margin: 0;
}

.quiz-container {
  background-color: #fff;
  border-radius: 10px;
  box-shadow: 0 0 10px 2px rgba(100, 100, 100, 0.1);
  width: 600px;
  max-width: 95vw;
  overflow: hidden;
}

.quiz-header {
  padding: 4rem;
}

h2 {
  padding: 1rem;
  text-align: center;
  margin: 0;
}

ul {
  list-style-type: none;
  padding: 0;
}

ul li {
  font-size: 1.2rem;
  margin: 1rem 0;
}

ul li label {
  cursor: pointer;
}

button {
  background-color: #8e44ad;
  color: #fff;
  border: none;
  display: block;
  width: 100%;
  cursor: pointer;
  font-size: 1.1rem;
  font-family: inherit;
  padding: 1.3rem;
}

button:hover {
  background-color: #732d91;
}

button:focus {
  outline: none;
  background-color: #5e3370;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" />

<div id="quiz-time-left1"></div>
<div class="quiz-container" id="quiz">
  <div class="quiz-header">
    <h2 id="question">Question is loading...</h2>
    <ul>
      <li> <input type="radio" name="answer" id="a" class="answer" /> <label for="a" id="a_text">Answer...</label> </li>
      <li> <input type="radio" name="answer" id="b" class="answer" /> <label for="b" id="b_text">Answer...</label> </li>
      <li> <input type="radio" name="answer" id="c" class="answer" /> <label for="c" id="c_text">Answer...</label> </li>
      <li> <input type="radio" name="answer" id="d" class="answer" /> <label for="d" id="d_text">Answer...</label> </li>
    </ul>
  </div> <button id="submit">Submit</button>
</div>

<progress id='myProgress' value='' max='100'>
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
  • Thanks @Mr. Polywhirl I love this. But It's sometimes showing same question 2 times and make it 4. The questions should be randomly placed and should sho all of them. But it sometime show same question twice. Another one, Its even showing all questions. Not a certain number of questions. – Asma Binta Younus Jan 20 '23 at 16:35
  • @AsmaBintaYounus I fixed this, it was because I was reshuffling each time a question was prompted. Try it again and see what I did. – Mr. Polywhirl Jan 20 '23 at 16:36
  • Wow...... It works......Thanks But whats about certain questions ? Please look at description and title again Brother, – Asma Binta Younus Jan 20 '23 at 16:39
  • @AsmaBintaYounus did you want the choices to be randomized as well? – Mr. Polywhirl Jan 20 '23 at 16:41
  • No Mr. Polywhirl, my main question was that how to show certain number questions from all questions! for example, in my quiz, there's 4 questions. I want to show just 2 question in per session randomly. Now when I run this code, it shows all 4 questions. I want that, it will show only 2 questions randomly from all questions. Please help me to do it brother. – Asma Binta Younus Jan 20 '23 at 17:25
  • @AsmaBintaYounus in the code above, just alter the `slice` range e.g. `shuffle(quizData).slice(0, 2);` (randomly select 2 from the 4). – Mr. Polywhirl Jan 20 '23 at 17:41