From c752264fe1fea6a1aa1ed45acd23b1d4cedc3754 Mon Sep 17 00:00:00 2001 From: tjhunt Date: Wed, 3 Sep 2008 02:35:56 +0000 Subject: [PATCH] MDL-16263 Flagging questions during a quiz attempt. Update flag state in the navigtion panel when it is updated on the question. --- mod/quiz/attemptlib.php | 29 +++++++++++++++++++++-------- mod/quiz/quiz.js | 20 ++++++++++++++++++++ question/qengine.js | 28 +++++++++++++++++++++++++++- 3 files changed, 68 insertions(+), 9 deletions(-) diff --git a/mod/quiz/attemptlib.php b/mod/quiz/attemptlib.php index 0c740d4ef6..af6e33ba9b 100644 --- a/mod/quiz/attemptlib.php +++ b/mod/quiz/attemptlib.php @@ -800,14 +800,26 @@ abstract class quiz_nav_panel_base { } protected function get_question_buttons() { - $html = '
'; + $html = '
' . "\n"; foreach ($this->attemptobj->get_question_iterator() as $number => $question) { - $html .= $this->get_question_button($number, $question); + $html .= $this->get_question_button($number, $question) . "\n" . + $this->get_button_update_script($question) . "\n"; } - $html .= '
'; + $html .= "
\n"; return $html; } + protected function get_button_id($question) { + // The id to put on the button element in the HTML. + return 'quiznavbutton' . $question->id; + } + + protected function get_button_update_script($question) { + return '\n"; + } + abstract protected function get_question_button($number, $question); abstract protected function get_end_bits(); @@ -830,8 +842,8 @@ abstract class quiz_nav_panel_base { public function display() { $strquiznavigation = get_string('quiznavigation', 'quiz'); - $content = $this->get_question_buttons() . '
' . - $this->get_end_bits() . '
'; + $content = $this->get_question_buttons() . "\n" . '
' . + "\n" . $this->get_end_bits() . "\n
\n"; print_side_block($strquiznavigation, $content, NULL, NULL, '', array('id' => 'quiznavigation'), $strquiznavigation); } } @@ -850,7 +862,8 @@ class quiz_attempt_nav_panel extends quiz_nav_panel_base { } return ''; + $this->get_question_state_classes($question) . '" id="' . + $this->get_button_id($question) . '" ' . $onclick . '/>'; } protected function get_end_bits() { @@ -870,8 +883,8 @@ class quiz_review_nav_panel extends quiz_nav_panel_base { protected function get_question_button($number, $question) { return '' . $number . ''; + '" class="qnbutton ' . $this->get_question_state_classes($question) . '" id="' . + $this->get_button_id($question) . '">' . $number . ''; } protected function get_end_bits() { diff --git a/mod/quiz/quiz.js b/mod/quiz/quiz.js index ca6b450f26..b4e082a510 100644 --- a/mod/quiz/quiz.js +++ b/mod/quiz/quiz.js @@ -19,6 +19,7 @@ function check_enter(e) { } } +// Code for updating the countdown timer that is used on timed quizzes. quiz_timer = { // The outer div, so we can get at it to move it when the page scrolls. timerouter: null, @@ -144,6 +145,25 @@ quiz_timer = { } }; +// Code for updating the navigation panel. At the moment it only updates +// the flagged states of questions. This is a constructor, it takes +function quiz_init_nav_button(buttonid, questionid) { + var button = document.getElementById(buttonid); + button.stateupdater = new quiz_nav_updater(button, questionid); +} + +function quiz_nav_updater(element, questionid) { + this.element = element; + question_flag_changer.add_flag_state_listener(questionid, this); +}; + +quiz_nav_updater.prototype.flag_state_changed = function(newstate) { + this.element.className = this.element.className.replace(/\s*\bflagged\b\s*/, ' '); + if (newstate) { + this.element.className += ' flagged'; + } +}; + quiz_secure_window = { // The message displayed when the secure window interferes with the user. protection_message: null, diff --git a/question/qengine.js b/question/qengine.js index a72804e40e..67ec86eef0 100644 --- a/question/qengine.js +++ b/question/qengine.js @@ -2,13 +2,14 @@ // the require_js calls in get_html_head_contributions in lib/questionlib.php. question_flag_changer = { + flag_state_listeners: new Object(), + init_flag: function(checkboxid, postdata) { var checkbox = document.getElementById(checkboxid); checkbox.ajaxpostdata = postdata; checkbox.className += ' jsworking'; question_flag_changer.update_image(checkbox); YAHOO.util.Event.addListener(checkbox, 'change', this.checkbox_state_change); - YAHOO.util.Event.addListener(checkbox, 'focus', 'blur()'); }, checkbox_state_change: function(e) { @@ -21,6 +22,7 @@ question_flag_changer = { postdata += '&newstate=0' } YAHOO.util.Connect.asyncRequest('POST', qengine_config.wwwroot + '/question/toggleflag.php', null, postdata); + question_flag_changer.fire_state_changed(checkbox); }, update_image: function(checkbox) { @@ -34,5 +36,29 @@ question_flag_changer = { img.alt = qengine_config.unflaggedalt; img.title = qengine_config.flagtooltip; } + }, + + add_flag_state_listener: function(questionid, listener) { + var key = 'q' + questionid; + if (!question_flag_changer.flag_state_listeners.hasOwnProperty(key)) { + question_flag_changer.flag_state_listeners[key] = []; + } + question_flag_changer.flag_state_listeners[key].push(listener); + }, + + questionid_from_cbid: function(cbid) { + return cbid.replace(/resp(\d+)__flagged/, '$1'); + }, + + fire_state_changed: function(checkbox) { + var questionid = question_flag_changer.questionid_from_cbid(checkbox.id); + var key = 'q' + questionid; + if (!question_flag_changer.flag_state_listeners.hasOwnProperty(key)) { + return; + } + var newstate = checkbox.checked; + for (var i = 0; i < question_flag_changer.flag_state_listeners[key].length; i++) { + question_flag_changer.flag_state_listeners[key][i].flag_state_changed(newstate); + } } }; -- 2.39.5