diff --git a/lang/en/quiz.php b/lang/en/quiz.php index bd5315a1b61..1fb53e3c565 100644 --- a/lang/en/quiz.php +++ b/lang/en/quiz.php @@ -10,6 +10,7 @@ $string['addquestionstoquiz'] = 'Add questions to current quiz'; $string['addrandom1'] = ' Add '; $string['addrandom2'] = 'random questions '; $string['addselectedtoquiz'] = 'Add selected to quiz'; +$string['affectedstudents'] = 'Affected $a'; $string['aiken'] = 'Aiken format'; $string['allinone'] = 'Unlimited'; $string['allowreview'] = 'Allow review'; @@ -150,6 +151,7 @@ $string['link'] = 'Link'; $string['listitems'] = 'Listing of Items in Quiz'; $string['literal'] = 'Literal'; $string['loguniform'] = 'digits, from a loguniform distribution'; +$string['makecopy'] = 'Save as new question'; $string['marks'] = 'Marks'; $string['match'] = 'Matching'; $string['matchanswer'] = 'Matching answer'; @@ -231,6 +233,8 @@ $string['regrade'] = 'Regrade all attempts'; $string['regradecomplete'] = 'All attempts have been regraded'; $string['regradecount'] = '$a->changed out of $a->attempt grades were changed'; $string['relative'] = 'Relative'; +$string['replace'] = 'Replace'; +$string['replacementoptions'] = 'Replace in'; $string['reviewnever'] = 'Never allow review'; $string['reviewafter'] = 'Allow review after quiz is closed'; $string['reviewbefore'] = 'Allow review while quiz is open'; @@ -263,6 +267,7 @@ $string['shortanswer'] = 'Short Answer'; $string['show'] = 'Show'; $string['showcorrectanswer'] = 'In feedback, show correct answers?'; $string['showfeedback'] = 'After answering, show feedback?'; +$string['showhidden'] = 'Also show hidden questions'; $string['shuffleanswers'] = 'Shuffle answers'; $string['shufflequestions'] = 'Shuffle questions'; $string['significantfiguresformat'] = 'significant figures'; diff --git a/mod/quiz/db/mysql.php b/mod/quiz/db/mysql.php index f7f90c237cb..d5650190d2b 100644 --- a/mod/quiz/db/mysql.php +++ b/mod/quiz/db/mysql.php @@ -314,6 +314,20 @@ function quiz_upgrade($oldversion) { table_column("quiz", "", "decimalpoints", "integer", "4", "", "2", "not null", "grademethod"); } + if($oldversion < 2005022800) { + table_column('quiz_questions', '', 'hidden', 'integer', '1', 'unsigned', '0', 'not null', 'version'); + table_column('quiz_responses', '', 'originalquestion', 'integer', '10', 'unsigned', '0', 'not null', 'question'); + modify_database ('', "CREATE TABLE `prefix_quiz_question_version` ( + `id` int(10) unsigned NOT NULL auto_increment, + `quiz` int(10) unsigned NOT NULL default '0', + `oldquestion` int(10) unsigned NOT NULL default '0', + `newquestion` int(10) unsigned NOT NULL default '0', + `userid` int(10) unsigned NOT NULL default '0', + `timestamp` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`id`) + ) TYPE=MyISAM COMMENT='The mapping between old and new versions of a question';"); + } + return true; } diff --git a/mod/quiz/db/mysql.sql b/mod/quiz/db/mysql.sql index 92ad4fabb06..476b248d42c 100644 --- a/mod/quiz/db/mysql.sql +++ b/mod/quiz/db/mysql.sql @@ -290,6 +290,21 @@ CREATE TABLE `prefix_quiz_question_grades` ( ) TYPE=MyISAM COMMENT='The grade for a question in a quiz'; # -------------------------------------------------------- +# +# Table structure for table `quiz_question_version` +# + +CREATE TABLE `prefix_quiz_question_version` ( + `id` int(10) unsigned NOT NULL auto_increment, + `quiz` int(10) unsigned NOT NULL default '0', + `oldquestion` int(10) unsigned NOT NULL default '0', + `newquestion` int(10) unsigned NOT NULL default '0', + `userid` int(10) unsigned NOT NULL default '0', + `timestamp` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`id`) +) TYPE=MyISAM COMMENT='The mapping between old and new versions of a question'; +# -------------------------------------------------------- + # # Table structure for table `quiz_questions` # @@ -305,6 +320,7 @@ CREATE TABLE `prefix_quiz_questions` ( `qtype` smallint(6) NOT NULL default '0', `stamp` varchar(255) NOT NULL default '', `version` int(10) NOT NULL default '1', + `hidden` int(1) unsigned NOT NULL default '0', PRIMARY KEY (`id`), KEY `category` (`category`) ) TYPE=MyISAM COMMENT='The quiz questions themselves'; @@ -331,6 +347,7 @@ CREATE TABLE `prefix_quiz_responses` ( `id` int(10) unsigned NOT NULL auto_increment, `attempt` int(10) unsigned NOT NULL default '0', `question` int(10) unsigned NOT NULL default '0', + `originalquestion` int(10) unsigned NOT NULL default '0', `answer` text NOT NULL default '', `grade` varchar(10) NOT NULL default '0.0', PRIMARY KEY (`id`), diff --git a/mod/quiz/db/postgres7.php b/mod/quiz/db/postgres7.php index c8bf93ff864..3ffb35952e2 100644 --- a/mod/quiz/db/postgres7.php +++ b/mod/quiz/db/postgres7.php @@ -299,6 +299,18 @@ function quiz_upgrade($oldversion) { table_column("quiz", "", "decimalpoints", "integer", "4", "", "2", "not null", "grademethod"); } + if($oldversion < 2005022800) { + table_column('quiz_questions', '', 'hidden', 'integer', '1', 'unsigned', '0', 'not null', 'version'); + table_column('quiz_responses', '', 'originalquestion', 'integer', '10', 'unsigned', '0', 'not null', 'question'); + modify_database ('', "CREATE TABLE prefix_quiz_question_version ( + id SERIAL PRIMARY KEY, + quiz integer NOT NULL default '0', + oldquestion integer NOT NULL default '0', + newquestion integer NOT NULL default '0', + userid integer NOT NULL default '0', + timestamp integer NOT NULL default '0');"); + } + return true; } diff --git a/mod/quiz/db/postgres7.sql b/mod/quiz/db/postgres7.sql index d383e72edc3..187b3e03ff4 100644 --- a/mod/quiz/db/postgres7.sql +++ b/mod/quiz/db/postgres7.sql @@ -202,6 +202,20 @@ CREATE INDEX prefix_quiz_question_grades_question_idx ON prefix_quiz_question_gr # -------------------------------------------------------- +# +# Table structure for table `quiz_question_version` +# + +CREATE TABLE prefix_quiz_question_version ( + id SERIAL PRIMARY KEY, + quiz integer NOT NULL default '0', + oldquestion integer NOT NULL default '0', + newquestion integer NOT NULL default '0', + userid integer NOT NULL default '0', + timestamp integer NOT NULL default '0' +); +# -------------------------------------------------------- + # # Table structure for table quiz_questions # @@ -216,7 +230,8 @@ CREATE TABLE prefix_quiz_questions ( defaultgrade integer NOT NULL default '1', qtype integer NOT NULL default '0', stamp varchar(255) NOT NULL default '', - version integer NOT NULL default '1' + version integer NOT NULL default '1', + hidden integer NOT NULL default '0' ); CREATE INDEX prefix_quiz_questions_category_idx ON prefix_quiz_questions (category); @@ -243,6 +258,7 @@ CREATE TABLE prefix_quiz_responses ( id SERIAL PRIMARY KEY, attempt integer NOT NULL default '0', question integer NOT NULL default '0', + originalquestion integer NOT NULL default '0', answer text NOT NULL default '', grade varchar(10) NOT NULL default '0.0' ); diff --git a/mod/quiz/edit.php b/mod/quiz/edit.php index 6884cd4ef30..ab80eacf6d6 100644 --- a/mod/quiz/edit.php +++ b/mod/quiz/edit.php @@ -177,8 +177,9 @@ $modform->category = $cat; } - if (isset($_REQUEST['recurse'])) { /// coming from checkbox below category selection form - $modform->recurse = $recurse; + if(isset($_REQUEST['displayoptions'])) { + $modform->recurse = isset($_REQUEST['recurse']) ? 1 : 0; + $modform->showhidden = isset($_REQUEST['showhidden']); } /// all commands have been dealt with, now print the page @@ -190,6 +191,9 @@ if (!isset($modform->recurse)) { $modform->recurse = 1; } + if (!isset($modform->showhidden)) { + $modform->showhidden = false; + } $SESSION->modform = $modform; @@ -258,14 +262,14 @@ // non-quiz-specific column print_simple_box_start("center", "100%"); // starts with category selection form - quiz_print_category_form($course, $modform->category, $modform->recurse); + quiz_print_category_form($course, $modform->category, $modform->recurse, $modform->showhidden); print_simple_box_end(); print_spacer(5,1); // continues with list of questions print_simple_box_start("center", "100%"); quiz_print_cat_question_list($modform->category, - isset($modform->instance), $modform->recurse, $page, $perpage); + isset($modform->instance), $modform->recurse, $page, $perpage, $modform->showhidden); print_simple_box_end(); if (!isset($modform->instance)) { print_continue("index.php?id=$modform->course"); diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php index 78f1e6edd72..2cb52d3d22e 100644 --- a/mod/quiz/locallib.php +++ b/mod/quiz/locallib.php @@ -149,7 +149,7 @@ class quiz_default_questiontype { exit; } - redirect("edit.php"); + return $question; } /// Convenience function that is used within the question types only @@ -345,6 +345,97 @@ class quiz_default_questiontype { // No options by default return false; } + + function print_replacement_options($question, $course, $quizid='0') { + // This function is used near the end of the question edit forms in all questiontypes + // It prints the table of quizzes in which the question is used + // containing the checkboxes to allow the teacher to replace the old question version + + // no need to display replacement options if the question is new + if(empty($question->id)) { + return true; + } + + // get quizzes using the question (using the question_grades table) + $quizlist = array(); + if(!$grades = get_records('quiz_question_grades', 'question', $question->id)) { + $grades = array(); + } + foreach($grades as $grade) { + $quizlist[$grade->quiz] = $grade->quiz; + } + $quizlist = implode(',', $quizlist); + if(empty($quizlist) or !$quizzes = get_records_list('quiz', 'id', $quizlist)) { + $quizzes = array(); + } + + // do the printing + if(count($quizzes) > 0) { + // print the table + $strquizname = get_string('modulename', 'quiz'); + $strdoreplace = get_string('replace', 'quiz'); + $straffectedstudents = get_string('affectedstudents', 'quiz', $course->students); + echo "\n"; + echo "".get_string("replacementoptions", "quiz").":\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + foreach($quizzes as $quiz) { + // work out whethere it should be checked by default + $checked = ''; + if((int)$quizid === (int)$quiz->id + or empty($quiz->usercount)) { + $checked = "checked=\"checked\""; + } + + // find how many different students have already attempted this quiz + $students = array(); + if($attempts = get_records('quiz_attempts', 'quiz', $quiz->id)) { + foreach($attempts as $attempt) { + if (!isteacher($course->id, $attempt->userid) // Ignore teacher attempts + and record_exists('quiz_responses', 'attempt', $attempt->id, 'question', $question->id, 'originalquestion', 0)) { + $students[$attempt->userid] = 1; + } + } + } + $studentcount = count($students); + + $strstudents = $studentcount === 1 ? $course->student : $course->students; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + } + echo "
$strquizname$strdoreplace$straffectedstudents
$quiz->nameid}replace\" type=\"checkbox\" ".$checked." />".(($studentcount) ? $studentcount.' '.$strstudents : '-')."
\n"; + } + echo "\n"; + } + + function print_question_form_end($question, $submitscript='') { + // This function is used at the end of the question edit forms in all questiontypes + // It prints the submit buttons and the standard hidden form fields + global $USER; + echo ' + + '; + if ($question->id) { + echo ' '; + } + echo ' + + + '; + // The following hidden field indicates that the versioning code should be turned on, i.e., + // that old versions should be kept if necessary + echo ' + '; + } + } quiz_load_questiontypes(); @@ -960,7 +1051,7 @@ function quiz_get_category_menu($courseid, $published=false) { return $catmenu; } -function quiz_print_category_form($course, $current, $recurse=1) { +function quiz_print_category_form($course, $current, $recurse=1, $showhidden=false) { /// Prints a form to choose categories /// Make sure the default category exists for this course @@ -998,14 +1089,22 @@ function quiz_print_category_form($course, $current, $recurse=1) { echo ""; echo ""; echo ''; - echo '
'; - print_string('recurse', 'quiz'); - echo ''; + echo ''; + echo ''; echo ''; + echo ' onchange="document.displayoptions.submit(); return true;" />'; + print_string('recurse', 'quiz'); + // hide-feature + echo '
'; + echo ''; + print_string('showhidden', 'quiz'); echo '
'; } @@ -1222,7 +1321,7 @@ function quiz_print_question_list($questionlist, $grades, $allowdelete=true) { } -function quiz_print_cat_question_list($categoryid, $quizselected=true, $recurse=1, $page, $perpage) { +function quiz_print_cat_question_list($categoryid, $quizselected=true, $recurse=1, $page, $perpage, $showhidden=false) { // Prints the table of questions in a category with interactions global $QUIZ_QUESTION_TYPE, $USER; @@ -1239,7 +1338,7 @@ function quiz_print_cat_question_list($categoryid, $quizselected=true, $recurse= $strquestionname = get_string("questionname", "quiz"); $strdelete = get_string("delete"); $stredit = get_string("edit"); - $strcopy = get_string("copy"); + $straddselectedtoquiz = get_string("addselectedtoquiz", "quiz"); $strtype = get_string("type", "quiz"); $strcreatemultiple = get_string("createmultiple", "quiz"); @@ -1298,7 +1397,9 @@ function quiz_print_cat_question_list($categoryid, $quizselected=true, $recurse= $categorylist = ($recurse) ? quiz_categorylist($category->id) : $category->id; - if (!$questions = get_records_select('quiz_questions', "category IN ($categorylist) AND qtype != '".RANDOM."'", 'qtype, name ASC', '*', $page*$perpage, $perpage)) { + // hide-feature + $showhidden = $showhidden ? '' : " AND hidden = '0'"; + if (!$questions = get_records_select('quiz_questions', "category IN ($categorylist) AND qtype != '".RANDOM."'$showhidden", 'qtype, name ASC', '*', $page*$perpage, $perpage)) { echo "

