How to Create a Self-Assessment Questionnaire with Graded Options

Building engaging and interactive learning tools doesn’t always require complex integrations with a Learning Management System (LMS). Sometimes, a simple, client-side self-assessment is all you need. This post will walk you through creating a self-assessment questionnaire using a bit of HTML and JavaScript, allowing users to immediately see their results based on weighted answers. This approach is perfect for quick quizzes, personal reflection tools, or any scenario where instant, private feedback is desired.

What We’re Building

Imagine a questionnaire where each question has multiple-choice answers, but unlike a typical multiple-choice quiz, each answer carries a different score. For example, “Never,” “Sometimes,” and “Always” could be options, with “Never” scoring 1 point, “Sometimes” 2 points, and “Always” 3 points. The user selects an option for each question, clicks “Check,” and instantly sees their total score. There’s also a “Reset” button to clear their choices.

The HTML Structure

Our questionnaire is built around a simple HTML <table>. Each question resides in its own table row (<tr>). Inside each row, we’ll have the question itself and then a set of radio buttons for the answer options.

The key to making this work is how we name our radio buttons:

<table>
  <thead>
    <tr>
      <th>Question</th>
      <th>Never</th>
      <th>Sometimes</th>
      <th>Always</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Do you exercise every day?</td>
      <td><input type="radio" name="R1" value="1"></td>
      <td><input type="radio" name="R1" value="2"></td>
      <td><input type="radio" name="R1" value="3"></td>
    </tr>
    <tr>
      <td>Do you brush your teeth every day?</td>
      <td><input type="radio" name="R2" value="1"></td>
      <td><input type="radio" name="R2" value="2"></td>
      <td><input type="radio" name="R2" value="3"></td>
    </tr>
    <!-- Add more questions here, incrementing the "name" attribute (e.g., R3, R4) -->
  </tbody>
</table>
<button id="ri-check">Check</button>
<button id="ri-reset">Reset</button>
<div id="ri-score"></div>Code language: HTML, XML (xml)

Important Notes:

  • name Attribute: Notice how all radio buttons within a single row share the same name attribute (e.g., “R1” for the first question, “R2” for the second). This ensures that only one option can be selected per question.
  • value Attribute: Each radio button has a value attribute. This is where you define the score for that specific option. You can set these values to anything you like.
  • IDs: We’ll use unique IDs for our “Check” and “Reset” buttons (ri-check, ri-reset) and for the div where the score will be displayed (ri-score).

The JavaScript Logic

The JavaScript handles the interactivity: calculating the score and resetting the form.let m = 0; // Our global variable to store the total score.

// This function ensures the DOM is fully loaded before running our script
function doReady() {
    // Event listener for the "Reset" button
    document.getElementById('ri-reset').addEventListener('click', R_reset);
    // Event listener for the "Check" button
    document.getElementById('ri-check').addEventListener('click', R_check);
}
// Function to reset the questionnaire
function R_reset() {
    m = 0; // Reset the score
    const activityContainer = document.getElementById('r-activity'); // Assuming your table/questions are inside an element with ID 'r-activity'
    const inputs = activityContainer.getElementsByTagName('input');
    for (let i = 0; i < inputs.length; i++) {
        inputs[i].checked = false; // Uncheck all radio buttons
    }
    document.getElementById('ri-score').innerHTML = ''; // Clear the score display
}
// Function to calculate and display the score
function R_check() {
    m = 0; // Reset score before recalculating
    // Get the value for each question (R1, R2, R3, etc.)
    // We check if an option is selected before getting its value to prevent errors
    if (document.querySelector('input[name="R1"]:checked')) {
        m += parseInt(document.querySelector('input[name="R1"]:checked').value);
    }
    if (document.querySelector('input[name="R2"]:checked')) {
        m += parseInt(document.querySelector('input[name="R2"]:checked').value);
    }
    // Repeat for R3, R4, R5, and any additional questions you add
    // Display the final score
    document.getElementById('ri-score').innerHTML = 'Score: ' + m;
}
// Call doReady when the document is loaded
document.addEventListener('DOMContentLoaded', doReady);Code language: JavaScript (javascript)

JavaScript Explanation:

  1. m = 0;: This variable will hold our running total score.
  2. doReady(): This function is crucial. It ensures that the HTML elements (like our buttons) are fully loaded onto the page before we try to attach event listeners to them. If we try to attach a listener to an element that doesn’t exist yet, it will cause an error.
  3. R_reset():
    • Sets m back to 0.
    • Finds all input elements within your activity container (you’ll need to wrap your table and buttons in a div with an ID like r-activity).
    • Loops through them and sets their checked property to false, effectively unselecting all radio buttons.
    • Clears the displayed score.
  4. R_check():
    • Resets m to 0 at the beginning of each calculation.
    • For each question (e.g., “R1,” “R2″), it uses document.querySelector(‘input[name=”R1”]:checked’) to find the selected radio button for that group.
    • It checks if a radio button was actually selected (if (document.querySelector(…))) to prevent errors if a question was skipped.
    • If selected, it retrieves the value of the chosen option, converts it to an integer using parseInt(), and adds it to our total m.
    • Finally, it updates the innerHTML of the ri-score div to display the calculated score.
  5. document.addEventListener(‘DOMContentLoaded’, doReady);: This line makes sure our doReady function runs as soon as the entire HTML document is loaded and parsed.

Extending Your Questionnaire

Adding more questions is straightforward:

  1. HTML: Copy an existing <tr> in your HTML, paste it, and increment the name attribute for the radio buttons (e.g., from R5 to R6). Remember to also change the question text and value attributes if desired.
  2. JavaScript: In the R_check() function, add another if block for the new question’s name attribute (e.g., if (document.querySelector(‘input[name=”R6″]:checked’)) { … }).

Conclusion

This simple yet effective self-assessment questionnaire provides immediate feedback without needing a server-side component. It’s a fantastic way to create interactive learning experiences directly within your web pages. Feel free to customize the questions, answer options, and scoring values to suit your specific needs! If you have any questions or run into issues, don’t hesitate to leave a comment below.