WELLCOME BACK

H

ello guys. How are you all? I hope you are all well. I came again with a post. Let’s go..

তো এই পোস্টে Quiz app/website নিয়ে কথা বলবো। আমি যে কোডগুলো দিবো সেগুলো সব ধরনের ওয়েবসাইটে ব্যবহার করতে পারবেন। চাইলে App ও ব্যবহার করতে পারবেন। তো Quiz এর সিস্টেম আর ডিজাইন কেমন তা আপনারাই Live দেখে নিন।যদি ভালো না লাগে বলবেন।

Demo and Screenshot

Demo:

SCREENSHOT





Folder system

তো এখন কোড গুলোর Folder দেখুন।

Quiz App
index.html
css
style.css
js
script.js
question.js

CODE

তো Folder দেখে নিশ্চয়ই বুঝে গেছেন কয়টি কোড দিবো আর কিভাবে ব্যবহার করবেন।
একটি index.html, style.css, script.js & question.js। তো চলুন কোডগুলো কপি করে ওয়েবসাইট বা অ্যাপ এ ব্যবহার করুন।

সব কোড একসাথে চান?? এটি দিলে অনেকের ভালো হবে তাই নিচের লিংক থেকে কপি কের আসুন।

Link:

index.html


<!DOCTYPE html>

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Quiz App in JavaScript </title>
    <!-- Linking Google fonts for icons -->
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@24,400,0,0" />
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <!-- Quiz Configuration Popup -->
    <div class="config-popup popup-container active">
      <div class="config-container quiz-box">
        <h2 class="config-title">Quiz Configuration</h2>

        <div class="config-option">
          <h4 class="option-title">Select Category</h4>
          <div class="category-options">
            <button class="category-option active">Programming</button>
            <button class="category-option">Geography</button>
            <button class="category-option">Mathematics</button>
            <button class="category-option">Entertainment</button>
          </div>
        </div>

        <div class="config-option">
          <h4 class="option-title">No. of Questions</h4>
          <div class="question-options">
            <button class="question-option">5</button>
            <button class="question-option active">10</button>
            <button class="question-option">15</button>
            <button class="question-option">20</button>
            <button class="question-option">25</button>
          </div>
        </div>

        <button class="start-quiz-btn">Start Quiz</button>
      </div>
    </div>

    <!-- Quiz Popup -->
    <div class="quiz-popup popup-container">
      <div class="quiz-container quiz-box">
        <header class="quiz-header">
          <h2 class="quiz-title">Quiz Application</h2>
          <div class="quiz-timer">
            <span class="material-symbols-rounded">timer</span>
            <p class="timer-duration"></p>
          </div>
        </header>

        <div class="quiz-content">
          <h1 class="question-text"></h1>
          <ul class="answer-options"></ul>
        </div>

        <div class="quiz-footer">
<p class="question-status"></p> <button class="next-question-btn"> Next <span class="material-symbols-rounded">arrow_right_alt</span> </button> </div> </div> </div> <!-- Quiz Result Popup --> <div class="result-popup popup-container"> <div class="result-container quiz-box"> <img src="quiz-over.png" class="result-img" /> <h2 class="result-title">Quiz Completed!</h2> <p class="result-message"></p> <button class="try-again-btn">Try Again</button> </div> </div> <!-- Scripts --> <script src="javascript/questions.js"></script> <script src="javascript/script.js"></script> </body> </html>

style.css


