Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 8 of 8
  1. #1
    New to the CF scene
    Join Date
    Jan 2013
    Posts
    2
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Trying to create a simple Multiple Choice game.

    My function that lists the question and choices won't work. I keep getting the error code 'document.getElementById(...)' is null or not an object. The syntax appears to be correct.

    I want the questions and choices to appear in the same divs. I do not want to list all my questions at once. When the user completes a question, they then move on to the next question which will appear in exactly the same divs as the first question until all the questions have been seen.

    Code:
     <script>
    
    var questions = new Array();
    questions[0] = 'Is there a difference between a jungle and a rain forest?'
    questions[1] = 'What is the world\'s most common religion?',
    questions[2] = 'What is the second largest country (in size) in the world?';
    
    var choices = new Array();
    choices[0] = ['No difference', 'Some difference', 'Completely different'],
    choices[1] = ['Christianity', 'Buddhism', 'Hinduism', 'Islam'],
    choices[2] = ['USA', 'China', 'Canada', 'Russia'];
    
    var answers = new Array();
    answers[0] = ['Some difference'],
    answers[1] = ['Christianity'],
    answers[2] = ['Canada'];
    
    var score = 0;
    i= 0;
    
    var listQuestion = function(){  
    if(i<questions.length){
    document.getElementById("myDiv1").innerHTML = '<p>'+questions[i]+'</p>';
    for (k=0; k<choices[i].length; k++){
    document.getElementById("myDiv2").innerHTML ='<p><input type = "radio" name = "questionchoice">'+choices[i][k]+'</p>';
    }
    document.getElementById("myDiv3").innerHTML = '<p><button onClick = "getRadioValue()">Check</button></p> <br>';
    };
    };
    
    
    
    var getRadioValue = function()
    {
        for (var h = 0; h < document.getElementsByName('questionchoice').length; h++)
        {
            var value = '';
    
            if (document.getElementsByName('questionchoice')[h].checked==true)
            {
                value = document.getElementsByName('questionchoice')[h].value;
    
    
        score+=1        
    
    }
        }
    if (value== answers[i]){
        document.getElementById("myDiv4").innerHTML ="That is correct. </br><button input type = 'submit' onClick = 'loadContent()'> Next Question</button>";   
    }
    
    else {
    
    document.getElementById("myDiv4").innerHTML ="That is incorrect. </br><button input type = 'submit' onClick = 'loadContent()'> Next Question</button>"; 
    
        }
    i++;
    };
    
    
    var whatIsScore = function(){
    
    return score; 
    
    }
    window.onload = listQuestion();
    
    </script>
    
    </head>
    
    <body>
    <div id="myDiv1"></div> 
    <div id="myDiv2"></div>
    <div id="myDiv3"></div>
    <div id="myDiv4"></div>
    
    
    </body>

  • #2
    Senior Coder Logic Ali's Avatar
    Join Date
    Sep 2010
    Location
    London
    Posts
    1,028
    Thanks
    0
    Thanked 207 Times in 202 Posts
    The address of a function is specified by its name alone:

    window.onload = listQuestion;

  • #3
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,519
    Thanks
    77
    Thanked 4,381 Times in 4,346 Posts
    Ummm...

    Code:
       ... onClick = 'loadContent()' ...
    Where, pray tell, is your loadContent function?
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #4
    Senior Coder jmrker's Avatar
    Join Date
    Aug 2006
    Location
    FL
    Posts
    3,086
    Thanks
    38
    Thanked 498 Times in 492 Posts

    Lightbulb

    Not necessarily the way I would do it, but trying to use most of your code ...
    Code:
    <html>
    <head>
    <title>MC Quiz</title>
    </head>
    <body>
    <div id="myDiv1"></div> 
    <div id="myDiv2"></div>
    <div id="myDiv4" style="color:red; font-size:2em;"></div>
    
    <button input type = 'submit' onClick='qno++; return listQuestion()'> Next Question</button> 
    <button onClick = "getRadioValue()">Check Answer</button> 
    <button onClick = "whatIsScore()">Check Score</button>
    <p /> 
    
    <script type="text/javascript">
    // From: http://www.codingforums.com/showthread.php?t=285546
    
    var questions = [];
    questions[0] = 'Is there a difference between a jungle and a rain forest?'
    questions[1] = 'What is the world\'s most common religion?',
    questions[2] = 'What is the second largest country (in size) in the world?';
    
    var choices = [];
    choices[0] = ['No difference', 'Some difference', 'Completely different'],
    choices[1] = ['Christianity', 'Buddhism', 'Hinduism', 'Islam'],
    choices[2] = ['USA', 'China', 'Canada', 'Russia'];
    
    var answers = [1,0,2];
    var score = 0;
    var qno = 0;
    
    var listQuestion = function(){  
      if (qno < questions.length) {
        document.getElementById('myDiv1').innerHTML = '';
        document.getElementById('myDiv2').innerHTML = '';
        document.getElementById('myDiv4').innerHTML = '';
    
        if (qno < questions.length){
          document.getElementById("myDiv1").innerHTML = '<p>'+questions[qno]+'</p>';
          for (k=0; k<choices[qno].length; k++){
            document.getElementById("myDiv2").innerHTML
              += '<p><input type="radio" name="questionchoice"'
              + ' value="'+k+'">'+choices[qno][k]+'</p>';
          }
        } 
        return true; 
      } else { alert('End of quiz'); return false; }
    };
    
    
    function getRBtnName(GrpName) {
      var sel = document.getElementsByName(GrpName);
      var fnd = -1;
      var str = '';
      for (var i=0; i<sel.length; i++) {
        if (sel[i].checked == true) { str = sel[i].value;  fnd = i; }
      }
    //  return fnd;   // return option index of selection
    // comment out next line if option index used in line above  
      return str;
    } 
    
    var getRadioValue = function() {
      var msg = 'That is CORRECT.';
      var picked = getRBtnName('questionchoice'); 
      if (picked == answers[qno]) { score += 1; }
                             else { msg = 'That is INCORRECT.' }
      document.getElementById("myDiv4").innerHTML = msg;
    };
    
    
    var whatIsScore = function() { alert('Score: '+score); return score; }
    window.onload = function() { listQuestion(); }
    </script>
    
    </body>
    </html>
    Note some of the significant differences to your code.
    Good Luck!

  • Users who have thanked jmrker for this post:

    hoshangc (01-10-2013)

  • #5
    New to the CF scene
    Join Date
    Jan 2013
    Posts
    2
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Thanks jmrker. It works.

    Thanks jmrker. It works.

    Can you please help me understand why we would need “var fnd = -1” for the option index of the selection? Also why did you choose -1?

    Also, in question 2, when you click Check Answer without checking anything you get “That is CORRECT.”, which, of course, is incorrect. When you click check answer without checking anything in the other questions, you get “That is INCORRECT.”, which, of course is the right answer. So why is question 2 doing this? Can you please help explain this?

    Thanks,

    Hoshang

  • #6
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,519
    Thanks
    77
    Thanked 4,381 Times in 4,346 Posts
    How about a more general approach?
    Code:
    <!DOCTYPE html>
    <html>
    <head>
    <title>Quiz</title>
    <style type="text/css">
    div#question {
        font-size: x-large;
    }
    div#answers, div#answers label {
        font-size: large;
    }
    div#result {
        font-size: x-large;
        color: #FF0000;
    }
    </style>
    </head>
    <body>
    <div>
        <form action="">
            <div id="question"></div>
            <div id="answers"></div>
            <div id="result">&nbsp;</div>
            <input type="button" id="checkAnswer" value="Check my answer"/><hr/>
            <input type="button" id="next" value="Next question" />
        </form>
    </div>
    
    <script type="text/javascript">
    var questions = [
        ['Is there a difference between a jungle and a rain forest?',
         'No difference', '*Some difference', 'Completely different' ],
        ['What is the world\'s most common religion?',
         '*Christianity', 'Buddhism', 'Hinduism', 'Islam'],
        ['What is the second largest country (in size) in the world?',
         'USA', 'China', '*Canada', 'Russia']
    ];
    
    var qdiv = document.getElementById("question");
    var adiv = document.getElementById("answers");
    var rdiv = document.getElementById("result");
    var questionCount = questions.length;
    
    var currentQuestion = 0;
    var currentAnswer;
    var correct = 0;
    var alredyAnswered = false;
    
    function nextQuestion( )
    {
        if ( currentQuestion >= questionCount )
        {
            rdiv.innerHTML = "You answered " + correct + " question(s) " 
                           + "out of " + questionCount + " correctly on the first try.";
            return;
        }
        var curq = questions[currentQuestion];
        var cura = curq.slice(1).sort( function() { return Math.random() - 0.7; } );
        qdiv.innerHTML = curq[0];
        while ( adiv.firstChild != null ) 
        { 
            adiv.removeChild( adiv.firstChild ); 
        }
        for ( var a = 0; a < cura.length; ++a )
        {
            var ans = cura[a];
            if ( ans.charAt(0) == "*" )
            {
                ans = ans.substring(1);
                currentAnswer = ans; 
            }
            var lbl = document.createElement("label");
            var rb = document.createElement("input");
            rb.type = "radio";
            rb.name = "rbanswer";
            rb.value = ans;
            lbl.appendChild(rb);
            lbl.appendChild( document.createTextNode(ans) );
            adiv.appendChild(lbl);
        }
        rdiv.innerHTML = "&nbsp;";
        alreadyAnswered = false;
        ++currentQuestion;
    }
    
    document.getElementById("checkAnswer").onclick =
        function()
        {
            var rbs = this.form.rbanswer;
            for ( var r = 0; r < rbs.length; ++r )
            {
                var rb = rbs[r];
                if ( rb.checked )
                {
                    if ( rb.value == currentAnswer )
                    {
                        rdiv.innerHTML = "That is correct.";
                        if ( ! alreadyAnswered ) ++correct;
                    } else {
                        rdiv.innerHTML = "Sorry, the correct answer is "
                                       + currentAnswer;
                    }
                    alreadyAnswered = true;
                    return;
                }
            }
            rdiv.innerHTML = "You did not check any answer...try again";
        };
    document.getElementById("next").onclick = nextQuestion;
             
    
    // start things off:
    nextQuestion();
    </script>
    </body>
    </html>
    This simplifies your array of question and answers. The "*" in an answer indicates it is the right one. The code scrambles the answers, so they aren't always in the same order, and of course strips the "*" before showing the answers. It simply remembers the current correct answer in a JS variable.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #7
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,519
    Thanks
    77
    Thanked 4,381 Times in 4,346 Posts
    Oh, and the code shows the better way to plunk those radio buttons down in the answers <div>, as opposed to using innerHTML.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • Users who have thanked Old Pedant for this post:

    hoshangc (01-11-2013)

  • #8
    Senior Coder jmrker's Avatar
    Join Date
    Aug 2006
    Location
    FL
    Posts
    3,086
    Thanks
    38
    Thanked 498 Times in 492 Posts

    Lightbulb

    Quote Originally Posted by hoshangc View Post
    Thanks jmrker. It works.

    Can you please help me understand why we would need “var fnd = -1” for the option index of the selection? Also why did you choose -1?

    Also, in question 2, when you click Check Answer without checking anything you get “That is CORRECT.”, which, of course, is incorrect. When you click check answer without checking anything in the other questions, you get “That is INCORRECT.”, which, of course is the right answer. So why is question 2 doing this? Can you please help explain this?

    Thanks,

    Hoshang
    'Old Pedant's code is probably a bit more flexible in the long run,
    but as I said before I was trying to use as much of your code as possible for you to see the changes I proposed.
    If I had started from scratch, my own code might be different still.

    Concerning the function in question, you should change it to this:
    Code:
    function getRBtnName(GrpName) {
      var sel = document.getElementsByName(GrpName);
      var fnd = -1;
      var str = '';
      for (var i=0; i<sel.length; i++) {
        if (sel[i].checked == true) { str = sel[i].value;  fnd = i; }
      }
      return fnd;   // return option index of selection
    // comment out next line if option index used in line above  
    //  return str;
    }
    It returns the number of the radio button selection which, when checked, would return 0...(n-1) where (n-1) is the number of selections available.
    The use of the -1 is not a value that will be returned if a selection is made.
    If no selections are made, the return value is -1 which will NOT match any of the answers array elements, hence the 'incorrect' message.

    In the original code, I neglected to change the return value of the function
    to match the values you set in the answers array.
    I was originally going to use the string returned in the function to match you original answer array contents.
    I modified the answer array to make it easier to test, but forgot to alter the value returned by the function as well.
    That is why it was giving the wrong message when the answer was analyzed.
    Last edited by jmrker; 01-11-2013 at 03:24 AM.


  •  

    LinkBacks (?)


    Tags for this Thread

    Posting Permissions

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