Answers.Body: <p>Have you considered doing this in Twig instead? If your needs are complex, then a custom module in PHP might be best, but since you described it as a &quot;simple&quot; quiz, I'd probably go with Twig. Here's a fully functional example:</p>
  <pre class="lang-twig prettyprint-override"><code>{% set allQuestions = entry.quiz.all() %}
  &lt;form method=&quot;post&quot;&gt;
      {% for question in allQuestions %}
          &lt;h3&gt;{{ question.question }}&lt;/h3&gt;
          {% for answer in question.answers %}
              &lt;label for=&quot;answer-{{ question.id }}-{{ loop.index0 }}&quot;&gt;
                  &lt;input type=&quot;radio&quot; name=&quot;answers[{{ loop.parent.loop.index0 }}]&quot; value=&quot;{{ loop.index0 }}&quot; id=&quot;answer-{{ question.id }}-{{ loop.index0 }}&quot;&gt;
                  {{ answer.answer }}
              &lt;/label&gt;
          {% endfor %}
      {% endfor %}
      &lt;button&gt;Submit&lt;/button&gt;
  &lt;/form&gt;
  
  {% if craft.app.request.param('answers') %}
      {% set correctAnswersByQuestion = [] %}
      {% for question in allQuestions %}
          {% set correctAnswer = question.answers|map(answer =&gt; answer.correct ? true : false) %}
          {% set correctAnswersByQuestion = correctAnswersByQuestion|push(correctAnswer) %}
      {% endfor %}
  
      &lt;h2&gt;Results:&lt;/h2&gt;
      {% set totalCorrect = 0 %}
      {% for questionIndex, answerIndex in craft.app.request.param('answers') %}
          &lt;p&gt;Question {{ questionIndex+1 }} was {{ correctAnswersByQuestion[questionIndex][answerIndex] ? 'correct' : 'incorrect' }}&lt;/p&gt;
          {% set totalCorrect = correctAnswersByQuestion[questionIndex][answerIndex] ? totalCorrect+1 : totalCorrect %}
      {% endfor %}
  
      &lt;h2&gt;Score:&lt;/h2&gt;
      {{ totalCorrect/allQuestions|length * 100 }}%
  {% endif %}
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-02-23T00:15:23.100Z
Answers.Text: Thanks! I hadn't really considered it, but that's an amazing start. I did say simple, but I would like the quiz to evolve in the future; for example, saving results to a User's profile, and possibly text input fields rather than just radio inputs.
Answers.UserDisplayName: supazu
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-02-22T23:38:46.250Z
Answers.LastActivityDate: 2023-02-23T10:54:49.213Z
Answers.LastEditDate: 2023-02-23T10:54:49.213Z
Answers.UserDisplayName: James Smith
Body: <p>I'm trying to set up a simple quiz module. I'm using a Matrix field called <code>quiz</code>, with a plain text <code>question</code> field and an <code>answers</code> table field. In the table field, there's two columns, plain text <code>answer</code> and checkbox <code>correct</code>. See image:</p>
  <p><a href="https://i.sstatic.net/8DT4z.jpg" rel="nofollow noreferrer"><img src="https://i.sstatic.net/8DT4z.jpg" alt="enter image description here" /></a></p>
  <p>The idea being that there's only one correct answer.</p>
  <p><strong>EDIT:</strong>
  Using James' amazing code as a base, I've tried to get that into PHP and it's coming along ok. Still working on it...</p>
  <pre><code>$userAnswers = Craft::$app-&gt;getRequest()-&gt;getBodyParam('answers');
  $user = Craft::$app-&gt;getUser()-&gt;getIdentity();
  
  $allQuestions = $quiz-&gt;quizMatrix-&gt;all();
  $numberOfQuestions = count($allQuestions);
  
  $correctAnswersByQuestion = [];
  
  foreach ($allQuestions as $question) {
      $correctAnswer = array_map(function($answer) {
          return (bool)$answer['correct'];
      }, $question['answers']);
      $correctAnswersByQuestion[] = $correctAnswer;
  }
  
  $totalCorrect = 0;
  
  foreach ($userAnswers as $key =&gt; $value) {
      $questionIndex = $key;
      $answerIndex = $value;
      $isCorrect = $correctAnswersByQuestion[$questionIndex][$answerIndex];
      echo &quot;&lt;p&gt;Question &quot; . ($questionIndex+1) . &quot; was &quot; . ($isCorrect ? 'correct' : 'incorrect') . &quot;&lt;/p&gt;&quot;;
      $totalCorrect += $isCorrect ? 1 : 0;
  }
  
  $score = ($totalCorrect / $numberOfQuestions) * 100;
  $data = 'Your score is '.$score.'%';
  $response = Craft::$app-&gt;getResponse();
  $response-&gt;data = $data;
  return $response;
  
  </code></pre>
  
