Google sheet Apps script | Trang trắc nghiệm Quiz – Cập nhật câu hỏi, trả lời, thời gian đếm ngược

Giaoan.link chia sẻ đến các bạn một project về Google sheet Apps script “Trang trắc nghiệm Quiz – Cập nhật câu hỏi, trả lời, thời gian đếm ngược”. Những ưu điểm của bản Quiz câu hỏi trắc nghiệm này:

  • Có thời gian đếm ngược cho mỗi câu hỏi
  • Cập nhật câu hỏi, câu trả lời thông qua Google sheet một cách dễ dàng
  • Có tô xanh câu trả lời đúng, tô đỏ câu trả lời sai
  • Có tổng kết số câu đúng, sai và tỉ lệ % đúng.

Dưới đây là video hướng dẫn và code các trang. Bạn xem video để biết cách cấu hình và cập nhật câu hỏi, câu trả lời.

||Bạn truy cập vào đây để tìm thêm những project khác

Các project ngẫu nhiên:

Bạn truy cập link dưới để xem video hướng dẫn

Ở trang webapp thứ nhất để hiển thị trang làm bài

Code apps script trên trang “Code.gs”

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

function getQuestions() {
  var sheet = SpreadsheetApp.openById('1tRUcm6o5WOE5Lbcg5_EBFzAcRBZb4_ymvvsctEwlSQY').getSheetByName('Data');
  var data = sheet.getRange(1, 1, sheet.getLastRow(), 3).getValues();
  var questions = [];
  
  for (var i = 1; i < data.length; i++) {
    questions.push({
      question: "Câu " + i + ": " + data[i][0],
      options: data[i][1].split(','),
      correct: data[i][2]
    });
  }
   
  return questions;
}

Code apps script trên trang “Index.html”

