0

I have been playing around with this code for far too long. The code worked fine at first, but when I tried to validate under strict I got a "name" attribute in the form element not valid, so I took it out. Now its keeps saying that document.quiz is not declared. Not sure how to declare of if I should change the .JS file. Any help would be great.

<head>
   <title>Online Aptitude Quiz: Page</title>
   <link href="./styles/quiz.css" rel="stylesheet" type="text/css" />



<script type="text/javascript" src="./scripts/functions.js"></script> 
<script type="text/javascript">

    var seconds = 0;
    var clockId;
    var quizclock;
    

    function runClock() {
    seconds++;
    document.quiz.quizclock.value= seconds;
    
}
    function startClock() {
    showQuiz();
    clockId = setInterval ("runClock()",1000);
}

    var timer;

    function stopClock() {
    clearInterval (clockId);
    correctAns = gradeQuiz();
    alert( "You have " + correctAns + " correct of 5 in " + seconds + " seconds.");
}
</script></head>
<body>

<form id="quiz" action ="">

<div id="header">
   <p><img src="./images/oae.jpg" alt="Online Aptitude Exam" />
   <span>Grunwald Testing, Inc.</span><br />
   1101 Science Drive<br />
   Oakdale, CA 88191
   </p>
</div>

<div id="intro">
   <p>This is a timed quiz of intelligence and perception. Your final score will
   be based on the number of correct answers and the time required to submit those
   answers.</p>
   <p>To start the quiz, click the <b>Start Quiz</b> button below, which will 
   reveal the first page of quiz questions and start the timer. When you have 
   completed the questions, click the <b>Submit Answers</b> button on the quiz 
   form.</p>

   <p id="buttons">
      <input type="button" onclick="startClock()" value="Start Quiz" />
      <br />
      <input id="quizclock" name="quizclock" value="0" />
   </p>
</div>

<div id="questions">
   <h1>Page 1: Pattern Recognition</h1>
   <table id="quiztable">
   <tr>
      <th rowspan="3">1.</th>
      <td colspan="2">Enter the next number in this sequence: 1, 3, 4, 7, 11, 18, ...</td>
   </tr>
   <tr>
      <td><input type="radio" name="q1" />a) 22</td>
      <td><input type="radio" name="q1" />c) 28</td>
   </tr>
   <tr>
      <td id="cor1"><input type="radio" name="q1" />b) 29</td>
      <td><input type="radio" name="q1" />d) 32</td>
   </tr>
   <tr>
      <th rowspan="3">2.</th>
      <td colspan="2">Enter the final three numbers in this sequence: 8, 5, 4, 9, 1, 7, 6, ...</td>
   </tr>
   <tr>
      <td id="cor2"><input type="radio" name="q2" />a) 10, 3, 2</td>
      <td><input type="radio" name="q2" />c) 2, 3, 10</td>
   </tr>
   <tr>
      <td><input type="radio" name="q2" />b) 2, 10, 3</td>
      <td><input type="radio" name="q2" />d) 10, 2, 3</td>
   </tr>
   <tr>
      <th rowspan="3">3.</th>
      <td colspan="2">Enter the next letter in this sequence: j, f, m, a, m, j, j, ...</td>
   </tr>
   <tr>
      <td><input type="radio" name="q3" />a) j</td>
      <td><input type="radio" name="q3" />c) f</td>
   </tr>
   <tr>
      <td><input type="radio" name="q3" />b) m</td>
      <td id="cor3"><input type="radio" name="q3" />d) a</td>
   </tr>
   <tr>
      <th rowspan="3">4.</th>
      <td colspan="2">What letter in this set does not belong?: A, B, D, G, J, S, O</td>
   </tr>
   <tr>
      <td id="cor4"><input type="radio" name="q4" />a) A</td>
      <td><input type="radio" name="q4" />c) J</td>
   </tr>
   <tr>
      <td><input type="radio" name="q4" />b) B</td>
      <td><input type="radio" name="q4" />d) O</td>
   </tr>
   <tr>
      <th rowspan="3">5.</th>
      <td colspan="2">What is the next figure in the following sequence?:<br />
         <img src="./images/figures.jpg" alt="" />
      </td>
   </tr>
   <tr>
      <td><input type="radio" name="q5" />a) <img src="./images/figa.jpg" alt="" /></td>
      <td><input type="radio" name="q5" />c) <img src="./images/figc.jpg" alt="" /></td>
   </tr>
   <tr>
      <td><input type="radio" name="q5" />b) <img src="./images/figb.jpg" alt="" /></td>
      <td id="cor5"><input type="radio" name="q5" />d) <img src="./images/figd.jpg" alt="" /></td>
   </tr>
   <tr>
      <td style="text-align: center;" colspan="3">
           
         <hr />
         <input type="button" onclick="stopClock()" value="Submit Answers" />
         
      </td>
   </tr>
   </table>