Tags: <modules>
Title: Creating a multiple choice quiz module
ThreadText: # Creating a multiple choice quiz module
  
  (Asked by: username_0 on 2023-02-22)
  
  I'm trying to set up a simple quiz module. I'm using a Matrix field called `quiz`, with a plain text `question` field and an `answers` table field. In the table field, there's two columns, plain text `answer` and checkbox `correct`. See image:
  
  [![enter image description here](https://i.sstatic.net/8DT4z.jpg)](https://i.sstatic.net/8DT4z.jpg)
  
  The idea being that there's only one correct answer.
  
  **EDIT:**
  Using username_1' amazing code as a base, I've tried to get that into PHP and it's coming along ok. Still working on it...
  
  ```
  $userAnswers = Craft::$app->getRequest()->getBodyParam('answers');
  $user = Craft::$app->getUser()->getIdentity();
  
  $allQuestions = $quiz->quizMatrix->all();
  $numberOfQuestions = count($allQuestions);
  
  $correctAnswersByQuestion = [];
  
  foreach ($allQuestions as $question) {
      $correctAnswer = array_map(function($answer) {
          return (bool)$answer['correct'];
      }, $question['answers']);
      $correctAnswersByQuestion[] = $correctAnswer;
  }
  
  $totalCorrect = 0;
  
  foreach ($userAnswers as $key => $value) {
      $questionIndex = $key;
      $answerIndex = $value;
      $isCorrect = $correctAnswersByQuestion[$questionIndex][$answerIndex];
      echo "<p>Question " . ($questionIndex+1) . " was " . ($isCorrect ? 'correct' : 'incorrect') . "</p>";
      $totalCorrect += $isCorrect ? 1 : 0;
  }
  
  $score = ($totalCorrect / $numberOfQuestions) * 100;
  $data = 'Your score is '.$score.'%';
  $response = Craft::$app->getResponse();
  $response->data = $data;
  return $response;
  
  ```
  
  **Tags:** modules
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2023-02-22. Score: 3 | Accepted answer
  
  Have you considered doing this in Twig instead? If your needs are complex, then a custom module in PHP might be best, but since you described it as a "simple" quiz, I'd probably go with Twig. Here's a fully functional example:
  
  ```twig
  {% set allQuestions = entry.quiz.all() %}
  <form method="post">
      {% for question in allQuestions %}
          <h3>{{ question.question }}</h3>
          {% for answer in question.answers %}
              <label for="answer-{{ question.id }}-{{ loop.index0 }}">
                  <input type="radio" name="answers[{{ loop.parent.loop.index0 }}]" value="{{ loop.index0 }}" id="answer-{{ question.id }}-{{ loop.index0 }}">
                  {{ answer.answer }}
              </label>
          {% endfor %}
      {% endfor %}
      <button>Submit</button>
  </form>
  
  {% if craft.app.request.param('answers') %}
      {% set correctAnswersByQuestion = [] %}
      {% for question in allQuestions %}
          {% set correctAnswer = question.answers|map(answer => answer.correct ? true : false) %}
          {% set correctAnswersByQuestion = correctAnswersByQuestion|push(correctAnswer) %}
      {% endfor %}
  
      <h2>Results:</h2>
      {% set totalCorrect = 0 %}
      {% for questionIndex, answerIndex in craft.app.request.param('answers') %}
          <p>Question {{ questionIndex+1 }} was {{ correctAnswersByQuestion[questionIndex][answerIndex] ? 'correct' : 'incorrect' }}</p>
          {% set totalCorrect = correctAnswersByQuestion[questionIndex][answerIndex] ? totalCorrect+1 : totalCorrect %}
      {% endfor %}
  
      <h2>Score:</h2>
      {{ totalCorrect/allQuestions|length * 100 }}%
  {% endif %}
  
  ```
  
  > **Comments:**
  > **username_0**: Thanks! I hadn't really considered it, but that's an amazing start. I did say simple, but I would like the quiz to evolve in the future; for example, saving results to a User's profile, and possibly text input fields rather than just radio inputs.  
  
  ---
  
  