]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-15543 - Display the quiz navigation on the attempt.php page
authortjhunt <tjhunt>
Fri, 11 Jul 2008 17:03:43 +0000 (17:03 +0000)
committertjhunt <tjhunt>
Fri, 11 Jul 2008 17:03:43 +0000 (17:03 +0000)
and most of

MDL-15540 - Write code to render the navigation panel - it does it all apart from working out the correct state in which to show each button, and apply appropriate styles as a result.

lang/en_utf8/quiz.php
mod/quiz/attempt.php
mod/quiz/attemptlib.php
mod/quiz/quiz.js
theme/standard/styles_layout.css

index e3aefdec6c3fe1b4ca7cb7a5205e02e423b7bf5e..cb4c3f01d41ab3052c422a566eb1496f5e712f94 100644 (file)
@@ -212,6 +212,7 @@ in course \'$a->coursename\'
 
 You can review this attempt at $a->quizreviewurl.';
 $string['emailnotifysubject'] = '$a->studentname has completed quiz $a->quizname';
+$string['endtest'] = 'End test ...';
 $string['errorinquestion'] = 'Error in question';
 $string['errormissingquestion'] = 'Error: The system is missing the question with id $a';
 $string['errornotnumbers'] = 'Error - answers must be numeric';
@@ -467,6 +468,7 @@ $string['quiznotavailable'] = 'The quiz will not be available until $a';
 $string['quizopen'] = 'Open the quiz';
 $string['quizopens'] = 'Quiz opens';
 $string['quizopenedon'] = 'This quiz opened at $a';
+$string['quiznavigation'] = 'Quiz navigation';
 $string['quizsettings'] = 'Quiz settings';
 $string['quiztimelimit'] = 'Time limit: $a';
 $string['quiztimer'] = 'Quiz Timer';
index 4508d5baccd621428ebf704eb1faffdd11cc42e2..c521d62a697b26d4694561b04ed9cff9a71ec53e 100644 (file)
 
     $attemptobj = new quiz_attempt($attemptid);
 