</div>

</form>

<p>
    <a href= "../index.html">Home</a>
</p>
</body>
</html>

And her is the .JS file

nction showQuiz() {
   document.getElementById("quiztable").style.visibility="visible";
}

function hideQuiz() {
   document.getElementById("quiztable").style.visibility="hidden";
}

function gradeQuiz() {
   correct=0;
   if (document.quiz.q1[2].checked) correct++;
   if (document.quiz.q2[0].checked) correct++;
   if (document.quiz.q3[3].checked) correct++;
   if (document.quiz.q4[0].checked) correct++;
   if (document.quiz.q5[3].checked) correct++;
   
   document.getElementById("cor1").style.backgroundColor="yellow";
   document.getElementById("cor2").style.backgroundColor="yellow";
   document.getElementById("cor3").style.backgroundColor="yellow";
   document.getElementById("cor4").style.backgroundColor="yellow";
   document.getElementById("cor5").style.backgroundColor="yellow";

   for (i=0; i<document.quiz.elements.length; i++) document.quiz.elements[i].disabled=true;

   return correct;
}
3
Contributors
5
Replies
7
Views
7 Years
Discussion Span
Last Post by Airshow
0

Nikc,

Many folks use document.formName ; it's thoroughly reliable. I stopped using validators a while back. They are oft-times more trouble than they are worth. What really matters is whether or not the code works, cross-browser, not conformance with a standard that the browsers are supposed to comply with.

If, for the sake of the exercise, your code must validate then you can address the form as document.getElementById('quiz') or document.forms[0] without setting a name.

Your clock can be started and run in one hit like this:

function startClock(){
    showQuiz();
    var clockField = document.forms[0].quizclock;
    clockId = setInterval (function(){ clockField.value = ++seconds; }, 1000);
}

This is more efficient than runClock() as the clock field only needs to be found (in the DOM) once. Thereafter a reference to the clock field remains available to the anonymous setinterval function via a neat javascript feature known as "closure", despite startClock having completed and returned!

Incidentally, I have reservations over the use of setInterval/setTimeout for timers, though they do hold up pretty well for maybe 10 minutes or more (depending on many factors including processor loading). It's better to use a timer with an underlying start time based on new Date() . Thereafter timer time is calculated by subtraction. Thus, even if the update interval is compromised, the indicated time can never be out by more than the update period (1 second in this case). See my comments and code in post 6 here

Airshow

Edited by Airshow: n/a

0

Airshow. I tried your function and still a no go..Not sure what else to try, now my timer will not start when I hit start quiz. The questions show up and you can click on the button for the answer but then the submit button doesnt show the results either. Any further help would be really great...Thanks

0

Nikc,

If I make a web page from the HTML and javascript in your OP and paste in my suggested version of startClock , then it works. I added a doctype but it shouldn't make any difference to this page :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

As far as I can see, the only thing that might prevent the clock from working would be another form on the page above "quiz". document.form[0] addresses the first form on the page.

The reason you don't see the answers all yellowed up is because gradeQuiz needs to address the form elements with document.getElementById('quiz')..... or document.form[0]..... , same as in startClock .

if (document.forms[0].q1[2].checked) correct++;
   //etc.

I have tested only in IE but FF/Opera/Chrome should be OK too.

Airshow

0

In your ORIGINAL code, instead of document.quiz , try using document.[B]forms.[/B]quiz (since you have <form id="quiz"...> )

Edited by hielo: n/a

0

A litte food for thought .....

... try using document.[B]forms.[/B]quiz ...

I tend to avoid this formulation because there are (at least in older browsers) potential cross-browser issues.

Some browsers prefer name over id and some id over name despite W3C being quite specific. As with most things, it's IE versus the rest of the world.

You have to be pretty dumb (or just unlucky) but I have encoutered confusion in a complex document (built with includes) where two programmers had inadvertently given one element in a collection an id which was the same as the name of another element in the same collection.

Without generating any javascript errors, IE did one thing and FF etc did another. It took a while to track down the bug.

Similarly .... although I suggest using document.forms[0]... , this can also cause a problem. Say you (or more likely another programmer at a later date) adds another form above your form? That form will then be document.forms[0] , your form will be document.forms[1] and your javascript will be rendered invalid. This is unlikely to happen with forms (there's generally only one per page) but more likely with other types of element that can also be addressed as members of a collection.

The safest approach is to use document.getElementById as it is immune from name/id conflicts (though clearly not from id/id conflicts) and also immune from additions above.

I have made this point (less extensively) on Daniweb before and was reminded that, in a document with many many DOM nodes, document.getElementById will be significantly less efficient than addressing by collection. This is also a valid point of view.

Airshow

Edited by Airshow: n/a

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.