/* Importing Google fonts - Montserrat */ @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@100..900&display=swap'); * { margin: 0; padding: 0; box-sizing: border-box; font-family: "Montserrat", sans-serif; } body { display: flex; align-items: center; justify-content: center; min-height: 100vh; background: #5145BA; } .popup-container { position: fixed; left: 0; top: 0; padding: 15px; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; opacity: 0; pointer-events: none; transition: 0.2s ease; } .popup-container.active { opacity: 1; pointer-events: auto; } .popup-container .quiz-box { position: relative; z-index: 5; opacity: 0; pointer-events: none; background: #fff; border-radius: 8px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.13); transform: translateY(-50px); transition: all 0.4s ease-out; } .popup-container.active .quiz-box { opacity: 1; z-index: 10; pointer-events: auto; transform: translateY(0); } /* Quiz Configuration Stylings */ .config-container { z-index: 10; width: 415px; padding: 25px; text-align: center; } .config-container .config-title { font-size: 1.31rem; } .config-container .config-option { margin-top: 25px; } .config-option .option-title { font-weight: 500; font-size: 1.125rem; margin-bottom: 20px; } .config-option .category-options { display: grid; gap: 15px; grid-template-columns: repeat(2, 1fr); } .config-option .question-options { display: flex; flex-wrap: wrap; gap: 12px; padding: 0 30px; justify-content: center; } .config-option button { padding: 12px; font-size: 0.938rem; color: #000; cursor: pointer; font-weight: 500; border-radius: 6px; background: #fff; border: 1px solid #9B8FFF; transition: 0.3s ease; } .config-option button.active { color: #5145BA; border-color: #5145BA; background: #dfdafd; } .config-option button:hover, .quiz-content .answer-option:hover { background: #dad5fd; } .config-option .question-options button { flex: 1 1 10%; } .config-container .start-quiz-btn, .quiz-footer .next-question-btn, .result-container .try-again-btn { color: #fff; border: none; font-weight: 500; background: #5145BA; padding: 13px 25px; cursor: pointer; font-size: 1rem; border-radius: 6px; transition: background 0.3s ease; } .config-container .start-quiz-btn { margin-top: 30px; } .config-container .start-quiz-btn:hover, .quiz-footer .next-question-btn:hover, .result-container .try-again-btn:hover { background: #403795; } /* Quiz Container Stylings */ .quiz-container { width: 480px; } .quiz-container .quiz-header { display: flex; padding: 14px 25px; align-items: center; justify-content: space-between; box-shadow: 0 3px 6px rgba(0, 0, 0, 0.09); } .quiz-header .quiz-title { font-size: 1.43rem; font-weight: 700; } .quiz-header .quiz-timer { display: flex; width: 70px; color: #fff; gap: 5px; align-items: center; background: #32313C; border-radius: 6px; padding: 7px 9px; font-weight: 600; transition: 0.2s ease; } .quiz-header .quiz-timer span { font-size: 1.4rem; } .quiz-container .quiz-content { padding: 20px 25px 25px; } .quiz-content .question-text { font-size: 1.5rem; font-weight: 600; } .quiz-content .answer-options { list-style: none; display: flex; gap: 15px; margin-top: 20px; flex-direction: column; } .quiz-content .answer-option { display: flex; cursor: pointer; align-items: center; font-weight: 500; border-radius: 6px; padding: 13px 16px; border: 1px solid #B5ACFF; background: #F3F1FF; justify-content: space-between; transition: 0.3s ease; } .quiz-content .answer-option span { display: block; flex-shrink: 0; margin: -4px -3px -4px 12px; } .quiz-content .answer-option.correct { border-color: #B7E1C1; background: #D4EDDA; color: #155724; } .quiz-content .answer-option.correct span { color: #16AE56; } .quiz-content .answer-option.incorrect { border-color: #F4BEC3; background: #F8D7DA; color: #721C24; } .quiz-content .answer-option.incorrect span { color: #F23723; } .quiz-container .quiz-footer { padding: 15px 25px; display: flex; align-items: center; justify-content: space-between; border-top: 1px solid #C6C6C6; } .quiz-footer .question-status { font-weight: 500; } .quiz-footer .question-status b { font-weight: 600; } .quiz-footer .next-question-btn { display: inline-flex; gap: 5px; align-items: center; padding: 9px 17px; } /* Quiz Result Stylings */ .result-container { text-align: center; padding: 40px; width: 410px; } .result-container .result-img { width: 110px; } .result-container .result-title { margin-top: 30px; } .result-container .result-message { font-size: 1.125rem; font-weight: 500; margin-top: 15px; } .result-container .result-message b { font-weight: 700; color: #5145BA; } .result-container .try-again-btn { padding: 12px 20px; margin-top: 30px; } /* Media query code for mobile screens */ @media (max-width: 624px) { .config-container, .quiz-container .quiz-content { padding: 20px; } .quiz-content .answer-option { padding: 12px 10px 12px 14px; } .config-container .question-options { padding: 0 15px; } .quiz-container .quiz-header, .quiz-container .quiz-footer { padding: 13px 20px; } .quiz-header .quiz-title, .quiz-content .question-text { font-size: 1.3rem; } .result-container { padding: 40px 20px; } .result-container .result-title { font-size: 1.4rem; } }

question.js

আপনি quiz অন্য করতে চাইলে question বদলাতে পারেন।

এই কোডটি অনেক বড় তাই পোস্ট এ সব লেখা যাচ্ছে না তাই নিচে লিংক দিচ্ছি কপি করে নিন। অনেক question যুক্ত করা আছে তাই এমন।

Link:

script.js


// DOM element selectors
const configContainer = document.querySelector(".config-container");
const quizContainer = document.querySelector(".quiz-container");
const answerOptions = quizContainer.querySelector(".answer-options");
const nextQuestionBtn = quizContainer.querySelector(".next-question-btn");
const questionStatus = quizContainer.querySelector(".question-status");
const timerDisplay = quizContainer.querySelector(".timer-duration");
const resultContainer = document.querySelector(".result-container");

// Quiz state variables
const QUIZ_TIME_LIMIT = 15;
let currentTime = QUIZ_TIME_LIMIT;
let timer = null;
let quizCategory = "programming";
let numberOfQuestions = 10;
let currentQuestion = null;
const questionsIndexHistory = [];
let correctAnswersCount = 0;
let disableSelection = false;

// Display the quiz result and hide the quiz container
const showQuizResult = () => {
  clearInterval(timer);
  document.querySelector(".quiz-popup").classList.remove("active");
  document.querySelector(".result-popup").classList.add("active");

  const resultText = `You answered <b>${correctAnswersCount}</b> out of <b>${numberOfQuestions}</b> questions correctly. Great effort!`;
  resultContainer.querySelector(".result-message").innerHTML = resultText;
};