+/// Because IE is buggy (see http://www.peterbe.com/plog/button-tag-in-IE) we cannot
+/// do the quiz navigation buttons as <button type="submit" name="page" value="N">Caption</button>.
+/// Instead we have to do them as <input type="submit" name="gotopageN" value="Caption"/> -
+/// at lest that seemed like the least horrible work-around to me. Therefore, we need to
+/// intercept gotopageN parameters here, and adjust $pgae accordingly.
+    if (optional_param('gotosummary', false, PARAM_BOOL)) {
+        $page = -1;
+    } else {
+        $numpagesinquiz = $attemptobj->get_num_pages();
+        for ($i = 0; $i < $numpagesinquiz; $i++) {
+            if (optional_param('gotopage' . $i, false, PARAM_BOOL)) {
+                $page = $i;
+                break;
+            }
+        }
+    }
+
 /// We treat automatically closed attempts just like normally closed attempts
     if ($timeup) {
         $finishattempt = 1;
@@ -275,9 +292,17 @@ if ($page == -1) {
     }
     echo '<div>';
 
-/// Print the navigation panel if required
-    // TODO!!!
-    quiz_print_navigation_panel($page, $attemptobj->get_num_pages());
+/// Print the navigation panel in a left column.
+    print_container_start();
+    echo '<div id="left-column">';
+    $attemptobj->print_navigation_panel('quiz_attempt_nav_panel', $page);
+    echo '</div>';
+    print_container_end();
+
+/// Start the main column.
+    echo '<div id="middle-column">';
+    print_container_start();
+    echo skip_main_destination();
 
 /// Print all the questions
     foreach ($attemptobj->get_question_ids($page) as $id) {
@@ -285,13 +310,13 @@ if ($page == -1) {
     }
 
 /// Print a link to the next page.
-    echo "<div class=\"submitbtns mdl-align\">\n";
+    echo '<div class="submitbtns">';
     if ($attemptobj->is_last_page($page)) {
-        $nextpage = -1;
+        $nextpage = 'gotosummary';
     } else {
-        $nextpage = $page + 1;
+        $nextpage = 'gotopage' . ($page + 1);
     }
-    echo link_arrow_right(get_string('next'), 'javascript:navigate(' . $nextpage . ')');
+    echo '<input type="submit" name="' . $nextpage . '" value="' . get_string('next') . '" />';
     echo "</div>";
 
     // Finish the form
@@ -306,6 +331,13 @@ if ($page == -1) {
 
     echo "</form>\n";
 
+    // End middle column.
+    print_container_end();
+    echo '</div>';
+
+    echo '</div>';
+    echo '<div class="clearer"></div>';
+
     // Finish the page
     $accessmanager->show_attempt_timer_if_needed($attemptobj->get_attempt(), time());
     if ($accessmanager->securewindow_required($attemptobj->is_preview_user())) {
index 490ceba3071c1be099ecfb668fb30120a058b4d0..ac5d693f7abbb973f808dbf4d1e14ff21f6e9ab5 100644 (file)
@@ -165,7 +165,6 @@ class quiz {
      * @return object the question object with that id.
      */
     public function get_question($id) {
-        $this->ensure_question_loaded($id);
         return $this->questions[$id];
     }
 
@@ -254,7 +253,7 @@ class quiz {
      */
     public function attempt_url($attemptid) {
         global $CFG;
-        return $CFG->wwwroot . '/mod/quiz/attempt.php?attempt=' . $attemptid . '&amp;page=0';
+        return $CFG->wwwroot . '/mod/quiz/attempt.php?attempt=' . $attemptid;
     }
 
     /**
@@ -555,7 +554,7 @@ class quiz_attempt extends quiz {
      */
     public function attempt_url($questionid = 0, $page = -1) {
         global $CFG;
-        return $CFG->wwwroot . '/mod/quiz/attempt.php?attempt=' . $this->attempt->id . '&' .
+        return $CFG->wwwroot . '/mod/quiz/attempt.php?attempt=' . $this->attempt->id .
                 $this->page_and_question_fragment($questionid, $page);
     }
 
@@ -582,7 +581,7 @@ class quiz_attempt extends quiz {
         if (is_null($otherattemptid)) {
             $otherattemptid = $this->attempt->id;
         }
-        return $CFG->wwwroot . '/mod/quiz/review.php?attempt=' . $otherattemptid . '&' .
+        return $CFG->wwwroot . '/mod/quiz/review.php?attempt=' . $otherattemptid .
                 $this->page_and_question_fragment($questionid, $page, $showall);
     }
 
@@ -614,7 +613,11 @@ class quiz_attempt extends quiz {
         quiz_send_notification_emails($this->course, $this->quiz, $this->attempt,
                 $this->context, $this->cm);
     }
-    
+
+    public function print_navigation_panel($panelclass, $page) {
+        $panel = new quiz_attempt_nav_panel($this, $this->get_review_options(), $page);
+        $panel->display();
+    }
 
     // Private methods =====================================================================
     // Check that the state of a particular question is loaded, and if not throw an exception.
@@ -641,7 +644,7 @@ class quiz_attempt extends quiz {
      * @return string bit to add to the end of a URL.
      */
     private function page_and_question_fragment($questionid, $page, $showall = false) {
-        if ($page = -1) {
+        if ($page == -1) {
             if ($questionid) {
                 $page = $this->questions[$questionid]->_page;
             } else {
@@ -657,10 +660,9 @@ class quiz_attempt extends quiz {
         }
         $param = '';
         if ($showall) {
-            $param = 'showall=1';
-        } else if (/*$page > 1*/ true) {
-            // TODO currently needed by the navigate JS, but clean this up later.
-            $param = 'page=' . $page;
+            $param = '&showall=1';
+        } else if ($page > 0) {
+            $param = '&page=' . $page;
         }
         return $param . $fragment;
     }
@@ -722,4 +724,86 @@ class quiz_attempt_question_iterator implements Iterator {
         return $this->current() !== false;
     }
 }
+
+abstract class quiz_nav_panel_base {
+    protected $attemptobj;
+    protected $options;
+    protected $page;
+
+    protected function __construct(quiz_attempt $attemptobj, $options, $page) {
+          $this->attemptobj = $attemptobj;
+          $this->options = $options;
+          $this->page = $page;
+    }
+
+    protected function get_question_buttons() {
+        $html = '<div class="qn_buttons">';
+        foreach ($this->attemptobj->get_question_iterator() as $number => $question) {
+            $html .= $this->get_question_button($number, $question);
+        }
+        $html .= '</div>';
+        return $html;
+    }
+
+    abstract protected function get_question_button($number, $question);
+
+    abstract protected function get_end_bits();
+
+    protected function get_question_state($question) {
+        $state = 'todo'; // TODO
+        if ($question->_page == $this->page) {
+            $state .= ' thispage';
+        }
+        return $state;
+    }
+
+    public function display() {
+        $strquiznavigation = get_string('quiznavigation', 'quiz');
+        $content = $this->get_question_buttons() . $this->get_end_bits();
+        print_side_block($strquiznavigation, $content, NULL, NULL, '', array('id' => 'quiznavigation'), $strquiznavigation);
+    }
+}
+
+class quiz_attempt_nav_panel extends quiz_nav_panel_base {
+    public function __construct(quiz_attempt $attemptobj, $options, $page) {
+        parent::__construct($attemptobj, $options, $page);
+    }
+
+    protected function get_question_button($number, $question) {
+        $questionsonpage = $this->attemptobj->get_question_ids($question->_page);
+        $onclick = '';
+        if ($question->id != reset($questionsonpage)) {
+            $onclick = ' onclick="form.action = form.action + \'#q' . $question->id .
+                '\'; return true;"';
+        }
+        return '<input type="submit" name="gotopage' . $question->_page .
+                '" value="' . $number . '" class="qnbutton ' .
+                $this->get_question_state($question) . '"' . $onclick . '/>';
+    }
+
+    protected function get_end_bits() {
+        return '<input type="submit" name="gotosummary" value="' .
+                get_string('endtest', 'quiz') . '" class="endtestlink" />';
+    }
+}
+
+class quiz_review_nav_panel extends quiz_nav_panel_base {
+    public function __construct(quiz_attempt $attemptobj, $options, $page) {
+        parent::__construct($attemptobj, $options, $page);
+    }
+
+    protected function get_question_button($number, $question) {
+        return '<a href="' . $this->attemptobj->review_url($question->id) .
+                '" class="qnbutton ' . $this->get_question_state($question) .
+                '">' . $number . '</a>';
+    }
+
+    protected function get_end_bits() {
+        $html = '<a href="' . $this->attemptobj->review_url(0, 0, true) . '">' .
+                get_string('showall', 'quiz') . '</a>';
+        $html .= '<a href="' . $this->attemptobj->view_url() . '">' .
+                get_string('finishreview', 'quiz') . '</a>';
+        return $html;
+    }
+}
 ?>
\ No newline at end of file
index 2ced50fc1c99f5cc8f7f2cdb6fc3572136a4da12..6201bbffecda1ffdfc2ffe058076f47a4728ed36 100644 (file)
@@ -6,16 +6,6 @@
  * @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) {
index 6741f441983ff22f71055c5e2c0684dd0df0bed8..5df23df9e05eff60f99785954adc93eafb366be1 100644 (file)
@@ -2562,7 +2562,6 @@ body.notes .notesgroup {
   text-align: left;
   margin: 0 auto 1.8em auto;
   border: 1px solid;
-  clear: both;
 }
 .que .info {
   float: left;
@@ -3818,14 +3817,21 @@ body#mod-forum-search .introcontent {
 #passwordform {
   margin: 1em 0;
 }
-#mod-quiz-attempt #page {
+#mod-quiz-attempt #middle-column {
   text-align: center;
 }
 #mod-quiz-attempt .pagingbar {
   margin: 1.5em auto;
 }
-#mod-quiz-attempt #page {
-    text-align: center;
+#mod-quiz-attempt #middle-column {
+  margin: 0 0 0 12.5em;
+}
+#mod-quiz-attempt #left-column {
+  width: 11.5em;
+  float: left;
+}
+#mod-quiz-attempt .submitbtns {
+  text-align: left;
 }
 
 #mod-quiz-attempt #quiz-timer-outer {
@@ -4048,6 +4054,26 @@ table.quizreviewsummary td.cell {
   text-align: center;
   margin: 6px 0;
 }
+
+#quiznavigation input.qnbutton {
+  border: 1px solid grey;
+  background: white;
+  font-weight: bold;
+  width: 1.5em;
+  height: 1.5em;
+  margin-right: 0.3em;
+  text-align: middle;
+}
+#quiznavigation input.qnbutton:hover {
+  background: silver;
+}
+#quiznavigation .qn_buttons {
+  margin: 0.2em;
+}
+#quiznavigation input.qnbutton.thispage {
+  background: #eee;
+}
+
 /***
  *** Modules: Resource
  ***/