]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-8682: Pressing enter when answering a short answer question can submit the wrong...
authortjhunt <tjhunt>
Wed, 26 Sep 2007 18:15:31 +0000 (18:15 +0000)
committertjhunt <tjhunt>
Wed, 26 Sep 2007 18:15:31 +0000 (18:15 +0000)
MDL-9451: Quiz answers can be lost if user navigates before page reloads. I am not totally sure I have fixed this, but I hope so. I moved the printing of the hidden form field with the list of questions on the page to the end of the form, so no answers will be processed unless the whole form loaded. Note that you could still lose data, but only if the page takes a really long time to load and you answer the first question and click submit before the whole quiz is loaded.

MDL-11463: The quiz uses two different timers, which is silly. I have removed the javascript that was ocasionally used to put a timer in the browser's title bar. Now we only use the one in the page for all cases.

Because MDL-8682 also needed javascript, I renamed timer.js to quiz.js so it could be a library of all the quiz's JavaScript, and started including it properly with require_js.

mod/quiz/attempt.php
mod/quiz/jsclock.php [deleted file]
mod/quiz/jstimer.php
mod/quiz/quiz.js [moved from mod/quiz/timer.js with 61% similarity]

index 3adf67031202002d4010fed054923ffee5c1add7..3f0fd0266c9ed1d7d656ce38840ff9dda2045436 100644 (file)
 /// Print the quiz page ////////////////////////////////////////////////////////
 
     // Print the page header
