Submit button not working in J S radio button quiz

Hi,
I have this javascript script (below) and the submit button doesn’t give the results of the test. The reset button seems to be working correctly. I’m wondering if some of the coding might be deprecated. Would you have any idea of the the solution? Thanks

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">

   <title>Clases particulares de ingl&eacute;s </title>
   <link rel="shortcut icon" 
href="http://www.profesornativo.com/favicon.ico?v=2" >
    <meta name="viewport" content="width=device-width, 
initial-scale=1.0" >
        <meta name="robots" content="index, follow">
   <meta name="description" content="">
<meta name="author" content="" >

<meta name="keywords" content="">

    <style>
      ol li {
	background-image: none;
        padding:10px;
      }
    </style>
   <link rel='stylesheet' type='text/css' href='nativo.css' >
 <script type="text/javascript" 
src="http://code.jquery.com/jquery-1.9.1.js"></script>
  </head>

  <body>
    <div id="pagewrap">
      <div id="container">
        <div id="content">
                          <h4>Select the correct  sentence.  </h4>
          <div class="information">
           <form method="post" autocomplete="off">
        <div class="question"><table> <tr><td class="do">
        <strong> 1:</strong><br> </td><td>     

        <label> <input type="radio" name="one" value="a"> Do you seen 
the 
match yesterday?</label>   <br>
        <label> <input type="radio" name="one" value="b"> Did you saw 
the match yesterday?</label> <br>
        <label> <input type="radio" name="one" value="c"> Did you see 
the match yesterday?  </label> </td> </tr> </table>
              
      </div>

      <div class="question"><table> <tr><td class="do">
        <strong> 2:</strong><br> </td><td>     

        <label><input type="radio" name="two" value="a">  Where you 
lived when you were a child?</label>  <br>
        <label><input type="radio" name="two" value="b" > Where did you 
live when you were a child? </label>  <br>
        <label><input type="radio" name="two" value="c">  Where you did 
live when you were a child? </label> </td> </tr> </table>
        
      </div>
      
      <div class="question"><table> <tr><td class="do">
        <strong>3:</strong><br> </td><td>     

        <label><input type="radio" name="three" value="a">  I don't live 
in Barcelona now.  </label>   <br>
        <label><input type="radio" name="three" value="b">  I doesn't 
live in Barcelona now. </label>  <br>
        <label><input type="radio" name="three" value="c"> I no live in 
Barcelona now.  </label> </td> </tr> </table>
        
      </div>
      
      <div class="question"><table> <tr><td class="do">
        <strong> 4:</strong><br> </td><td>     
                                                          
        <label><input type="radio" name="four" value="a">  He don't want  
to buy a new smartphone.</label>  <br>
        <label><input type="radio" name="four" value="b"> He doesn't 
want buy a new smartphone.</label>       <br>
        <label><input type="radio" name="four" value="c"> He doesn't 
want to buy a new smartphone. </label>  </td> </tr> </table>
         <div class="question">                                                                               
      </div>
      </div>
      
      <div class="question"><table> <tr><td class="do">
        <strong> 5:</strong><br> </td><td>      

        <label><input type="radio" name="five" value="a"> We don't like 
football. </label> <br>
        <label><input type="radio" name="five" value="b"> We not like 
football.</label>  <br>
        <label><input type="radio" name="five" value="c"> We like not 
football.</label>  </tr> </table>
 
      </div>
      
      <div class="question"><table> <tr><td class="do">
        <strong> 6:</strong><br> </td><td>       

        <label><input type="radio" name="six" value="a"> She don't work 
here now.  </label>  <br>
        <label><input type="radio" name="six" value="b"> She doesn't 
work here now. </label> <br>
        <label><input type="radio" name="six" value="c">  She not work 
here now.</label> </td> </tr> </table>
    
      </div>
       <div class="question"><table> <tr><td class="do">
        <strong> 7:</strong><br> </td><td>      

        <label><input type="radio" name="seven" value="a"> Do your 
sister work in a bank?   </label>  <br>
        <label><input type="radio" name="seven" value="b"> Your sister 
does work in a bank?She doesn't work here now. </label> <br>
        <label><input type="radio" name="seven" value="c"> Does your 
sister work in a bank?</label> </td> </tr> </table>
      
      </div>
       <div class="question"><table> <tr><td class="do">
        <strong> 8:</strong><br> </td><td>     

        <label><input type="radio" name="eight" value="a"> What do your 
brother do?  </label>  <br>
        <label><input type="radio" name="eight" value="b">  What your 
brother does? </label> <br>
        <label><input type="radio" name="eight" value="c">  What does 
your brother do?</label> </td> </tr> </table>
             
      </div>
       <div class="question"><table> <tr><td class="do">
        <strong> 9:</strong><br> </td><td>      

        <label><input type="radio" name="nine" value="a"> What kind of 
music they do like?   </label>  <br>
        <label><input type="radio" name="nine" value="b">  What kind of 
music does they like?</label> <br>
        <label><input type="radio" name="nine" value="c">  What kind of 
music do they like?</label> </td> </tr> </table>
          
      </div>
      <div class="question"><table> <tr><td class="do">
        <strong> 10:</strong><br> </td><td>
      
        <label><input type="radio" name="ten" value="a"> When did she  
decide to emigrate? </label>  <br>
        <label><input type="radio" name="ten" value="b"> When she 
decided to emigrate? </label> <br>
        <label><input type="radio" name="ten" value="c">  When she did 