"; print_string("noquestions", "quiz"); echo "

"; @@ -1341,8 +1442,18 @@ function quiz_print_cat_question_list($categoryid, $quizselected=true, $recurse= src=\"../../pix/t/preview.gif\" border=\"0\" alt=\"$strpreview\" /> "; echo "id\">\"$stredit\" "; - echo "id&copy=true\">\"$strcopy\""; + // hide-feature + if($question->hidden) { + $strhideshow = get_string("show"); + $imghideshow = "show.gif"; + $hideshow = 0; + } else { + $strhideshow = get_string("hide"); + $imghideshow = "hide.gif"; + $hideshow = 1; + } + echo "id&hide=$hideshow&sesskey=$USER->sesskey\">\"$strhideshow\""; echo "\n"; } echo "\n"; @@ -1369,7 +1480,7 @@ function quiz_print_cat_question_list($categoryid, $quizselected=true, $recurse= echo '
'; echo "sesskey\">"; print_string('addrandom1', 'quiz'); - choose_from_menu($randomcount, 'randomcreate', '10', ''); + choose_from_menu($randomcount, 'randomcreate', '1', ''); print_string('addrandom2', 'quiz'); // Don't offer the option to change the grade //choose_from_menu($randomcount, 'randomgrade', '1', ''); @@ -1897,4 +2008,13 @@ function quizzes_question_used( $id, $published=false, $courseid=0 ) { } return $beingused; } + +function quiz_parse_fieldname($name, $nameprefix='question') { + $reg = array(); + if(preg_match("/q(\\d+)(\w+)/", $name, $reg)) { + return array('mode' => $reg[2], 'id' => (int)$reg[1]); + } else { + return false; + } +} ?> diff --git a/mod/quiz/question.php b/mod/quiz/question.php index 18d4dbd7cef..d786cb60b7a 100644 --- a/mod/quiz/question.php +++ b/mod/quiz/question.php @@ -1,5 +1,14 @@ qtype; - } else if ($category) { + } else if ($category) { // only for creating new questions if (! $category = get_record("quiz_categories", "id", $category)) { error("This wasn't a valid category!"); } @@ -57,7 +77,7 @@ } $strquizzes = get_string('modulenameplural', 'quiz'); - $streditingquestion = ($copy) ? get_string('copyingquestion', 'quiz') : get_string('editingquestion', 'quiz'); + $streditingquestion = get_string('editingquestion', 'quiz'); if (isset($SESSION->modform->instance)) { $strediting = ''.get_string('editingquiz', 'quiz').' -> '. $streditingquestion; @@ -114,7 +134,110 @@ } if ($form = data_submitted() and confirm_sesskey()) { - $question = $QUIZ_QTYPES[$qtype]->save_question($question, $form, $course); + + if (isset($form->versioning)) { // use new code that + // handles whether to overwrite or copy a question and keeps + // track of the versions in the quiz_question_version table + + // $replaceinquiz is an array with the ids of all quizzes in which the teacher has chosen to replace the old version + $replaceinquiz = array(); + foreach($form as $key => $val) { + if ($tmp = quiz_parse_fieldname($key, 'q')) { + if ($tmp['mode'] == 'replace') { + $replaceinquiz[$tmp['id']] = $tmp['id']; + unset($form->$key); + } + } + } + + // $quizlist is an array with the ids of quizzes which use this question + $quizlist = array(); + if ($grades = get_records('quiz_question_grades', 'question', $form->id)) { + foreach($grades as $grade) { + $quizlist[$grade->quiz] = $grade->quiz; + } + } + + // Logic to determine whether old version should be overwritten + $makecopy = isset($form->makecopy) || (!$form->id); unset($form->makecopy); + $noresponses = $makecopy || !(record_exists('quiz_responses', 'question', $form->id) or + record_exists('quiz_responses', 'originalquestion', $form->id)); // Should be improved once the preview flag exists so that teacher preview responses are not taken into account + $notused = $makecopy || !record_exists('quiz_question_grades', 'question', $form->id); + $replaceinall = ($quizlist == $replaceinquiz); // question is being replaced in all quizzes + $replaceold = (!$makecopy && $noresponses && ($notused || $replaceinall)); + + if (!$replaceold) { // create a new question + $oldquestion = clone($question); + if (!$makecopy) { + $oldquestion->hidden = 1; + if (!set_field("quiz_questions", 'hidden', 1, 'id', $question->id)) { + error("Could not hide question!"); + } + } + unset($question->id); + } + unset($makecopy, $noresponses, $notused, $replaceinall, $replaceold); + + $question = $QUIZ_QTYPES[$qtype]->save_question($question, $form, $course); + + if(!isset($question->id)) { + error("Failed to save the question!"); + } + + if(isset($oldquestion->id)) { + // create version entries for different quizzes + $version = new object(); + $version->oldquestion = $oldquestion->id; + $version->newquestion = $question->id; + $version->userid = $USER->id; // field still needs to be added to table + $version->timestamp = time(); + + foreach($replaceinquiz as $qid) { + $version->quiz = $qid; + if(!insert_record("quiz_question_version", $version)) { + error("Could not store version information of question $oldquestion->id in quiz $qid!"); + } + } + + /// now update the question references in the quizzes + + $quizzes = implode(',', $replaceinquiz); + if (empty($quizzes) || !$quizzes = get_records_list("quiz", "id", $quizzes)) { + $quizzes = array(); + } + foreach($quizzes as $quiz) { + $questionlist = ",$quiz->questions,"; // a little hack with the commas here. not nice but effective + $questionlist = str_replace(",$oldquestion->id,", ",$question->id,", $questionlist); + $questionlist = substr($questionlist, 1, -1); // and get rid of the surrounding commas again + if (!set_field("quiz", 'questions', $questionlist, 'id', $quiz->id)) { + error("Could not update questionlist in quiz $quiz->id!"); + } + // the quiz_question_grades table needs to be updated too (aah, the joys of duplication :) + if (!set_field('quiz_question_grades', 'question', $question->id, 'quiz', $quiz->id, 'question', $oldquestion->id)) { + error("Could not update question grade!"); + } + if (isset($SESSION->modform) && (int)$SESSION->modform->instance === (int)$quiz->id) { + $SESSION->modform->questions = $questionlist; + $SESSION->modform->grades[$question->id] = $SESSION->modform->grades[$oldquestion->id]; + unset($SESSION->modform->grades[$oldquestion->id]); + } + } + + // fix responses + if ($attempts = get_records_list('quiz_attempts', 'quiz', implode(',', $replaceinquiz))) { + foreach ($attempts as $attempt) { + if (!set_field('quiz_responses', 'originalquestion', $oldquestion->id, 'attempt', $attempt->id, 'question', $oldquestion->id) + or !set_field('quiz_responses', 'question', $question->id, 'attempt', $attempt->id, 'question', $oldquestion->id)) { + error("Could not point responses to new question"); + } + } + } + } + + redirect("edit.php"); + } else { // use the old code which simply overwrites old versions + $question = $QUIZ_QTYPES[$qtype]->save_question($question, $form, $course); + } } $grades = array(1,0.9,0.8,0.75,0.70,0.66666,0.60,0.50,0.40,0.33333,0.30,0.25,0.20,0.16666,0.10,0.05,0); @@ -165,14 +288,10 @@ $defaultformat = FORMAT_MOODLE; } - if ($copy) { - print_heading(get_string('copyingfrom', 'quiz', $question->name)); - // clear question id so that the data is saved to a new question - $question->id = ''; - $question->name .= '_copy'; - } - + echo '
'; + print_simple_box_start('center'); require('questiontypes/'.$QUIZ_QTYPES[$qtype]->name().'/editquestion.php'); + print_simple_box_end(); if ($usehtmleditor) { use_html_editor('questiontext'); diff --git a/mod/quiz/questiontypes/match/match.html b/mod/quiz/questiontypes/match/match.html index 0e9f8e329dd..be18ab23fab 100644 --- a/mod/quiz/questiontypes/match/match.html +++ b/mod/quiz/questiontypes/match/match.html @@ -81,11 +81,11 @@ qtype]->print_replacement_options($question, $course, $contextquiz); + $QUIZ_QTYPES[$question->qtype]->print_question_form_end($question); ?> - - - -" /> +
diff --git a/mod/quiz/questiontypes/multianswer/multianswer.html b/mod/quiz/questiontypes/multianswer/multianswer.html index 8f892e47056..553db60c3d2 100644 --- a/mod/quiz/questiontypes/multianswer/multianswer.html +++ b/mod/quiz/questiontypes/multianswer/multianswer.html @@ -41,11 +41,13 @@ ?> +qtype]->print_replacement_options($question, $course, $contextquiz); + $QUIZ_QTYPES[$question->qtype]->print_question_form_end($question); +?> - - - + -" /> + diff --git a/mod/quiz/questiontypes/multianswer/questiontype.php b/mod/quiz/questiontypes/multianswer/questiontype.php index 536dbd181b4..04d0f802d55 100644 --- a/mod/quiz/questiontypes/multianswer/questiontype.php +++ b/mod/quiz/questiontypes/multianswer/questiontype.php @@ -166,7 +166,7 @@ class quiz_embedded_cloze_qtype extends quiz_default_questiontype { exit; } - redirect("edit.php"); + return $question; } function convert_to_response_answer_field($questionresponse) { diff --git a/mod/quiz/questiontypes/multichoice/multichoice.html b/mod/quiz/questiontypes/multichoice/multichoice.html index 42858f1f8ef..2560ace7370 100644 --- a/mod/quiz/questiontypes/multichoice/multichoice.html +++ b/mod/quiz/questiontypes/multichoice/multichoice.html @@ -123,13 +123,11 @@ qtype]->print_replacement_options($question, $course, $contextquiz); + $QUIZ_QTYPES[$question->qtype]->print_question_form_end($question); ?> - - - - -" /> + diff --git a/mod/quiz/questiontypes/numerical/numerical.html b/mod/quiz/questiontypes/numerical/numerical.html index 8fce32ed7c7..57b3cae213c 100644 --- a/mod/quiz/questiontypes/numerical/numerical.html +++ b/mod/quiz/questiontypes/numerical/numerical.html @@ -132,13 +132,12 @@ for ($i=1; $i qtype]->print_replacement_options($question, $course, $contextquiz); + $QUIZ_QTYPES[$question->qtype]->print_question_form_end($question, 'onclick="return determineMinAndMax();"'); ?> - - - -" />