Quiz creation JavaScript

56 Views Asked by At

I try to create one quiz page I'm passing data from the database I have attached the sample data also the key is similar in all the 3 databases the show element and hide elements are not working as expected but the start timer and displaying first question are doing correctly and I have basic CSS only. Kindly focus only on js to display only one question at a time what i want is 1)when the page loaded it have to get the first element of b 2)and get the time value of c and start the timer if timer ends it have to get the next element of b and start the timer 3)in d we are having the key and value when the page loaded it have to display the question it have to show only one question at a time that is only one value at a time

The sample data from data base

d={'BOT SEC A': [[1, '1', '1', '1', '1', '1', '1', '1', '11', '1'], [2, '2', '2', '2', '2', '2', '2', '2', '2', '2']], 'BOT SEC B': [[3, '3', '3', '3', '3', '3', '3', '3', '3', '3'], [4, '4', '4', '4', '4', '4', '4', '4', '4', '4']], 'CHE SEC A': [[13, '13', '13', '13', '13', '13', '13', '13', '13', '13'], [14, '14', '14', '14', '14', '14', '14', '14', '14', '14']], 'CHE SEC B': [[15, '15', '15', '15', '15', '15', '15', '15', '15', '15'], [16, '16', '16', '16', '16', '16', '16', '16', '16', '16']], 'PHY SEC A': [[9, '9', '9', '9', '9', '9', '9', '9', '9', '9'], [10, '10', '10', '10', '10', '10', '10', '10', '10', '10']], 'PHY SEC B': [[11, '11', '11', '11', '11', '11', '11', '11', '11', '11'], [12, '12', '12', '12', '12', '12', '12', '12', '12', '12']], 'ZOO SEC A': [[5, '5', '5', '5', '5', '5', '5', '5', '5', '5'], [6, '6', '6', '6', '6', '6', '6', '6', '6', '6']], 'ZOO SEC B': [[7, '7', '7', '7', '7', '7', '7', '7', '7', '7'], [8, '8', '8', '8', '8', '8', '8', '8', '8', '8']]}//question_with_section 

        questions_with_sections = {}

        for section_name, question_ids in questionpaper.items():
            section_questions = []
            for question_id in question_ids:
                try:
                    question = Question.objects.get(id=question_id)
                    question_data = [
                        question.id,
                        question.question_name,  # Use the actual field containing the question text
                        question.option_1,
                        question.option_2,
                        question.option_3,
                        question.option_4,
                        question.option_5,
                        question.option_6,
                        question.option_7,
                        question.option_8,
                    ]
                    section_questions.append(question_data)
                except Question.DoesNotExist:
                    #print(f"Question with ID {question_id} not found.")
                    section_questions.append({'question_text': 'Question not found'})

            questions_with_sections[section_name] = section_questions

b=['CHE SEC B', 'CHE SEC A', 'PHY SEC A', 'PHY SEC B', 'ZOO SEC B', 'ZOO SEC A', 'BOT SEC B', 'BOT SEC A']//subject names 
c={'BOT SEC A': 61, 'BOT SEC B': 61, 'ZOO SEC A': 61, 'ZOO SEC B': 61, 'PHY SEC A': 61, 'PHY SEC B': 61, 'CHE SEC A': 61, 'CHE SEC B': 61}  // time for each sections to attend   




The code

<!DOCTYPE html>
<html lang="en">


<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    body {
      margin: 0;
      padding: 0;
      display: flex;
      transition: background-color 1s;
    }
    
    #div1,
    #div2,
    #div3,
    #div4,
    #questionDiv {
      border: 1px solid #000;
      margin: 10px;
      padding: 10px;
    }
    
    .numberBox {
      border: 1px solid #000;
      width: 30px;
      height: 30px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      margin: 5px;
      cursor: pointer;
    }
    
    #questionDiv button {
      margin: 5px;
    }
  </style>
</head>