decide to emigrate? </label> </td> </tr> </table>
       
      </div>

               <div id="score"></div>    
            <div class="buttons">         
             <input type="submit" id="submit" value="Submit">
              <input type="reset" class="reset" id="reset" name="reset" 
value="Reset">  
                   </div>                                   
    </form>  
                </div> 
                </div>
                </div>
                </div>

 
    <script>
     /*global $:false */
  function clearAnswerImages(){
        $("img").remove();
}

       function mark(el, status){
        var images = {
          correct: "http://www.profesornativo.com/tick.jpg",
          incorrect: "http://www.profesornativo.com/x.jpg",
          unanswered: "http://www.profesornativo.com/q.jpg",
        }, 
        img = new Image();
        img.src = images[status];
        img.className = status;
        el.append(img);
      }

      function displayScore(){
        var numQuestions = $(".question").length,
            questionsCorrect = $("img.correct").length;

     $("#score").html("You got " + questionsCorrect + " out of " + 
numQuestions);
      }

      $("form").on("submit", function(e){
        e.preventDefault();
        clearAnswerImages(); 

       var $questions = $(".question");
        $questions.each(function(){
          var answer = $(this).find("input:checked"),
              key = answer.attr("name"),
              val = answer.attr("value");

          if(answer.length === 0){ 
            mark($(this).find("p"), "unanswered");
          } else if (answers[key] !== val){
            mark(answer.parent(), "incorrect");   // I  changed this 
line
          } else {
            mark(answer.parent(), "correct");
          } 
        });

        displayScore();
      });

     $("input[type=reset]").on("click", function(){
  $("input:checked").prop("checked", false);
  $('#score').empty(); //I inserted this line      
  clearAnswerImages(); 
});

       var answers = { 
        "one": "c",
        "two": "b", 
        "three": "a",
        "four": "c",
        "five": "a",
        "six": "b",
        "seven": "c",
        "eight": "c",
        "nine": "c",
        "ten": "a",
                                                
      }; 
    </script>
  </body>
</html>
1 Like

Works for me, once you remove the linebreak where you wrote “I changed this line”.

(Though it thinks there’s 11 questions because you’ve got an empty question div in there…)

Thanks. I tried that idea of removing the line break at “I changed this line”, but I have the same problem. I must be doing something else wrong? Below is the current code after making some changes.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Clases particulares de ingl&eacute;s </title>
    <link rel="shortcut icon" href="http://www.profesornativo.com/favicon.ico?v=2">
    <meta name="viewport" content="width=device-width, 
