SitePoint Sponsor

User Tag List

Results 1 to 14 of 14
  1. #1
    SitePoint Addict
    Join Date
    Apr 2003
    Location
    spain
    Posts
    283
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    adding score ++ to test questions

    Hi, I`d like to add something like "you got 8 answers correct out of 10" to this code:

    `
    Code:
    <!DOCTYPE HTML>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Quiz with radio buttons</title>
        <style>
          label{ display: block; }
          input[type=submit]{ margin-top: 15px; }
        </style>
      </head>
    
      <body>
        <form> 
          <div class="question">
            <p><strong>Q1</strong>: Mary is English. She was born in London</p>
    
            <label><input type="radio" name="one" value="a">Mary was born in England</label>
            <label><input type="radio" name="one" value="b">Mary, who is English, was born in London</label>
            <label><input type="radio" name="one" value="c">English Mary was born in London</label>
            <label><input type="radio" name="one" value="d">London Mary is English born</label>
          </div>
    
          <div class="question"> 
            <p><strong>Q2</strong>: Mary is English. She was born in London</p>
    
            <label><input type="radio" name="two" value="a">Mary was born in England</label>
            <label><input type="radio" name="two" value="b">Mary, who is English, was born in London</label>
            <label><input type="radio" name="two" value="c">English Mary was born in London</label>
            <label><input type="radio" name="two" value="d">London Mary is English born</label>
          </div>
    
          <input type="submit" />
          <input type="reset" value="Start again" /> 
        </form>
    
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        <script>
          function clearAnswerImages(){
            $("img").each(function(){
              $(this).remove();
            })
          }
    
          function mark(el, status){
            var images = {
              correct: "http://www.littletherese.com/tick.jpg",
              incorrect: "http://www.littletherese.com/x.jpg",
              unanswered: "http://assets.altperks.com/shared/images/clickable/questionmark-15x15.gif",
            }, 
            img = new Image();
            img.src = images[status];
            el.append(img);
          }
    
          $("form").on("submit", function(e){
            e.preventDefault();
            clearAnswerImages();
    
            $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");
              } 
            });
          });
    
          $("input[type=reset]").on("click", function(){
            $("input:checked").each(function(){
              $(this).prop("checked", false);
            });
    
            clearAnswerImages();
          });
    
          var answers = {
            "one": "b",
            "two": "b"
          }
        </script>
      </body>
    </html>
    Thanks for any help.

  2. #2
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,078
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Hi dubman,

    You can do it like this:

    Code:
    <!DOCTYPE HTML>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Quiz with radio buttons</title>
        <style>
          label{ display: block; }
          input[type=submit]{ margin-top: 15px; }
          #score{
            padding: 5px;
            margin: 15px 0 0 0;
          }
        </style>
      </head>
    
      <body>
        <form> 
          <div class="question">
            <p><strong>Q1</strong>: Mary is English. She was born in London</p>
    
            <label><input type="radio" name="one" value="a">Mary was born in England</label>
            <label><input type="radio" name="one" value="b">Mary, who is English, was born in London</label>
            <label><input type="radio" name="one" value="c">English Mary was born in London</label>
            <label><input type="radio" name="one" value="d">London Mary is English born</label>
          </div>
    
          <div class="question"> 
            <p><strong>Q2</strong>: Mary is English. She was born in London</p>
    
            <label><input type="radio" name="two" value="a">Mary was born in England</label>
            <label><input type="radio" name="two" value="b">Mary, who is English, was born in London</label>
            <label><input type="radio" name="two" value="c">English Mary was born in London</label>
            <label><input type="radio" name="two" value="d">London Mary is English born</label>
          </div>
    
          <input type="submit" />
          <input type="reset" value="Start again" /> 
        </form>
    
        <div id="score"></div>
    
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        <script>
          function clearAnswerImages(){
            $("img").each(function(){
              $(this).remove();
            })
          }
    
          function mark(el, status){
            var images = {
              correct: "http://www.littletherese.com/tick.jpg",
              incorrect: "http://www.littletherese.com/x.jpg",
              unanswered: "http://assets.altperks.com/shared/images/clickable/questionmark-15x15.gif",
            }, 
            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();
    
            $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").each(function(){
              $(this).prop("checked", false);
            });
    
            clearAnswerImages();
          });
    
          var answers = {
            "one": "b",
            "two": "b"
          }
        </script>
      </body>
    </html>
    HTH

  3. #3
    SitePoint Addict
    Join Date
    Apr 2003
    Location
    spain
    Posts
    283
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Brilliant! Thanks so much!

  4. #4
    SitePoint Addict
    Join Date
    Apr 2003
    Location
    spain
    Posts
    283
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry, one last thing. The reset button doesn't clear the "score" field. How can I get all the fields to clear on reset? Thanks.

  5. #5
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,078
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    No probs

    Use the .html() method to set the div's contents to that of an empty string.

  6. #6
    SitePoint Addict
    Join Date
    Apr 2003
    Location
    spain
    Posts
    283
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok, I got it working with the last line of the code below:
    Code:
    $("input[type=reset]").on("click", function(){
            $("input:checked").each(function(){
              $(this).prop("checked", false);
              $('#score').empty(); //I inserted this line
            });
    I ran the complete javascript code through JSHint and got a few "missing semi-colons"
    one of which was after a curly brace }; I thought there shouldn't be semi-colons after a curly brace?
    I also got some "undefined variables", but I think this isn't a problem?

    Anyway, I'm delighted with the help. Thank you!

  7. #7
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,078
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Hi,

    Yeah .empty() will do the job just as well.

    Regarding the missing semi-colons: they are all valid (i.e. JSHint is correct).
    The one after the curly brace is a variable declaration and is necessary.

    Regarding the undefined variables:
    $ - you can ignore or alternatively add this at the top of the script file:
    Code:
    /*global $:false */
    This declares to JSHint that $ is a global variable, and the false indicates that it should not be overridden.

    The missing var before $questions was a mistake. Good catch.

  8. #8
    SitePoint Addict
    Join Date
    Apr 2003
    Location
    spain
    Posts
    283
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Pullo View Post
    Hi,

    Yeah .empty() will do the job just as well.

    Regarding the missing semi-colons: they are all valid (i.e. JSHint is correct).
    The one after the curly brace is a variable declaration and is necessary.

    Regarding the undefined variables:
    $ - you can ignore or alternatively add this at the top of the script file:
    Code:
    /*global $:false */
    This declares to JSHint that $ is a global variable, and the false indicates that it should not be overridden.

    The missing var before $questions was a mistake. Good catch.
    Sorry, I don't know how to fix that "missing var before $questions". Now, after updating the code, JSHint gives me 2 errors:
    One undefined variable
    47 $questions
    48 $questions

    JSHint code:
    Code:
       /*global $:false */
      function clearAnswerImages(){
            $("img").each(function(){
              $(this).remove();
            });
          }
    
          function mark(el, status){
            var images = {
              correct: "http://www.littletherese.com/tick.jpg",
              incorrect: "http://www.littletherese.com/x.jpg",
              unanswered: "http://assets.altperks.com/shared/images/clickable/questionmark-15x15.gif",
            }, 
            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();
            
            $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").each(function(){
              $(this).prop("checked", false);
              $('#score').empty(); //I inserted this line
            });
    
            clearAnswerImages();
          });
    
          var answers = {
            "one": "b",
            "two": "b"
          };

  9. #9
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,078
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    That's easy
    Change this:

    Code:
    $questions = $(".question");
    To this:

    Code:
    var $questions = $(".question");

  10. #10
    SitePoint Addict
    Join Date
    Apr 2003
    Location
    spain
    Posts
    283
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Pullo View Post
    That's easy
    Change this:

    Code:
    $questions = $(".question");
    To this:

    Code:
    var $questions = $(".question");
    Done! The code is clean now in JsHint. I notice that the reset button clears answers and "score", *but in the case that "submit" is pressed, without having answered any questions, the result is "You got 0 correct out of 10", and in this case, pressing "reset" doesn't clear the score message. I can understand the logic of it (I think...), but I'm wondering how reset could clear the "0 correct" message as well.
    This is the clean code.
    Code:
    <script>
         /*global $:false */
      function clearAnswerImages(){
            $("img").each(function(){
              $(this).remove();
            });
          }
          
    
          function mark(el, status){
            var images = {
              correct: "http://www.littletherese.com/tick.jpg",
              incorrect: "http://www.littletherese.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").each(function(){
              $(this).prop("checked", false);
              $('#score').empty(); //I inserted this line          
            });
    
            clearAnswerImages(); 
          });
    
           var answers = { 
            "one": "b",
            "two": "c", 
            "three": "a",
            "four": "c",
            "five": "b",
            "six": "c",
            "seven": "a",
            "eight": "a",
            "nine": "b",
            "ten": "c",
                                                    
          }; 
        </script>
    Thanks.

  11. #11
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,078
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Hi,

    This is your click handler for the reset button:

    Code:
    $("input[type=reset]").on("click", function(){
      $("input:checked").each(function(){
        $(this).prop("checked", false);
        $('#score').empty();
      });
    
      clearAnswerImages(); 
    });
    You need to move the call to empty, outside of the loop to reset the checkboxes.

    You can also simplify the loop to this:

    Code:
    $("input:checked").prop("checked", false);
    which gives you:

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

  12. #12
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,283
    Mentioned
    51 Post(s)
    Tagged
    2 Thread(s)
    Also
    Code:
    function clearAnswerImages(){
            $("img").each(function(){
              $(this).remove();
            });
          }
    could simply be
    Code:
    function clearAnswerImages(){
            $("img").remove();
    }
    Use each() only if your each-thingies are boxes or something holding many other child-thingies and you need multiple variables set for every each-thingie-box so that you can run multiple listeners/functions/cookoffs/whatever. Remember that in jQuery if you say $('some thing') you're always getting an object with a *list* of thingies (even if it's a list of one), so any jQuery function you tack on to that $('thingie') will automatically be done to each thingie in your list of thingies.

  13. #13
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,078
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Thanks poes, good catch.

  14. #14
    SitePoint Addict
    Join Date
    Apr 2003
    Location
    spain
    Posts
    283
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Red face

    Thanks Pullo and Poes! It works great now!


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •