From: tjhunt Date: Wed, 3 Sep 2008 07:11:59 +0000 (+0000) Subject: MDL-16263 Flagging questions during a quiz attempt. Save flag state on submit when... X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=5e9170b43ec6264be6a0b2a5cdcde8ccb6ad17e4;p=moodle.git MDL-16263 Flagging questions during a quiz attempt. Save flag state on submit when JS is off. --- diff --git a/lib/questionlib.php b/lib/questionlib.php index 060cdb5b52..1630c170cc 100644 --- a/lib/questionlib.php +++ b/lib/questionlib.php @@ -982,6 +982,7 @@ function get_question_states(&$questions, $cmoptions, $attempt, $lastattemptid = $states[$i]->penalty = 0; $states[$i]->sumpenalty = 0; $states[$i]->manualcomment = ''; + $states[$i]->flagged = 0; // Prevent further changes to the session from incrementing the // sequence number @@ -1109,8 +1110,13 @@ function restore_question_state(&$question, &$state) { */ function save_question_session($question, $state) { global $QTYPES, $DB; + // Check if the state has changed if (!$state->changed && isset($state->id)) { + if (isset($state->newflaggedstate) && $state->flagged != $state->newflaggedstate) { + // If this fails, don't worry too much, it is not critical data. + question_update_flag($state->questionsessionid, $state->newflaggedstate); + } return $state->id; } // Set the legacy answer field @@ -1129,6 +1135,7 @@ function save_question_session($question, $state) { // create or update the session if (!$session = $DB->get_record('question_sessions', array('attemptid' => $state->attempt, 'questionid' => $question->id))) { + $session = new stdClass; $session->attemptid = $state->attempt; $session->questionid = $question->id; $session->newest = $state->id; @@ -1137,8 +1144,9 @@ function save_question_session($question, $state) { $session->newgraded = $state->id; $session->sumpenalty = $state->sumpenalty; $session->manualcomment = $state->manualcomment; + $session->flagged = !empty($state->newflaggedstate); if (!$DB->insert_record('question_sessions', $session)) { - print_error('cannotinsert', 'question'); + return false; } } else { $session->newest = $state->id; @@ -1150,16 +1158,19 @@ function save_question_session($question, $state) { } else { $session->manualcomment = $session->manualcomment; } - $DB->update_record('question_sessions', $session); + $session->flagged = !empty($state->newflaggedstate); + if (!$DB->update_record('question_sessions', $session)) { + return false; + } } unset($state->answer); // Save the question type specific state information and responses - if (!$QTYPES[$question->qtype]->save_session_and_responses( - $question, $state)) { + if (!$QTYPES[$question->qtype]->save_session_and_responses($question, $state)) { return false; } + // Reset the changed flag $state->changed = false; return $state->id; @@ -1231,7 +1242,6 @@ function question_extract_responses($questions, $formdata, $defaultevent=QUESTIO } else { $actions[$quid]->event = $defaultevent; } - // Update the state with the new response $actions[$quid]->responses[$key] = $response; @@ -1435,8 +1445,10 @@ function question_process_responses($question, &$state, $action, $cmoptions, &$a $action->responses = array('' => ''); } + $state->newflaggedstate = !empty($action->responses['_flagged']); + // make sure these are gone! - unset($action->responses['submit'], $action->responses['validate']); + unset($action->responses['submit'], $action->responses['validate'], $action->responses['_flagged']); // Check the question session is still open if (question_state_is_closed($state)) { @@ -1477,6 +1489,9 @@ function question_process_responses($question, &$state, $action, $cmoptions, &$a $newstate->changed = true; // will assure that it gets saved to the database $newstate->last_graded = clone($state->last_graded); $newstate->timestamp = $action->timestamp; + $newstate->newflaggedstate = $state->newflaggedstate; + $newstate->flagged = $state->flagged; + $newstate->questionsessionid = $state->questionsessionid; $state = $newstate; // Set the event to the action we will perform. The question type specific diff --git a/question/qengine.js b/question/qengine.js index b5a2cebe64..4c47374b21 100644 --- a/question/qengine.js +++ b/question/qengine.js @@ -5,30 +5,35 @@ question_flag_changer = { flag_state_listeners: new Object(), init_flag: function(checkboxid, postdata) { - // Convert the checkbox to an image input. + // Convert the checkbox to a hidden input. var input = document.getElementById(checkboxid); var state = input.checked; input.ajaxpostdata = postdata; - input.flaggedstate = state; - input.type = 'image'; + input.value = state ? 1 : 0; + input.type = 'hidden'; - // Set up the correct image, alt and title. - question_flag_changer.update_image(input); + // Create an image input to replace the img tag. + var image = document.createElement('input'); + image.type = 'image'; + image.statestore = input; + question_flag_changer.update_image(image); + input.parentNode.appendChild(image); // Remove the label element. var label = document.getElementById(checkboxid + 'label'); label.parentNode.removeChild(label); // Add the event handler. - YAHOO.util.Event.addListener(input, 'click', this.flag_state_change); + YAHOO.util.Event.addListener(image, 'click', this.flag_state_change); }, flag_state_change: function(e) { - var input = e.target ? e.target : e.srcElement; - input.flaggedstate = !input.flaggedstate; - question_flag_changer.update_image(input); + var image = e.target ? e.target : e.srcElement; + var input = image.statestore; + input.value = 1 - input.value; + question_flag_changer.update_image(image); var postdata = input.ajaxpostdata - if (input.flaggedstate) { + if (input.value == 1) { postdata += '&newstate=1' } else { postdata += '&newstate=0' @@ -38,15 +43,15 @@ question_flag_changer = { YAHOO.util.Event.preventDefault(e); }, - update_image: function(input) { - if (input.flaggedstate) { - input.src = qengine_config.pixpath + '/i/flagged.png'; - input.alt = qengine_config.flaggedalt; - input.title = qengine_config.unflagtooltip; + update_image: function(image) { + if (image.statestore.value == 1) { + image.src = qengine_config.pixpath + '/i/flagged.png'; + image.alt = qengine_config.flaggedalt; + image.title = qengine_config.unflagtooltip; } else { - input.src = qengine_config.pixpath + '/i/unflagged.png'; - input.alt = qengine_config.unflaggedalt; - input.title = qengine_config.flagtooltip; + image.src = qengine_config.pixpath + '/i/unflagged.png'; + image.alt = qengine_config.unflaggedalt; + image.title = qengine_config.flagtooltip; } }, @@ -68,7 +73,7 @@ question_flag_changer = { if (!question_flag_changer.flag_state_listeners.hasOwnProperty(key)) { return; } - var newstate = input.flaggedstate; + var newstate = input.value == 1; 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); }