initial-scale=1.0">
    <meta name="robots" content="index, follow">
    <meta name="description" content="">
    <meta name="author" content="">
    <meta name="keywords" content="">
    <style>
      ol li {
        background-image: none;
        padding: 10px;
      }
    </style>
    <link rel='stylesheet' type='text/css' href='nativo.css'>
  </head>
  <body>
    <div id="pagewrap">
      <div id="container">
        <div id="content">
          <h4>Select the correct sentence. </h4>
          <div class="information">
            <form method="post" autocomplete="off">
              <div class="question">
                <table>
                  <tr>
                    <td class="do">
                      <strong> 1:</strong>
                      <br>
                    </td>
                    <td> &nbsp; <label>
                        <input type="radio" name="one" value="a"> Do you seen the match yesterday? </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="one" value="b"> Did you saw he match yesterday? </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="one" value="c"> Did you see the match yesterday? </label>
                    </td>
                  </tr>
                </table>
              </div>
              <div class="question">
                <table>
                  <tr>
                    <td class="do">
                      <strong> 2:</strong>
                      <br>
                    </td>
                    <td> &nbsp; <label>
                        <input type="radio" name="two" value="a"> Where you lived when you ere a child? </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="two" value="b"> Where did you live when you were a child? </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="two" value="c"> Where you did live when you were a child? </label>
                    </td>
                  </tr>
                </table>
              </div>
              <div class="question">
                <table>
                  <tr>
                    <td class="do">
                      <strong>3:</strong>
                      <br>
                    </td>
                    <td> &nbsp; <label>
                        <input type="radio" name="three" value="a"> I don't live in Barcelona now. </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="three" value="b"> I doesn't live in Barcelona now. </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="three" value="c"> I no live in Barcelona now. </label>
                    </td>
                  </tr>
                </table>
              </div>
              <div class="question">
                <table>
                  <tr>
                    <td class="do">
                      <strong> 4:</strong>
                      <br>
                    </td>
                    <td> &nbsp; <label>
                        <input type="radio" name="four" value="a"> He don't want to buy a new smartphone. </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="four" value="b"> He doesn't want uy a new smartphone. </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="four" value="c"> He doesn't want to buy a new smartphone. </label>
                    </td>
                  </tr>
                </table>
                <div class="question"></div>
              </div>
              <div class="question">
                <table>
                  <tr>
                    <td class="do">
                      <strong> 5:</strong>
                      <br>
                    </td>
                    <td> &nbsp; <label>
                        <input type="radio" name="five" value="a"> We don't like football. </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="five" value="b"> We not like football. </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="five" value="c"> We like not football. </label>
                  </tr>
                </table>
              </div>
              <div class="question">
                <table>
                  <tr>
                    <td class="do">
                      <strong> 6:</strong>
                      <br>
                    </td>
                    <td> &nbsp; <label>
                        <input type="radio" name="six" value="a"> She don't work here now. </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="six" value="b"> She doesn't work here now. </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="six" value="c"> She not work here now. </label>
                    </td>
                  </tr>
                </table>
              </div>
              <div class="question">
                <table>
                  <tr>
                    <td class="do">
                      <strong> 7:</strong>
                      <br>
                    </td>
                    <td> &nbsp; <label>
                        <input type="radio" name="seven" value="a"> Do your sister work in a bank? </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="seven" value="b"> Your sister does work in a bank? She doesn't work here now. </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="seven" value="c"> Does your sister work in a bank? </label>
                    </td>
                  </tr>
                </table>
              </div>
              <div class="question">
                <table>
                  <tr>
                    <td class="do">
                      <strong> 8:</strong>
                      <br>
                    </td>
                    <td> &nbsp; <label>
                        <input type="radio" name="eight" value="a"> What do your brother do? </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="eight" value="b"> What your brother does? </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="eight" value="c"> What does your brother do? </label>
                    </td>
                  </tr>
                </table>
              </div>
              <div class="question">
                <table>
                  <tr>
                    <td class="do">
                      <strong> 9:</strong>
                      <br>
                    </td>
                    <td> &nbsp; <label>
                        <input type="radio" name="nine" value="a"> What kind of music they do like? </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="nine" value="b"> What kind of music does they like? </label>
                      <br> &nbsp; <label>
                        <input type="radio" name="nine" value="c"> What kind of music do they like? </label>
                    </td>
                  </tr>
                </table>
              </div>
              <div class="question">
                <table>
                  <tr>
                    <td class="do">
                      <strong> 10:</strong>
                      <br>
                    </td>
                    <td>
                      <label>
                        <input type="radio" name="ten" value="a"> When did she decide to emigrate? </label>
                      <br>
                      <label>
                        <input type="radio" name="ten" value="b"> When she decided to emigrate? </label>
                      <br>
                      <label>
                        <input type="radio" name="ten" value="c"> When she did decide to hemigrate? </label>
                    </td>
                  </tr>
                </table>
              </div>
              <div id="score"></div>
              <div class="buttons">
                <input type="submit" id="submit" value="Submit">
                <input type="reset" class="reset" id="reset" name="reset" value="Reset">
              </div>
            </form>
          </div>
          <div class="address"></div>
        </div>
      </div>
    </div>
    <script>
      /*global $:false */
      function clearAnswerImages() {
        $("img").remove();
      }

      function mark(el, status) {
        var images = {
            correct: "http://www.profesornativo.com/tick.jpg",
            incorrect: "http://www.profesornativo.com/x.jpg",
            unanswered: "http://www.profesornativo.com/q.jpg",
          },
          img = new Image();
        img.src = images[status];
        img.className = status;
        el.append(img);
      }

      function displayScore() {
        var numQuestions = $(".question").length,
          questionsCorrect = $("img.correct").length;
        $("#score").html("You got " + questionsCorrect + " out of " + numQuestions);
      }
      $("form").on("submit", function(e) {
        e.preventDefault();
        clearAnswerImages();
        var $questions = $(".question");
        $questions.each(function() {
          var answer = $(this).find("input:checked"),
            key = answer.attr("name"),
            val = answer.attr("value");
          if (answer.length === 0) {
            mark($(this).find("p"), "unanswered");
          } else if (answers[key] !== val) {
            mark(answer.parent(), "incorrect"); //line changed
          } else {
            mark(answer.parent(), "correct");
          }
        });
        displayScore();
      });
      $("input[type=reset]").on("click", function() {
        $("input:checked").prop("checked", false);
        $('#score').empty(); //I inserted this line      
        clearAnswerImages();
      });
      var answers = {
        "one": "c",
        "two": "b",
        "three": "a",
        "four": "c",
        "five": "a",
        "six": "b",
        "seven": "c",
        "eight": "c",
        "nine": "c",
        "ten": "a",
      };
    </script>
  </body>
</html>

so when you click the button, what happens? Does the console say anything?

When I select an answer of, say, question 2 and scroll down to click Submit, the page returns to the top, and the radio button I clicked gets cleared, so the submit buttons acts more like a reset button.

Where’s the link to jQuery gone?

There ia a jquery line is in the javascript section, just after the last closing div.

