SitePoint Sponsor

User Tag List

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

    JS promises for online quiz

    Hi, I would like to use js promises to make online multiple choice type questions. I was trying to figure out how I could integrate some elseif statements

    in the following code, in order to add more options:
    Code:
    <script type="text/javascript">
          var validationConfig = {
            '.question_1': {
              checks: 'a',
              field: 'Question 1'
            },
    				'.question_2': {
              checks: 'c',
              field: 'Question 2'
            }
          };
        
          function showAlerts(errors) {
            var alertContainer = $('.alert');
            $('.error').remove();
        
            if (!errors) {
              alertContainer.html('<small class="label success">All correct</small>');
            }
            else {
              $.each(errors, function (idx, err) {
                var msg = $('<small></small>')
                    .addClass('error')
                    .text(err.error);
        
                err.control.parent().append(msg);
              });
            }
          }
    Any help appreciated.

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

    So, let's take a few steps back, as the promises solution was something I posted in a previous thread and might or might not be the best solution for you.

    As I understand it, you have a page full of multiple choice questions, which when the user submits the form, you are validating server-side using PHP.

    You are now considering using JS to add an additional layer of validation on the client-side.

    Is that correct?

  3. #3
    SitePoint Addict
    Join Date
    Apr 2003
    Location
    spain
    Posts
    283
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I was just thinking that the javascript solution would have a more responsive feel to it than php - for the user I mean,
    even though now the php code is also doing the job, thanks to help from the php forum....

    Yea, I think the client side validation seems better. I was wondering if it might be possible to adapt your promises code
    with the usual js if and elseif statements, but I couldn't find a way to do it.

    I also thought that javascript may be more "lightweight"
    than php, since it doesn't depend on round trips to the server for validation? Thanks.

  4. #4
    SitePoint Addict
    Join Date
    Apr 2003
    Location
    spain
    Posts
    283
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is a php page I have been working on. I think it does everything I need in php.

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

    I've taken that page as a base and have added the JS functionality we discussed.

    Here's a demo.

    Please not: the JS is only half finished (although the page works already).

    Have a look at the source code and tell me if you think that is something you could work with.
    If it is, I'll rework the JavaScript and write a more verbose post about what I have done and how you can extend things.

    Hope that helps some.

  6. #6
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,996
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    I've just been thinking about this
    If you don't want the answers to be visible, then perhaps AJAX would be the way to go.
    This way, you would use JavaScript to submit the form data to a PHP script, which would then evaluate them.
    This would also improve the feel of the page (i.e. no refresh), but not show the answers in the source code.

  7. #7
    SitePoint Addict
    Join Date
    Apr 2003
    Location
    spain
    Posts
    283
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, the demo page looks very good to me, and I think I can adapt it for my needs. Just wondering how I can activate the php code, for people with js turned off? The answers being visible in the source code would be ok, although if the Ajax method isn't too complicated, that would be a good idea too. Thanks.

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

    Quote Originally Posted by dubman View Post
    Well, the demo page looks very good to me, and I think I can adapt it for my needs.
    Excellent

    Quote Originally Posted by dubman View Post
    Just wondering how I can activate the php code, for people with js turned off?
    It works like this:
    A visitor with JS turned on fills out the form and clicks submit.
    The JS catches the submit event, prevents the form from submitting, validates the user's input, then gives the user feedback.
    No page reload takes place.

    Then a visitor with JS turned off fills out the form and clicks submit.
    The form submits to your PHP script and is validated there.
    The PHP script reloads the page or redirects to another page.

    Quote Originally Posted by dubman View Post
    The answers being visible in the source code would be ok, although if the Ajax method isn't too complicated, that would be a good idea too..
    Then it's better to use the solution we have here.
    AJAX would further complicate things.

    What I'll do is rework the JS in the next couple of days and post back here.

  9. #9
    SitePoint Addict
    Join Date
    Apr 2003
    Location
    spain
    Posts
    283
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Great! So, do you mean that I should have the php code in the same page as the js? No need to add any if statements to distinguish between js and php?

  10. #10
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,996
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by dubman View Post
    So, do you mean that I should have the php code in the same page as the js?
    Nope, this is not possible.
    You should have:

    A HTML page containing the form.
    A CSS file which contains the styles for your page.
    A JS file which contains the code to validate user input on the client-side.
    A PHP file which contains the code to validate user input on the server-side (in case a user has JavaScript disabled).

  11. #11
    SitePoint Addict
    Join Date
    Apr 2003
    Location
    spain
    Posts
    283
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok, the css file is understood. But do you mean something like this in the html file?

    Code:
    <form action="for_to.php" method="post" id="form_id" name="f">

  12. #12
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,996
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Exactly. You specify where to send the form data in the form's action attribute.
    for_to.php is a remote file which must be interpreted before it is served to the browser.

    The JS file on the other hand is included in the page like so:
    <script type="text/javascript" src="..."></script>
    In contrast to the PHP file, it is interpreted at run time and can thus do things like manipulate form data.

  13. #13
    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
    The JS file on the other hand is included in the page like so:
    <script type="text/javascript" src="..."></script>
    Ok, so you mean the javascript that's used to configure the dropdown boxes, etc should be included near the end of the HTML page?
    But do I also need to link to these files in my HTML page?
    Code:
    <script src="jquery.js" type="text/javascript"></script>
    <script src="validator.js" type="text/javascript"></script>

  14. #14
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,996
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Nope.
    Are they from my old demo?

    This one s hould work as is.

  15. #15
    SitePoint Addict
    Join Date
    Apr 2003
    Location
    spain
    Posts
    283
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yea, they're from your old demo. But just to clarifY: so I just add the js code to my html file, and therefore I don't need a separate js file (linked to
    from my html page)?

  16. #16
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    5,996
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Oh right, yeah, sorry.
    You can either stick the JS in an external file, or include it directly in the page.
    I'll sort out the demo for you tomorrow and explain what I have done.

  17. #17
    SitePoint Addict
    Join Date
    Apr 2003
    Location
    spain
    Posts
    283
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ok thanks, but I think you deserve a weekend break! There's no hurry ;o)

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

    I've tidied up the code somewhat:

    Code:
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>Clases particulares de ingl&eacute;s con profesor nativo en Granollers... </title>
        <link rel='stylesheet' type='text/css' href='http://www.littletherese.com/say_tell.css' />
        <style>
          ol li {
            background-image: none;
            padding:10px;
          }
        </style>
      </head>
    
      <body>
        <div id="pagewrap"> 
          <div id="container">
            <div id="content">
              <h4>For or to?</h4>
              <div class="scroll">
                <form action="" method="post" id="myForm" name="f">
                  <ol>
                    <li>
                      She had to go to the shop
                      <select name="question1">
                        <option value="na"></option>
                        <option value="a"> for </option>   
                        <option value="b"> to </option> 
                      </select> 
                      buy bread.
                    </li>
                    <li>
                      They went to Italy
                      <select name="question2">
                        <option value="na"></option>
                        <option value="a"> to </option> 
                        <option value="b"> for </option> 
                      </select>
                      see a football match.
                    </li>
                    <li>
                      She had to study a lot
                      <select name="question3">
                        <option value="na"></option>
                        <option value="a"> for </option>   
                        <option value="b"> to </option> 
                      </select> 
                      pass the exam.
                    </li>
                    <li>
                      You have to pay
                      <select name="question4">
                        <option value="na"></option>
                        <option value="a"> for </option>   
                        <option value="b"> to </option> 
                      </select> 
                      get a license.
                    </li>
                    <li>
                      She needed lots of money
                      <select name="question5">
                        <option value="na"></option>
                        <option value="a"> to </option>   
                        <option value="b"> for </option> 
                      </select> 
                      buy the house.
                    </li>
                    <li>
                      I asked my friend 
                      <select name="question6">
                        <option value="na"></option>
                        <option value="a"> to </option>   
                        <option value="b"> for </option> 
                      </select> 
                      some money. 
                    </li>
                    <li>
                      Some people need glasses
                      <select name="question7">
                        <option value="na"></option>
                        <option value="a"> to </option>   
                        <option value="b"> for </option> 
                      </select> 
                      reading. 
                    </li>
                    <li>
                      I didn't have time
                      <select name="question8">
                        <option value="na"></option>
                        <option value="a"> for </option>   
                        <option value="b"> to </option> 
                      </select> 
                      repair the car. 
                    </li>
                    <li>
                      I have been working here
                      <select name="question9">
                        <option value="na"></option>
                        <option value="a"> since </option>   
                        <option value="b"> for </option> 
                      </select> 
                      10 years. 
                    </li>
                    <li>
                      Fresh fruit is good
                      <select name="question10">
                        <option value="na"></option>
                        <option value="a"> for </option>   
                        <option value="b"> to </option> 
                      </select> 
                      your health.
                    </li>
                  </ol>
                
                  <div id="score"></div> 
                  
                  <input type="submit" id="submit" value="Result" />
                  <input type="reset" class="reset" id="reset" name="reset" value="Start again" />
                </form>
              </div> 
            </div> 
          </div> 
        </div>
        
        <script>
          Object.size = function(obj) {
            var size = 0, key;
            for (key in obj) {
              if (obj.hasOwnProperty(key)) size++;
            }
            return size;
          };
          
          (function(){
            "use strict";
            window.checkAnswers = function(opts){
              
              function validateInput(){
                var question,
                    answer;
                    
                for (question in opts) {
                  if(opts.hasOwnProperty(question)) {
                    answer = f.elements[question].options[f.elements[question].selectedIndex].value;
                    if(answer === "na"){
                      opts[question].state = "not-filled-in";
                    } else if(answer === opts[question].answer){
                      opts[question].state = "correct";
                    } else {
                      opts[question].state = "error";
                    }
                  }
                }
              }
              
              function markCorrectOrIncorrect(){
                var question, 
                    li;
                
                for (question in opts) {
                  if(opts.hasOwnProperty(question)) {
                    var img = new Image(),
                    li = f.elements[question].parentElement,
                    feedbackImg = li.getElementsByTagName('img')[0];
    
                    if (feedbackImg){
                      li.removeChild(feedbackImg);
                    }
                    
                    if(opts[question].state === "correct"){
                      img.src = "http://www.littletherese.com/tick.jpg";
                      li.appendChild(img)
                    } else if(opts[question].state === "error"){
                      img.src = "http://www.littletherese.com/x.jpg";
                      li.appendChild(img)
                    }
                  }
                }
              }
              
              function displayScore(){
                var correct = 0,
                    error = 0,
                    score = document.getElementById("score"),
                    totalQuestions = Object.size(opts),
                    question;
    
                for (question in opts) {
                  if(opts.hasOwnProperty(question)) {
                    if(opts[question].state === "correct"){
                      correct ++
                    } else if(opts[question].state === "error"){
                      error ++
                    }
                  }
                }
                score.innerHTML = "You got " + correct + " out of " + totalQuestions;
              }
              
              function init(){
                validateInput();
                markCorrectOrIncorrect();
                displayScore();
              }
              
              init();
            }
          }());
    
          f.onsubmit = function(){
            checkAnswers({
              question1: {answer: "a"},
              question2: {answer: "a"},
              question3: {answer: "a"},
              question4: {answer: "a"},
              question5: {answer: "a"},
              question6: {answer: "a"},
              question7: {answer: "a"},
              question8: {answer: "a"},
              question9: {answer: "a"},
              question10: {answer: "a"}
            })
            return false;
          }
          
          f.reset.onclick = function(){
            location.reload();
          }
        </script> 
      </body>
    </html>
    This will work as a standalone example. You don't need any other libraries.
    I tested in the latest version of Chrome, Opera, FireFox, Safari (Win), as well as IE 7 - 10.

    If you add more questions, just modify the opts object passed to checkAnswers()
    The format is:

    Code:
    select element name, {answer: "option value of correct answer"}
    Please also note that it is better to use a <ol> (ordered list) to structure your questions.

    Hope that helps.


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
  •