// Clear and reset the timer
const resetTimer = () => {
  clearInterval(timer);
  currentTime = QUIZ_TIME_LIMIT;
  timerDisplay.textContent = `${currentTime}s`;
};

// Initialize and start the timer for the current question
const startTimer = () => {
  timer = setInterval(() => {
    currentTime--;
    timerDisplay.textContent = `${currentTime}s`;

    if (currentTime <= 0) {
      clearInterval(timer);
      disableSelection = true;
      nextQuestionBtn.style.visibility = "visible";
      quizContainer.querySelector(".quiz-timer").style.background = "#c31402";
      highlightCorrectAnswer();

      // Disable all answer options after one option is selected
      answerOptions.querySelectorAll(".answer-option").forEach((option) => (option.style.pointerEvents = "none"));
    }
  }, 1000);
};

// Fetch a random question from based on the selected category
const getRandomQuestion = () => {
  const categoryQuestions = questions.find((cat) => cat.category.toLowerCase() === quizCategory.toLowerCase())?.questions || [];

  // Show the results if all questions have been used
  if (questionsIndexHistory.length >= Math.min(numberOfQuestions, categoryQuestions.length)) {
    return showQuizResult();
  }

  // Filter out already asked questions and choose a random one
  const availableQuestions = categoryQuestions.filter((_, index) => !questionsIndexHistory.includes(index));
  const randomQuestion = availableQuestions[Math.floor(Math.random() * availableQuestions.length)];

  questionsIndexHistory.push(categoryQuestions.indexOf(randomQuestion));
  return randomQuestion;
};

// Highlight the correct answer option and add icon
const highlightCorrectAnswer = () => { const correctOption = answerOptions.querySelectorAll(".answer-option")[currentQuestion.correctAnswer]; correctOption.classList.add("correct"); const iconHTML = `<span class="material-symbols-rounded"> check_circle </span>`; correctOption.insertAdjacentHTML("beforeend", iconHTML); }; // Handle the user's answer selection const handleAnswer = (option, answerIndex) => { if (disableSelection) return; clearInterval(timer); disableSelection = true; const isCorrect = currentQuestion.correctAnswer === answerIndex; option.classList.add(isCorrect ? "correct" : "incorrect"); !isCorrect ? highlightCorrectAnswer() : correctAnswersCount++; // Insert icon based on correctness const iconHTML = `<span class="material-symbols-rounded"> ${isCorrect ? "check_circle" : "cancel"} </span>`; option.insertAdjacentHTML("beforeend", iconHTML); // Disable all answer options after one option is selected answerOptions.querySelectorAll(".answer-option").forEach((option) => (option.style.pointerEvents = "none")); nextQuestionBtn.style.visibility = "visible"; }; // Render the current question and its options in the quiz const renderQuestion = () => { currentQuestion = getRandomQuestion(); if (!currentQuestion) return; disableSelection = false; resetTimer(); startTimer(); // Update the UI nextQuestionBtn.style.visibility = "hidden"; quizContainer.querySelector(".quiz-timer").style.background = "#32313C"; quizContainer.querySelector(".question-text").textContent = currentQuestion.question; questionStatus.innerHTML = `<b>${questionsIndexHistory.length}</b> of <b>${numberOfQuestions}</b> Questions`; answerOptions.innerHTML = ""; // Create option <li> elements, append them, and add click event listeners currentQuestion.options.forEach((option, index) => { const li = document.createElement("li"); li.classList.add("answer-option"); li.textContent = option; answerOptions.append(li); li.addEventListener("click", () => handleAnswer(li, index)); }); }; // Start the quiz and render the random question const startQuiz = () => { document.querySelector(".config-popup").classList.remove("active"); document.querySelector(".quiz-popup").classList.add("active"); // Update the quiz category and number of questions quizCategory = configContainer.querySelector(".category-option.active").textContent; numberOfQuestions = parseInt(configContainer.querySelector(".question-option.active").textContent); renderQuestion(); }; // Highlight the selected option on click - category or no. of question configContainer.querySelectorAll(".category-option, .question-option").forEach((option) => { option.addEventListener("click", () => { option.parentNode.querySelector(".active").classList.remove("active"); option.classList.add("active"); }); }); // Reset the quiz and return to the configuration container const resetQuiz = () => { resetTimer(); correctAnswersCount = 0; questionsIndexHistory.length = 0; document.querySelector(".config-popup").classList.add("active"); document.querySelector(".result-popup").classList.remove("active"); }; // Event listeners nextQuestionBtn.addEventListener("click", renderQuestion); resultContainer.querySelector(".try-again-btn").addEventListener("click", resetQuiz); configContainer.querySelector(".start-quiz-btn").addEventListener("click", startQuiz);

যদি আপনি সব কোড একখানে বলতে index.html এই ব্যবহার করেন তাহলে script.js & question.js দুটি আলাদা script এ কইরেন।

তো আজ এই পর্যন্তই কোনো সমস্যা থাকলে কমেন্ট এ বলুন।

THE END

S

o friends, that’s it for today. See you in another post. If you like the post then like and comment. Stay tuned to Trickbd.com for any updates.

Leave a Reply