Maybe the below page might shed more light. It’s code from a different page in my site, but I think basically similar javascript. This page doesn’t work either. When, for example, I select 2a in question 2, the address bar shows, added to the name of the website:
?two=a
And if I select answers from 1 to 5 (the address bar shows the answers I selected, some being correct and others incorrect, as folows:
one=c&two=b&three=a&four=a&five=b. (again, added to the name of my website.)

I hope all that isn’t too confusing. Thanks. Below is the code that shows the above errors.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Clases particulares de ingles </title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="robots" content="index, follow" />
    <meta name="description" content=" ." />
    <meta name="author" content=" " />
    <style>
      ol li {
        background-image: none;
        padding: 10px;
      }
    </style>
    <link rel='stylesheet' type='text/css' href='http://www.profesornativo.com/nativo.css' />
  </head>
  <body>
    <div id="pagewrap">
      <div id="container">
        <div id="content">
          <h1 class="h1-home">Idioms 2 </h1>
          <h4>Match the sentences in bold with the corresponding idioms. </h4>
          <div class="scroll">
            <form>
              <div class="question">
                <strong> 1: They succeeded in spite of many difficulties. </strong>
                <br />
                <label>
                  <input type="radio" name="one" value="a"> They succeeded in the odds </label>
                <br />
                <label>
                  <input type="radio" name="one" value="b"> They succeeded over the adds. </label>
                <br />
                <label>
                  <input type="radio" name="one" value="c"> They succeeded against the odds. </label>
              </div>
              <div class="question">
                <p>
                  <strong> 2: The advantages and disadvantages.</strong>
                  <br />
                  <label>
                    <input type="radio" name="two" value="a"> The fors and againsts. </label>
                  <br />
                  <label>
                    <input type="radio" name="two" value="b"> The pros and cons. </label>
                  <br />
                  <label>
                    <input type="radio" name="two" value="c"> The pros and antis. </label>
              </div>
              <div class="question">
                <p>
                  <strong> 3: He reconsidered. </strong>
                  <br />
                  <label>
                    <input type="radio" name="three" value="a"> He had different opinions. </label>
                  <br />
                  <label>
                    <input type="radio" name="three" value="b"> He had another thought. </label>
                  <br />
                  <label>
                    <input type="radio" name="three" value="c"> He had second thoughts. </label>
              </div>
              <div class="question">
                <p>
                  <strong> 4: He is recovering from the flu. </strong>
                  <br />
                  <label>
                    <input type="radio" name="four" value="a"> He's on the fiddle. </label>
                  <br />
                  <label>
                    <input type="radio" name="four" value="b"> He's on the mend. </label>
                  <br />
                  <label>
                    <input type="radio" name="four" value="c"> He's on his bike. </label>
              </div>
              <div class="question">
                <p>
                  <strong> 5: They are reasonably rich.</strong>
                  <br />
                  <label>
                    <input type="radio" name="five" value="a"> They are well to do. </label>
                  <br />
                  <label>
                    <input type="radio" name="five" value="b"> They are well and good. </label>
                  <br />
                  <label>
                    <input type="radio" name="five" value="c"> They are counting their blessings. </label>
              </div>
              <div class="question">
                <p>
                  <strong> 6: It happened completely unexpectedely.</strong>
                  <br />
                  <label>
                    <input type="radio" name="six" value="a"> It happened on the bounce. </label>
                  <br />
                  <label>
                    <input type="radio" name="six" value="b"> It happened out of the blue. </label>
                  <br />
                  <label>
                    <input type="radio" name="six" value="c"> It happened out of thin air. </label>
              </div>
              <div class="question">
                <p>
                  <strong> 7: She's really fit!</strong>
                  <br />
                  <label>
                    <input type="radio" name="seven" value="a"> She's fitter than a bell! </label>
                  <br />
                  <label>
                    <input type="radio" name="seven" value="b"> She's as fit as a fiddle! </label>
                  <br />
                  <label>
                    <input type="radio" name="seven" value="c"> She's as fit as a drum! </label>
              </div>
              <div class="question">
                <p>
                  <strong> 8: Don't complain about a present.</strong>
                  <br />
                  <label>
                    <input type="radio" name="eight" value="a"> Don't look at the horse's teeth. </label>
                  <br />
                  <label>
                    <input type="radio" name="eight" value="b"> Don't ask about the price. </label>
                  <br />
                  <label>
                    <input type="radio" name="eight" value="c"> Don't look a gift horse in the mouth. </label>
              </div>
              <div class="question">
                <p>
                  <strong> 9: She very nearly bought the house. </strong>
                  <br />
                  <label>
                    <input type="radio" name="nine" value="a"> She was on the brink of buying the house. </label>
                  <br />
                  <label>
                    <input type="radio" name="nine" value="b"> She was on the edge of buying the house </label>
                  <br />
                  <label>
                    <input type="radio" name="nine" value="c"> She was on her toes about buying the house. </label>
              </div>
              <div class="question">
                <p>
                  <strong>10: He accidently revealed the truth.</strong>
                  <br />
                  <label>
                    <input type="radio" name="ten" value="a"> He let the dog bark. </label>
                  <br />
                  <label>
                    <input type="radio" name="ten" value="b"> He let the bird out of the cage. </label>
                  <br />
                  <label>
                    <input type="radio" name="ten" value="c"> He let the cat out of the bag. </label>
              </div>
              <div class="question">
                <p>
                  <strong>11: It made me think.</strong>
                  <br />
                  <label>
                    <input type="radio" name="eleven" value="a"> It was a penny for my thoughts. </label>
                  <br />
                  <label>
                    <input type="radio" name="eleven" value="b"> It gave me food for thought. </label>
                  <br />
                  <label>
                    <input type="radio" name="eleven" value="c"> It gave me my thinking cap. </label>
              </div>
              <input type="submit" id="submit" value="Submit" />
              <input type="reset" class="reset" id="reset" name="reset" value="Reset" />
            </form>
          </div>
          <div id="score"></div>
          <div class="address"></div>
        </div>
      </div>
    </div>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script>
      /*global $:false */
      function clearAnswerImages() {
        $("img").remove();
      }

      function mark(el, status) {
        var images = {
            correct: "http://www.profesornativo.com/tick.jpg",
            incorrect: "http://www.profesornativo.com/x.jpg",
            unanswered: "",
          },
          img = new Image();
        img.src = images[status];
        img.className = status;
        el.append(img);
      }

      function displayScore() {
        var numQuestions = $(".question").length,
          questionsCorrect = $("img.correct").length;
        $("#score").html("You got " + questionsCorrect + " out of " + numQuestions);
      }
      $("form").on("submit", function(e) {
        e.preventDefault();
        clearAnswerImages();
        var $questions = $(".question");
        $questions.each(function() {
          var answer = $(this).find("input:checked"),
            key = answer.attr("name"),
            val = answer.attr("value");
          if (answer.length === 0) {
            mark($(this).find("p"), "unanswered");
          } else if (answers[key] !== val) {
            mark(answer.parent(), "incorrect"); // I  changed this line
          } else {
            mark(answer.parent(), "correct");
          }
        });
        displayScore();
      });
      $("input[type=reset]").on("click", function() {
        $("input:checked").prop("checked", false);
        $('#score').empty(); //I inserted this line      
        clearAnswerImages();
      });
      var answers = {
        "one": "c",
        "two": "b",
        "three": "c",
        "four": "b",
        "five": "a",
        "six": "b",
        "seven": "b",
        "eight": "c",
        "nine": "a",
        "ten": "c",
        "eleven": "b",
      };
    </script>
  </body>
</html>

Well first of all, use an up to date version of jQuery. If you must use 1.X, at least use 1.12.4. Better, 3.7.1.

Good to see you have removed the tables and are heading towards something more up to date and semantic. You might want to consider using fieldsets for each multi-option question.

Getting the HTML right should make life easier when it comes to the JS. Do you think you could make a codepen of this? Is that doable? It might make it easier for people to help.

It will require separating the HTML, CSS and JS, but that isn’t bad thing.

edit: example HTML

<form>
    <!-- Question 01 - They succeeded in spite of many difficulties. -->
    <fieldset class='question'>
        <legend>1: They succeeded in spite of many difficulties.</legend>
        <div class='option'>
            <input type='radio' id='answer_01_a' name='one' value='a' />
            <label for='answer_01_a'>They succeeded in the odds</label>
        </div>
        <div class='option'>
            <input type='radio' id='answer_01_b' name='one' value='b' />
            <label for='answer_01_b'>They succeeded over the adds.</label>
        </div>
        <div class='option'>
            <input type='radio' id='answer_01_c' name='one' value='c' />
            <label for='answer_01_c'>They succeeded against the odds.</label>
        </div>
    </fieldset>

    <!-- Question 02 - The advantages and disadvantages. -->
    <fieldset class='question'>
        <legend>2: The advantages and disadvantages.</legend>
        <div class='option'>
            <input type='radio' id='answer_02_a' name='two' value='a' />
            <label for='answer_02_a'>The fors and againsts.</label>
        </div>
        <div class='option'>
            <input type='radio' id='answer_02_b' name='two' value='b' />
            <label for='answer_02_b'>The pros and cons.</label>
        </div>
        <div class='option'>
            <input type='radio' id='answer_02_c' name='two' value='c' />
            <label for='answer_02_c'>The pros and antis.</label>
        </div>
    </fieldset>
    ...
</form>

Simple codepen example

From an accessibility standpoint, it also allows for making selections using a combination of tab, shift + tab and the cursor keys

1 Like

For a bit of fun, I thought I would have a go at this exercise.

Storing the data

One of the things I questioned was how the HTML is being created. Is the original poster (OP) inputting it manually, or is it being generated using a server-side language like PHP.

Given what a drag it would be to manually input the code, I decided to extract the data from the exisiting HTML and store it in a JSON file — something you might imagine would be pulled from a database. I also included the answers in the JSON data.

[
    {
        "id": 1,
        "title": "They succeeded in spite of many difficulties.",
        "name": "one",
        "options": {
            "a": "They succeeded in the odds",
            "b": "They succeeded over the adds.",
            "c": "They succeeded against the odds."
        },
        "answer": "c"
    },
    {
        "id": 2,
        "title": "The advantages and disadvantages.",
        "name": "two",
        "options": {
            "a": "The fors and againsts.",
            "b": "The pros and cons.",
            "c": "The pros and antis."
        },
        "answer": "b"
    },
    {
        "id": 3,
        "title": "He reconsidered.",
		"name": "three",
        "options": {
            "a": "He had different opinions.",
            "b": "He had another thought.",
            "c": "He had second thoughts."
        },
        "answer": "c"
    },
    ...
]

Templating

For templating I originally considered using JS’s Template strings, but opted instead to use ejs with the following template to render out the html. I thought this might be a more realisitic example of how the HTML might be generated.

<form id='quiz'>
    <h2>Quiz: Well known sayings</h2>
    <% for (const question of questions) { %>
        <!-- <%- question.title %> -->
        <fieldset class='question'>
            <legend><%- question.id %>: <%- question.title %></legend>
            <% Object.entries(question.options).forEach(([key, value], i) => { %>
            <div class='option'>
                <input type='radio' id='answer_<%- question.id %>_<%- key %>' name='<%- question.name %>' value='<%- key %>' />
                <label for='answer_<%- question.id %>_<%- key %>'><%- value %></label>
            </div><% }); %>
        </fieldset>
    <% } %>
    <div class='buttons-group'>
        <button type='submit'>Submit</button>
        <button type='reset'>Reset</button>
    </div>
</form>

The JSON data and the the ejs template file are fetched using JS’s fetch api and are passed to the render function returning rendered HTML.

This is an example of one of the rendered fieldsets.

    ...
    <!-- The advantages and disadvantages. -->
    <fieldset class="question">
        <legend>2: The advantages and disadvantages.</legend>
        
        <div class="option">
            <input type="radio" id="answer_2_a" name="two" value="a">
            <label for="answer_2_a">The fors and againsts.</label>
        </div>
        <div class="option">
            <input type="radio" id="answer_2_b" name="two" value="b">
            <label for="answer_2_b">The pros and cons.</label>
        </div>
        <div class="option">
            <input type="radio" id="answer_2_c" name="two" value="c">
            <label for="answer_2_c">The pros and antis.</label>
        </div>
    </fieldset>
    ...

Answers

The answers and names were extracted using destructuring from the JSON data and using Object.fromEntries were transformed to an object as per the OP’s original answer object.

// name and answer values mapped to array pairs, then
// transformed into an object using Object.fromEntries
// e.g. { "one": "c", ... "five": "a" }
const answers = Object.fromEntries(
    questions.map(({ name, answer }) => [name, answer])
)

These could then be used to compare against checked radio buttons in the form.

    ...
    let numCorrect = 0;
    // form.elements holds a collection of the form's input elements
    for (const input of form.elements) {
        if(input.checked) {
            const isCorrect = input.value === answers[input.name];
            // add 'false' or 'true' class to the input
            input.classList.add(isCorrect.toString())
            if (isCorrect) numCorrect ++;
        }
    }
    ...

Final JS code

Here is the complete JS code.

/**
 * generic function to fetch the json and ejs text file
 * param {string} type - response method e.g. 'json', 'text' or 'blob'
 * param {String} url - url to fetch data from
 * return {any} the fetched and parsed data
*/
async function fetchType(type, url) {
    try {
        const response = await fetch(url);
        if (!response.ok)
            throw new Error(`Response status: ${response.status}`);

        return await response[type]();
    } catch (error) {
        console.error(error.message);
    }
}

/**
 * render the template with ejs and append it to the parent element
 * param {HTMLElement} parent - parent element to append the template to
 * param {String} template - ejs template string
 * param {Object} obj - object to pass to the template
 * return {HTMLElement} the element we just added
*/
function render(parent, template, obj) {
    // render the template with ejs and append it to the parent element
    parent.insertAdjacentHTML('afterbegin', ejs.render(template, obj))
    // return the element we just added
    return parent.firstElementChild;
}

async function main() {
    const questions = await fetchType(
        'json', 'https://assets.codepen.io/3351103/questions.json'
    );
    
    // name and answer values mapped to array pairs, then
    // transformed into an object using Object.fromEntries
    // e.g. { "one": "c", ... "five": "a" }
    const answers = Object.fromEntries(
        questions.map(({ name, answer }) => [name, answer])
    )
    
    // import an ejs template string (see the link)
    const fieldsetTemplate = await fetchType(
        'text', 'https://assets.codepen.io/3351103/fieldset.txt'
    );
    
    const container = document.getElementById('quiz-container');
    const form = render(container, fieldsetTemplate, { questions });
    const log = document.getElementById('log');

    form.addEventListener(
        'submit',
        (event) => {
            event.preventDefault();
            let numCorrect = 0;

            for (const input of form.elements) {
                if(input.checked) {
                    const isCorrect = input.value === answers[input.name];
                    input.classList.add(isCorrect.toString())
                    if (isCorrect) numCorrect ++;
                }
            }
            
            log.textContent = `${numCorrect} correct answers out of ${questions.length}`;
        }
    );
    
    form.addEventListener(
        'change',
        (event) => {
            // get the parent fieldset of this changed input
            const fieldset = event.target.closest('fieldset')
            for (const input of fieldset.elements) {
                // clear true or false classes in this fieldset
                input.classList.remove('true', 'false');
            }
        }
    )
    
    form.addEventListener('reset', (event) => (log.textContent = ''))
}

main();

I know you only asked about your submit button, so this is somewhat overkill, but hopefully it is of some use to you. :slight_smile:

1 Like

OK, first I’m working on updating the jquery, etc. Thanks

Well, finally got it working by using M_Hutley’s codepen example (above). Thank you!
I inserted these lines inside the head tags:

<script src="https://code.jquery.com/jquery-3.7.1.min.js"
  integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="
  crossorigin="anonymous"></script>
<script src="home/sean/idioms.js"></script>
  </head>

I tried linking to the js file using the link by adding it before the closing head tag, as shown above, but it didn’t work, so I added the script to the html file, as before. Basically, I used Bluefish editor to save the js script, and then saved it in home/sean/idioms.js,
then linked to that in the html file. Any idea what I’m doing wrong? Thanks.

You should not be putting your <script src="home/sean/idioms.js"></script> in the head. At least not without wrapping it in something like $(document).ready()

Your idioms.js script requires the DOM to be rendered first, so that it can access the page elements e.g. form, input[type=reset].

A better place to put it is at the bottom, before the closing body tag

   ... page elements here
    <script src="home/sean/idioms.js"></script>
</body>

Just to ask, but why are you using jquery for this? Is there a good reason over using vanilla javascript?

For your consideration, here is an example with vanilla JS that is more inline with yours and doesn’t use a template and json to render the html.

const answers = {
    one: 'c',
    two: 'b',
    three: 'c',
    four: 'b',
    five: 'a',
    six: 'b',
    seven: 'b',
    eight: 'c',
    nine: 'a',
    ten: 'c',
    eleven: 'b'
}

window.addEventListener('DOMContentLoaded', () => {
    const form = document.getElementById('quiz')
    const log = document.getElementById('log');

    form.addEventListener(
        'submit', (event) => {
            event.preventDefault();
            let numCorrect = 0;

            for (const input of form.elements) {
                if(input.checked) {
                    const isCorrect = input.value === answers[input.name];
                    // will add boolean as a string e.g. 'true' or 'false' as a classname
                    input.classList.add(isCorrect.toString())
                    if (isCorrect) numCorrect ++;
                }
            }
            
            log.textContent = `${numCorrect} correct answers out of ${answers.length}`;
        }
    );
    
    form.addEventListener(
        'change', (event) => {
            // get the parent fieldset of this changed input
            const fieldset = event.target.closest('fieldset')
            for (const input of fieldset.elements) {
                // clear true or false classes in this fieldset
                input.classList.remove('true', 'false');
            }
        }
    )
    
    form.addEventListener('reset', (event) => (log.textContent = ''))    
})

The css for the inputs

.option input.true:checked + label:after {
    content: '✔';
    font-size: 1.1rem;
    font-weight: bold;
    color: green;
    margin-left: 5px;
}
  
.option input.false:checked + label:after {
    content: '✘';
    font-size: 1.1rem;
    font-weight: bold;
    color: red;
    margin-left: 5px;
}

codepen here

1 Like

The Vanilla sounds good. I will try after my second breakfast! Thanks.

1 Like

(Can’t resist)
After elevenses and before the trip to Isengard…

1 Like

I’m afraid I haven’t managed to get the above vanilla js working. I see that it works in Codepen. What I tried is that I created a new html page and pasted the vanilla html there, adding opening and closing html tags, etc, and I updated the js page idioms.js in home/sean/buttons.js and placed the link here:

<script src="home/sean/idioms.js"></script>
</body>
</html>  

Is that correct?

And I placed this link to the css here in the head of rhe html page:

<link rel='stylesheet' type='text/css' media="screen" href='buttons.css'>

Okay, so I have taken the code out of codepen and put it into files and folders. See the explorer on the left, to see how I have structured this. You can change these accordingly.

HTML index.html
I haven’t pasted all the fieldsets here, you will need to fill in the blanks. They can be copied from the codepen I posted.

<!DOCTYPE html>
<html lang='en'>
<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <title>Idioms</title>
    <link rel='stylesheet' href='./public/css/main.css'>
</head>
<body>
    <div id='quiz-container' class='container'>
        <form id='quiz'>
            <h2>Quiz: Well known sayings</h2>

            <!-- They succeeded in spite of many difficulties. -->
            <fieldset class='question'>
                <legend>1: They succeeded in spite of many difficulties.</legend>

                <div class='option'>
                    <input type='radio' id='answer_1_a' name='one' value='a'>
                    <label for='answer_1_a'>They succeeded in the odds</label>
                </div>
                <div class='option'>
                    <input type='radio' id='answer_1_b' name='one' value='b'>
                    <label for='answer_1_b'>They succeeded over the adds.</label>
                </div>
                <div class='option'>
                    <input type='radio' id='answer_1_c' name='one' value='c'>
                    <label for='answer_1_c'>They succeeded against the odds.</label>
                </div>
            </fieldset>

            <!-- The advantages and disadvantages. -->
            <fieldset class='question'>
                <legend>2: The advantages and disadvantages.</legend>

                <div class='option'>
                    <input type='radio' id='answer_2_a' name='two' value='a'>
                    <label for='answer_2_a'>The fors and againsts.</label>
                </div>
                <div class='option'>
                    <input type='radio' id='answer_2_b' name='two' value='b'>
                    <label for='answer_2_b'>The pros and cons.</label>
                </div>
                <div class='option'>
                    <input type='radio' id='answer_2_c' name='two' value='c'>
                    <label for='answer_2_c'>The pros and antis.</label>
                </div>
            </fieldset>

            ... rest of fieldsets here

            <!-- It made me think. -->
            <fieldset class='question'>
                <legend>11: It made me think.</legend>

                <div class='option'>
                    <input type='radio' id='answer_11_a' name='eleven' value='a'>
                    <label for='answer_11_a'>It was a penny for my thoughts.</label>
                </div>
                <div class='option'>
                    <input type='radio' id='answer_11_b' name='eleven' value='b'>
                    <label for='answer_11_b'>It gave me food for thought.</label>
                </div>
                <div class='option'>
                    <input type='radio' id='answer_11_c' name='eleven' value='c'>
                    <label for='answer_11_c'>It gave me my thinking cap.</label>
                </div>
            </fieldset>

            <div class='buttons-group'>
                <button type='submit'>Submit</button>
                <button type='reset'>Reset</button>
            </div>
        </form>
        <output id='log'></output>
    </div>
    <!-- link to Javascript file -->
    <script src='./public/js/main.js'></script>
</body>
</html>

CSS ./public/css/main.css
This has been compiled from the scss in codepen to plain css. I used the live sass compiler extension in VS Code to do this.

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;300;400;500;600&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@100..900&display=swap');

/* CSS Resets */
*, *::before, *::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

body {
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

img, picture, video, canvas, svg {
  display: block;
  max-width: 100%;
}

input, button, textarea, select {
  font: inherit;
}

p, h1, h2, h3, h4, h5, h6 {
  overflow-wrap: break-word;
}

ol, ul {
  list-style: none;
  padding: 0;
}

fieldset {
  border: none;
  outline: none;
}

/* main styles */

body {
  font-family: 'Poppins', sans-serif;
  color: #444;
  padding: 2rem;
}

.container {
  max-width: 800px;
  width: 100%;
  margin: 0 auto;
  background-color: #ecede4;
  padding: 2rem 2rem 3rem;
}

h2 {
  color: #059373;
  font-size: 1.4rem;
  margin-bottom: 1.5rem;
}

#log {
  display: block;
  font-size: 1.3rem;
  font-weight: 900;
  height: 20px;
}

form#quiz {
  margin-bottom: 1rem;
}