+    require_js($CFG->wwwroot . '/mod/quiz/quiz.js');
     $pagequestions = explode(',', $pagelist);
     $headtags = get_html_head_contributions($pagequestions, $questions, $states);
     if (!empty($popup)) {
 
     // Start the form
     echo '<form id="responseform" method="post" action="attempt.php?q=', s($quiz->id), '&amp;page=', s($page),
-            '" enctype="multipart/form-data" onclick="this.autocomplete=\'off\'">', "\n";
+            '" enctype="multipart/form-data"' .
+            ' onclick="this.autocomplete=\'off\'" onkeypress="return check_enter(event);">', "\n";
     if($quiz->timelimit > 0) {
         // Make sure javascript is enabled for time limited quizzes
         ?>
         <script type="text/javascript">
-            // Do nothing.
+            // Do nothing, but you have to have a script tag before a noscript tag.
         </script>
         <noscript>
         <div>
         </noscript>
         <?php
     }
-
-    // Add a hidden field with the quiz id
     echo '<div>';
 
 /// Print the navigation panel if required
     $numpages = quiz_number_of_pages($attempt->layout);
     if ($numpages > 1) {
-        ?>
-        <script type="text/javascript">
-        //<![CDATA[
-        function navigate(page) {
-            var ourForm = document.getElementById('responseform');
-            ourForm.action = ourForm.action.replace(/page=.*/, 'page=' + page);
-            if (ourForm.onsubmit) {
-                ourForm.onsubmit();
-            }
-            ourForm.submit();
-        }
-        //]]>
-        </script>
-        <?php
         quiz_print_navigation_panel($page, $numpages);
     }
 
 /// Print all the questions
-
-    // Add a hidden field with questionids
-    echo '<input type="hidden" name="questionids" value="'.$pagelist."\" />\n";
-
     $number = quiz_first_questionnumber($attempt->layout, $pagelist);
     foreach ($pagequestions as $i) {
         $options = quiz_get_renderoptions($quiz->review, $states[$i]);
     // Finish the form
     echo '</div>';
     echo '<input type="hidden" name="timeup" id="timeup" value="0" />';
+
+    // Add a hidden field with questionids. Do this at the end of the form, so 
+    // if you navigate before the form has finished loading, it does not wipe all
+    // the student's answers.
+    echo '<input type="hidden" name="questionids" value="'.$pagelist."\" />\n";
+
     echo "</form>\n";
 
-    $secondsleft = ($quiz->timeclose ? $quiz->timeclose : 999999999999) - time();
-    if ($ispreviewing) {
-        // For teachers ignore the quiz closing time
-        $secondsleft = 999999999999;
+    // If the quiz has a time limit, or if we are close to the close time, include a floating timer.
+    $showtimer = false;
+    $timerstartvalue = 999999999999;
+    if ($quiz->timeclose) {
+        $timerstartvalue = min($timerstartvalue, $quiz->timeclose - time());
+        $showtimer = $timerstartvalue < 60*60; // Show the timer if we are less than 60 mins from the deadline.
     }
-
-    // If time limit is set include floating timer.
-    // MDL-7495, no timer for users with disability
     if ($quiz->timelimit > 0 && !has_capability('mod/quiz:ignoretimelimits', $context, NULL, false)) {
-        $timesincestart = time() - $attempt->timestart;
-        $timerstartvalue = min($quiz->timelimit*60 - $timesincestart, $secondsleft);
-        if ($timerstartvalue <= 0) {
-            $timerstartvalue = 1;
-        }
-
+        $timerstartvalue = min($timerstartvalue, $attempt->timestart + $quiz->timelimit*60- time());
+        $showtimer = true;
+    }
+    if ($showtimer && (!$ispreviewing || $timerstartvalue > 0)) {
+        $timerstartvalue = max($timerstartvalue, 1); // Make sure it starts just above zero.
         require('jstimer.php');
-    } else {
-        // Add the javascript timer in the title bar if the closing time appears close
-        if ($secondsleft > 0 and $secondsleft < 24*3600) {  // less than a day remaining
-            include('jsclock.php');
-        }
     }
 
     // Finish the page
diff --git a/mod/quiz/jsclock.php b/mod/quiz/jsclock.php
deleted file mode 100644 (file)
index ca2ff1c..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-<?php // $Id$
-defined('MOODLE_INTERNAL') or die('Direct access to this script is forbidden.');
-?>
-
-<script text="text/javascript">
-//<![CDATA[
-/// This Javascript clock provides a little countdown in the title bar
-
-var timerID = null;
-var timerRunning = false;
-var secondsleft = <?php echo $secondsleft ?>;
-var titleafter  = '<?php echo format_string($quiz->name) ?>';
-var titlebefore = '<?php echo get_string("countdown", "quiz").": " ?>';
-var alertmessage  = '<?php print_string("countdownfinished", "quiz") ?>';
-var alertmessage10  = '<?php print_string("countdowntenminutes", "quiz") ?>';
-
-function stopclock() {
-    if (timerRunning) {
-        clearTimeout(timerID);
-        timerRunning = false;
-    }
-}
-
-function startclock() {
-    stopclock();
-    showtime();
-}
-
-function showtime() {
-
-    secondsleft = secondsleft - 1;
-
-    if (secondsleft == 600) {
-        alert(alertmessage10);
-    }
-
-    if (secondsleft == 0) {
-        stopclock();
-        document.title = titleafter;
-        return alert(alertmessage);
-
-    } else {
-        current = secondsleft;
-
-        var hours = Math.floor( current / 3600 );
-        current = current - (hours*3600);
-
-        var minutes =   Math.floor( current / 60 );
-        current = current - (minutes*60);
-
-        var seconds = current;
-
-        var timeValue = "" + hours;
-        timeValue  += ((minutes < 10) ? ":0" : ":") + minutes;
-        timeValue  += ((seconds < 10) ? ":0" : ":") + seconds;
-
-        document.title = titlebefore+timeValue+' '+titleafter;
-        timerID = setTimeout("showtime()",1000);
-        timerRunning = true;
-    }
-}
-
-document.onLoad = startclock();
-
-
-//]]>
-</script>
index adc64340256db4e564c32ebe29b4de4f69888bff..dc3183bf9a17909fd6f5caa71d7e73e31120d39a 100644 (file)
@@ -20,7 +20,6 @@ var ec_quiz_finish = ec_page_start + <?php echo ($timerstartvalue * 1000); ?>;
 
 //]]>
 </script>
-<script type="text/javascript" src="timer.js"></script>
 <div id="timer">
 <!--EDIT BELOW CODE TO YOUR OWN MENU-->
 <table class="generalbox" border="0" cellpadding="0" cellspacing="0" style="width:150px;">
similarity index 61%
rename from mod/quiz/timer.js
rename to mod/quiz/quiz.js
index b21b57f113eaa0714db52bb47dd1da8af6a4bf72..f7e24e6188090f5f777bd555cffadeb2793ddc62 100644 (file)
@@ -1,9 +1,34 @@
-// $Id$
-//
-// QuizTimer
-// Provides a counter that keeps track how much
-// time user have left to check in started quiz.
-//
+/*
+ * JavaScript library for the quiz module.
+ *
+ * (c) The Open University and others.
+ * @author T.J.Hunt@open.ac.uk and others.
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ */
+
+/* Used by quiz navigation links to force a form submit, and hence save the user's data. */
+function navigate(page) {
+    var ourForm = document.getElementById('responseform');
+    ourForm.action = ourForm.action.replace(/page=.*/, 'page=' + page);
+    if (ourForm.onsubmit) {
+        ourForm.onsubmit();
+    }
+    ourForm.submit();
+}
+
+/* Use this in an onkeypress handler, to stop enter submitting the forum unless you 
+are actually on the submit button. Don't stop the user typing things in text areas. */
+function check_enter(e) {
+    var target = e.target ? e.target : e.srcElement;
+    var keyCode = e.keyCode ? e.keyCode : e.which;
+
+    if(keyCode==13 && (!target.type || (target.type!='submit' && target.type!='textarea')))
+        return false;
+    else
+        return true;
+}
+
+/* Used to update the on-screen countdown clock for quizzes with a time limit */
 function countdown_clock(theTimer) {
     var timeout_id = null;
 
@@ -42,6 +67,7 @@ function countdown_clock(theTimer) {
     timeout_id = setTimeout("countdown_clock(theTimer)", 1000);
 }
 
+/* Use to keep the quiz timer on-screen as the user scrolls. */
 function movecounter(timerbox) {
     var pos;
 
@@ -63,4 +89,4 @@ function movecounter(timerbox) {
     }
     old = pos;
     temp = setTimeout('movecounter(timerbox)',100);
-}
\ No newline at end of file
+}