<body>


  <div id="div1">
    <!-- Append keys from B dynamically using JavaScript -->
  </div>
  <div id="div2">
    <!-- Content will be dynamically populated by JavaScript -->
    <button onclick="sectionend()">SECTIONSUBMIT</button>
  </div>
  <div id="div3">
    <!-- Timer will be displayed here -->
    <h1 id="timerDisplay">Time Remaining: 0 seconds</h1>
    <button onclick="sectionend()">SECTIONSUBMIT</button>
  </div>
  <div id="div4">
    <button id="markForReview" onclick="markForReview()">Mark for Review</button>
    <br>
    <button onclick="saveAndNext()">Save & Next</button>
    <br>
    <button onclick="clearResponse()">Clear Response</button>
    <br>
    <button onclick="submit()">Submit</button>
  </div>
  <div id="questionDiv1">
    <form method="POST" action="{% url 'submit_exam' %}">
      {% csrf_token %}
      <input type="hidden" name="examname" value="{{ exam }}">
      <div id="questionDiv"></div>
      <button>submit</button>
    </form>
    <!-- Question will be dynamically populated by JavaScript -->
  </div>


  <script>
    // Sample data
    const D = {
      {
        questions_with_sections | safe
      }
    };
    const B = {
      {
        ordered_sections | safe
      }
    };
    const C = {
      {
        timing_data_dict | safe
      }
    };


    let currentKeyIndex = 0;
    let timerSeconds = parseInt(C[B[currentKeyIndex]]);
    const selectedOptions = {};


    function populateDiv1() {
      const div1 = document.getElementById('div1');
      B.forEach(key => {
        const button = document.createElement('button');
        button.textContent = key;
        button.addEventListener('click', () => showKeyValues(key));
        div1.appendChild(button);
      });
    }


    function showKeyValues(key) {
      if (key === B[currentKeyIndex]) {
        const div2 = document.getElementById('div2');
        div2.innerHTML = '';
        const value = D[key];
        if (value) {
          for (let i = 0; i < value.length; i++) {
            const numberBox = document.createElement('div');
            numberBox.className = `numberBox ${key}-${i}`;
            numberBox.textContent = i + 1;
            numberBox.addEventListener('click', () => takeDivKey(key, i + 1));
            div2.appendChild(numberBox);
          }
        }
        startTimer();
      }
    }


    function startTimer() {
      const timerDisplay = document.getElementById('timerDisplay');


      const timer = setInterval(() => {
        timerSeconds--;


        if (timerSeconds <= 0) {
          clearInterval(timer);
          switchKey();
        } else {
          timerDisplay.textContent = `Time Remaining: ${timerSeconds} seconds`;
        }
      }, 1000);
    }



    function switchKey() {
      if (currentKeyIndex < B.length - 1) {
        currentKeyIndex++;
        timerSeconds = parseInt(C[B[currentKeyIndex]]);
        showKeyValues(B[currentKeyIndex]);
        takeDivKey(B[currentKeyIndex], 1);
        startTimer();
      } else {
        document.body.style.backgroundColor = "red";
      }
    }

    function takeDivKey(key, value) {
      const questionDiv = document.getElementById('questionDiv');
      const totalQuestionsForCurrentKey = D[key].length;
      hideElements(questionDiv);
      createFunction(key, value);
    }

    // Function to hide elements
    function hideElements(questionDiv) {
      //alert("hide called")
      const radioContainer = questionDiv.querySelector('.radio-container');
      const previousParagraph = questionDiv.querySelector('.question-text');
      //alert(radioContainer)
      //alert(previousParagraph)
      // Check if the elements exist before attempting to hide them
      if (radioContainer) {
        radioContainer.style.display = 'none';
        //alert("radio hidden")
      }
      if (previousParagraph) {
        previousParagraph.style.display = 'none';
        //alert("paragraph hidden")
      }
    }
    // Function to create new elements
    function createFunction(key, value) {
      const questionDiv = document.getElementById('questionDiv');
      const questionArray = D[key][value - 1];
      const questionText = questionArray[1];
      const options = questionArray.slice(2);
      // Show the current question
      const questionTextElement = document.createElement('text'); // Change from 'p' to 'div'
      questionTextElement.className = 'question-text';
      // Create a container for radio buttons
      const newRadioContainer = document.createElement('div');
      newRadioContainer.className = 'radio-container';
      options.forEach(option => {
        const label = document.createElement('label');
        const radio = document.createElement('input');
        radio.type = 'radio';
        radio.name = `question${questionArray[0]}`;
        radio.value = option;
        label.appendChild(radio);
        // Create a span for each option text
        const optionTextContainer = document.createElement('span');
        optionTextContainer.appendChild(document.createTextNode(option));
        label.appendChild(optionTextContainer);
        newRadioContainer.appendChild(label);
        // Check if the current option is the selected one
        if (selectedOptions[key] === option) {
          radio.checked = true;
        }
        radio.addEventListener('change', () => {
          selectedOptions[key] = option;
          handleRadioButtonChange();
        });
      });
      // Append the new container to the questionDiv
      questionDiv.appendChild(questionTextElement);
      questionTextElement.appendChild(newRadioContainer);
    }


    // Function to show elements
    function showElements(questionDiv) {
      const radioContainer = questionDiv.querySelector('.radio-container');
      const previousParagraph = questionDiv.querySelector('.question-text');

      // Check if the elements exist before attempting to display them
      if (radioContainer) {
        radioContainer.style.display = 'block';
      }
      if (previousParagraph) {
        previousParagraph.style.display = 'block';
      }
    }



    function markForReview() {
      const currentKey = B[currentKeyIndex];
      const questionDiv = document.getElementById('questionDiv');
      const selectedRadioButton = questionDiv.querySelector('input[name^="question"]:checked');
      const numberBoxes = document.getElementsByClassName('numberBox');


      if (selectedRadioButton) {
        const questionIndex = parseInt(selectedRadioButton.name.replace('question', ''), 10) - 1;
        const currentNumberBox = numberBoxes[questionIndex];
        currentNumberBox.style.backgroundColor = 'violet';
        currentNumberBox.innerHTML = '✔';
        switchToNextQuestion();
      } else {
        const currentNumberBox = numberBoxes[currentKeyIndex];
        currentNumberBox.style.backgroundColor = 'red';
        switchToNextQuestion();
      }
    }


    function saveAndNext() {
      switchToNextQuestion();
    }


    function clearMarkedForReview() {
      const currentKey = B[currentKeyIndex];
      const questionDiv = document.getElementById('questionDiv');
      const selectedRadioButton = questionDiv.querySelector('input[name^="question"]:checked');


      if (selectedRadioButton) {
        const questionIndex = parseInt(selectedRadioButton.name.replace('question', ''), 10) - 1;
        const numberBoxes = document.getElementsByClassName('numberBox');


        const currentNumberBox = numberBoxes[questionIndex];
        currentNumberBox.style.backgroundColor = '';
        currentNumberBox.innerHTML = '';
      }
    }


    function switchToNextQuestion() {
      const currentKey = B[currentKeyIndex];
      const questionDiv = document.getElementById('questionDiv');
      const selectedRadioButton = questionDiv.querySelector('input[name^="question"]');


      const questionIndex = parseInt(selectedRadioButton.name.replace('question', ''), 10);
      // const currentQuestionID = D[currentKey][questionIndex];
      alert(questionIndex)
      let nextQuestionIndex = -1;


      for (let i = 0; i < D[currentKey].length; i++) {
        if (D[currentKey][i][0] === questionIndex) {
          nextQuestionIndex = (i + 1);
          alert(nextQuestionIndex)
          alert(D[currentKey].length)
          break;
        }
      }


      if ((nextQuestionIndex !== -1) && (nextQuestionIndex < D[currentKey].length)) {
        takeDivKey(currentKey, (nextQuestionIndex + 1));
        handleRadioButtonChange();
      } else {
        handleRadioButtonChange(selectedRadioButton);
        alert("Wait for the timer to end or move to the next key");
        handleRadioButtonChange();
      }
    }


    function sectionend() {
      switchKey();
    }


    function clearResponse() {
      const questionDiv = document.getElementById('questionDiv');
      const selectedRadioButton = questionDiv.querySelector('input[name^="question"]:checked');


      if (selectedRadioButton) {
        selectedRadioButton.checked = false;
        clearMarkedForReview();
        handleRadioButtonChange(selectedRadioButton);
      }
    }


    function submit() {
      alert("Submitted");
    }


    function sectionSubmit() {
      switchKey();
    }


    function handleRadioButtonChange() {
      const currentKey = B[currentKeyIndex];
      const questionDiv = document.getElementById('questionDiv');
      const numberBoxes = document.getElementsByClassName('numberBox');


      const checkedRadioButton = document.querySelector('input[type="radio"]:checked');


      if (checkedRadioButton) {
        const questionIndex = parseInt(checkedRadioButton.name.replace('question', ''), 10);
        let nextQuestionIndex = -1;


        for (let i = 0; i < D[currentKey].length; i++) {
          if (D[currentKey][i][0] === questionIndex) {
            nextQuestionIndex = i;
            break;
          }
        }


        if (nextQuestionIndex !== -1) {
          const currentNumberBox = numberBoxes[nextQuestionIndex];


          if (currentNumberBox) {
            currentNumberBox.style.backgroundColor = 'green';


            const selectedOption = checkedRadioButton.value;
            //alert(selectedOption);
            selectedOptions[currentKey] = selectedOption;
          }
        }
      } else {
        const currentNumberBox = numberBoxes[currentKeyIndex];
        if (currentNumberBox) {
          currentNumberBox.style.backgroundColor = 'red';
        }
      }
    }


    populateDiv1();
    showKeyValues(B[0]);
    takeDivKey(B[0], 1);
  </script>
</body>


</html>

0

There are 0 best solutions below