form#quiz legend {
  font-family: 'Poppins', sans-serif;
  font-size: 1.1rem;
  font-weight: 600;
  margin-bottom: 0.25rem;
  color: black;
}

form#quiz fieldset {
  display: flex;
  flex-direction: column;
  margin-bottom: 2rem;
  padding: 0 0 2rem;
  border: 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.2);
  row-gap: 0.25rem;
  counter-reset: option;
}

form#quiz .option {
  display: flex;
  padding-left: 25px;
  align-items: center;
  font-size: 1.1rem;
}

form#quiz .option:before {
  counter-increment: option;
  content: counter(option, lower-alpha);
  font-family: 'Roboto Slab';
  font-weight: bold;
  color: salmon;
  padding-right: 5px;
}

form#quiz .option input {
  outline-color: #0075ff;
}

form#quiz .option label {
  font-family: 'Roboto Slab', sans-serif;
  letter-spacing: 0.01rem;
  padding-left: 5px;
}

/* ticks and crosses */
form#quiz .option label:after {
  font-size: 1.1rem;
  font-weight: bold;
  margin-left: 5px;
}

form#quiz .option input.true:checked + label:after {
  content: '✔';
  color: green;
}

form#quiz .option input.false:checked + label:after {
  content: '✘';
  color: red;
}