<!DOCTYPE html>
<html>
  <head>
    <title>Quiz</title>
    <style>
      #quiz-container {
        font-family: Arial, sans-serif;
        width: 600px;        
        border: 1px solid grey;
        border-radius: 8px;
        box-shadow: 2px 2px 5px grey;
        margin-top: 100px;
        margin-left: auto;
        margin-right: auto;
        padding: 10px;
        
        }
      .question { 
        margin-bottom: 10px;
        font-weight: bold;
         }
      .input { margin: 5px; }
      .options{       
        margin: 5px; 
        }
      .correct { font-size:0.8em; color: green; font-weight: bold}
      .incorrect { font-size:0.8em;color: red; }
      .title-qiz{
        width: 70%;
        font-size: 1.5em;
        font-weight: bold;
        color: blue;
        text-align: center;        
      }
      .title-finish{
        width: 100%;
        margin-bottom: 20px;
        font-size: 1.5em;
        font-weight: bold;
        color: blue;
        text-align: center;  
        border-bottom: 1px solid grey;
      }

      .timer{
        width: 200px;
        color: red;
        font-size: 1.5em;
        font-weight: bold;
      }

      .div-flex{
        display: flex;
        gap: 20px;
        margin-bottom: 10px;
        border-bottom: 1px solid grey;
      }
      .btn-timer{       
        width: 150px;
        margin-top: 20px;
        margin-bottom: 15px;
        padding: 10px 10px;
        border: none;
        outline: none;
        border-radius: 5px;
        background-color: yellow;
        font-size: 1em;
        font-weight: bold;
        color: #000;
        box-shadow: 0 0 10px blue;
        transition: .5s;
        cursor: pointer;

      }
      .btn-timer:hover{
        box-shadow: none;
      }
      @media(max-width: 800px){
        #quiz-container{width: 100%;}
      }
    </style>
  </head>
  <body>
    <div id="quiz-container">
      <div class="div-flex">
        <div class="title-qiz">BÀI TRẮC NGHIỆM ONLINE</div>
        <div class="timer" id="timer">THỜI GIAN: <span id="time">30</span>s</div>
      </div>      
      <div id="question-container"></div> 
      <div id="result"></div>
      </div>
    </div>
    
    <script>
      let questions = [];
      let currentQuestionIndex = 0;
      let correctAnswers = 0;
      let timer;
      
      function fetchQuestions() {
        google.script.run.withSuccessHandler(displayQuestion).getQuestions();
      }
      
      function displayQuestion(questionsData) {
        questions = questionsData;
        showQuestion();
      }

      function showQuestion() {
        if (currentQuestionIndex < questions.length) {
          const questionData = questions[currentQuestionIndex];
          document.getElementById('question-container').innerHTML = `
            <div class="question">${questionData.question}</div>
            <div class="options">
              ${questionData.options.map(option => `<label><input type="radio" name="option" value="${option}">${option}</label><br>`).join('')}
            </div>
            <div style="text-align: center;">
            <button class="btn-timer" onclick="submitAnswer()">Gửi câu trả lời</button>
            </div>
          `;
          startTimer();
        } else {
          showResult();
        }
      }
      
      function startTimer() {
        let timeLeft = 30;
        document.getElementById('time').innerText = timeLeft;
        timer = setInterval(() => {
          timeLeft--;
          document.getElementById('time').innerText = timeLeft;
          if (timeLeft == 0) {
            clearInterval(timer);
            alert('Đã hết thời gian!');
            submitAnswer();
          }
        }, 1000);
      }

      function submitAnswer() {
        clearInterval(timer);
        const selectedOption = document.querySelector('input[name="option"]:checked');
        const correctOption = questions[currentQuestionIndex].correct;
        if (selectedOption) {
          if (selectedOption.value == correctOption) {
            correctAnswers++;
          }
          selectedOption.parentElement.classList.add(selectedOption.value == correctOption ? 'correct' : 'incorrect');
        }
        document.querySelector(`input[value="${correctOption}"]`).parentElement.classList.add('correct');
        setTimeout(nextQuestion, 2000);  // Give some time to show the correct answer
      }

      function nextQuestion() {
        currentQuestionIndex++;
        showQuestion();
      }

      function showResult() {
        document.getElementById('quiz-container').innerHTML = `
          <div class="title-finish">BẠN ĐÃ KẾT THÚC BÀI TRẮC NGHIỆM!</div>
          <div style="color: blue">Số câu đúng: ${correctAnswers}</div>
          <div style="color: red">Số câu sai: ${questions.length - correctAnswers}</div>
          <div>Tỉ lệ đạt: ${(correctAnswers / questions.length * 100).toFixed(2)}%</div>
        `;
      }

      window.onload = fetchQuestions;
    </script>
  </body>
</html>

Ở trang webapp thứ hai để hiển thị trang làm bài

Code trên trang “Code.gs”

function doGet() {
  return HtmlService.createHtmlOutputFromFile('Index');
}

Code trên trang “Index.html”

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <style>
      .container{
        border: 1px solid grey;
        border-radius: 10px;
        margin-left: auto;
        margin-right: auto;
        margin-top: 50px;
        width: 800px;
        text-align: center;
      }

      .title{
        font-family: "Poppins", sans-serif;
        font-size: 1.2em;
        font-weight: bold;        
        border-bottom: 1px solid blue;        
        color: blue;        
        margin: 20px;
      }

      .btn{
        font-size: 1em;
        font-weight: bold;
        border: 1px solid grey;
        border-radius: 10px;
        padding: 10px 15px;
        margin: 0px 0 15px;
        color: black;
        background-color: #fec706;
        box-shadow: 0 0 5px grey;
        letter-spacing: 1px;
        outline: none;
        transition: .5s;
        cursor: pointer;       
      }    

      a {
        text-decoration: none !important;
        color: black;
      }
    </style>

  </head>
  <body>
      <div class="container">
        <div class="title">BÀI TRẮC NGHIỆM GỒM 10 CÂU HỎI, BẠN CÓ <span style="color: red"> 30 GIÂY </span> ĐỂ HOÀN THÀNH 1 CÂU</div>
        <button class="btn" ><a href="https://script.google.com/macros/s/AKfycbwsCTEJ1CLkabMEvMiHhjhL8wDMcLPdPByP9CJM3M_gQ9Q3EoaXmuFQ6Sdd3qsxTFcuog/exec">BẮT ĐẦU LÀM BÀI</a></button>
      </div>

  </body>
</html>