/* group for the submit and reset buttons */
form#quiz .buttons-group {
  display: flex;
  -moz-column-gap: 1rem;
       column-gap: 1rem;
}

form#quiz button {
  cursor: pointer;
}

Note: you can achieve similar in codepen

JS ./public/js/main.js
I have wrapped the code from codepen inside an IIFE (Immediately Invoked Function Expression) . The purpose to avoid conflicts with any other scripts. The code is taken out of the global namespace and wrapped inside it’s own self executing function.

// put code inside of an IIFE, so as to avoid conflicts with global variables
(function () {
    const answers = {
        one: 'c',
        two: 'b',
        three: 'c',
        four: 'b',
        five: 'a',
        six: 'b',
        seven: 'b',
        eight: 'c',
        nine: 'a',
        ten: 'c',
        eleven: 'b'
    };

    window.addEventListener('DOMContentLoaded', () => {
        const form = document.getElementById('quiz');
        const log = document.getElementById('log');

        form.addEventListener(
            'submit', (event) => {
                event.preventDefault();
                let numCorrect = 0;

                for (const input of form.elements) {
                    if (input.checked) {
                        const isCorrect = input.value === answers[input.name];
                        // will add boolean as a string e.g. 'true' or 'false'
                        input.classList.add(isCorrect.toString());
                        if (isCorrect) numCorrect++;
                    }
                }

                log.textContent = `${numCorrect} correct answers out of ${answers.length}`;
            }
        );

        form.addEventListener(
            'change', (event) => {
                // get the parent fieldset of this changed input
                const fieldset = event.target.closest('fieldset');
                for (const input of fieldset.elements) {
                    // clear true or false classes in this fieldset
                    input.classList.remove('true', 'false');
                }
            }
        );

        form.addEventListener('reset', (event) => (log.textContent = ''));
    });
}());

I hope this helps. If you have any questions I will try and answer them :slight_smile:

If the questions relate to CSS they might be better posted in a new topic under the category of CSS.

1 Like

Thanks for all that assistance. I have added the fieldsets. I assume that even without the css, the page should actually work? As regards the js code, do I need to upload it to my public_html folder, or how can I upload to the “public” folder mentioned in the link below, and should I add that link just before the closing body tag of the html page, like below?

</body>
<script src='/public/js/main.js</script> 
</html>

I’m not familiar with Bluefish editor, but as mentioned you can alter your folder structure to suit — using a public folder is just a common convention.

In this example I have moved all files into the same folder. I have also renamed the css and js files to ‘idioms.css’ and ‘idioms.js’

With regards the CSS, I would suggest adding the code from the screenshot, as it ties in with the JS giving you ticks and crosses. You can then style the rest how you like.

Example with rest of css removed

Oh, just to point out I have added a fix. I was wrongly trying to get the length of the answers object. Instead I have created a ‘numQuestions’ variable based on the number of elements with a class of ‘question’.

JS ammend

// put code inside of an IIFE, so as to avoid conflicts with global variables
(function () {
    const answers = {
        one: 'c',
        two: 'b',
        three: 'c',
        four: 'b',
        five: 'a',
        six: 'b',
        seven: 'b',
        eight: 'c',
        nine: 'a',
        ten: 'c',
        eleven: 'b'
    };

    window.addEventListener('DOMContentLoaded', () => {
        const form = document.getElementById('quiz');
        const log = document.getElementById('log');
        // This line added to get a count of the questions.
        const numQuestions = form.querySelectorAll('.question').length;

        form.addEventListener(
            'submit', (event) => {
                event.preventDefault();
                let numCorrect = 0;

                for (const input of form.elements) {
                    if (input.checked) {
                        const isCorrect = input.value === answers[input.name];
                        // will add boolean as a string e.g. 'true' or 'false'
                        input.classList.add(isCorrect.toString());
                        if (isCorrect) numCorrect++;
                    }
                }

                log.textContent = `${numCorrect} correct answers out of ${numQuestions}`;
            }
        );

        form.addEventListener(
            'change', (event) => {
                // get the parent fieldset of this changed input
                const fieldset = event.target.closest('fieldset');
                for (const input of fieldset.elements) {
                    // clear true or false classes in this fieldset
                    input.classList.remove('true', 'false');
                }
            }
        );

        form.addEventListener('reset', (event) => (log.textContent = ''));
    });
}());