Commit 7b41a4a9 authored by jamiesensei's avatar jamiesensei
Browse files

some more small changes to datasetdependent and calculated question type forms

parent 71534002
......@@ -466,7 +466,7 @@ class moodleform {
for ($i=0; $i<$repeats; $i++) {
foreach ($elementobjs as $elementobj){
$elementclone = clone($elementobj);
$name=$elementclone->getName();
$name = $elementclone->getName();
if (!empty($name)){
$elementclone->setName($name."[$i]");
}
......@@ -479,6 +479,7 @@ class moodleform {
$elementclone->setLabel(str_replace('{no}', ($i+1), $value));
}
$mform->addElement($elementclone);
}
}
......
......@@ -72,7 +72,7 @@ if ($wizardnow!==''){
}
if ($mform === null) {
print_error('missingimportantcode', 'question', $returnurl, 'question editing form definition');
print_error('missingimportantcode', 'question', $returnurl, 'question editing form definition for "'.$question->qtype.'"');
}
$toform = $question; // send the question object and a few more parameters to the form
$toform->returnurl = $returnurl;
......@@ -110,7 +110,7 @@ if ($mform->is_cancelled()){
redirect($nexturl.'&wizardnow='.$data->wizard.$queryappend, '', 20);
}
} else {
// Display the question editing form
$streditingquestion = get_string('editingquestion', 'question');
if (isset($SESSION->modform->instance)) {
// TODO: remove restriction to quiz
......@@ -121,12 +121,11 @@ if ($mform->is_cancelled()){
get_string("editquestions", "quiz").'</a> -> '.$streditingquestion;
}
print_header_simple($streditingquestion, '', $strediting);
if (isset($mform->heading)){
print $mform->heading;
} else {
print_heading_with_help(get_string("editing".$question->qtype, "quiz"), $question->qtype, "quiz");
}
$mform->display();
print_footer($COURSE);
// Display a heading, question editing form and possibly some extra content needed for
// for this question type.
$QTYPES[$question->qtype]->display_question_editing_page(&$mform, $question, $wizardnow);
print_footer($course);
}
?>
<?php
$QTYPES[$question->qtype]->print_question_form_start($question, array(), $course, $usehtmleditor);
?>
<tr valign="top">
<td align="right"><b><?php print_string("correctanswerformula", "quiz") ?>:</b></td>
<td align="left">
<input align="left" type="text" id="formula0" name="answers[]" size="20" value="<?php p($answers[0]->answer) ?>" alt="<?php print_string("correctanswerformula", "quiz") ?>" />&nbsp;&nbsp;
<input type="hidden" name="fraction[]" value="1.0" />
</td>
</tr>
<tr valign="top">
<td align="right"><b><?php print_string("tolerance", "quiz"); ?>:</b></td>
<td align="left">
<input align="left" type="text" id="tolerance0" name="tolerance[]" size="15" value="<?php p($answers[0]->tolerance) ?>" alt="<?php print_string("tolerance", "quiz"); ?>" />&plusmn;
</td>
</tr>
<tr valign="top">
<td align="right"><b><?php print_string("tolerancetype", "quiz"); ?>:</b></td>
<td align="left">
<?php choose_from_menu($qtypeobj->tolerance_types(),
'tolerancetype[]', $answers[0]->tolerancetype, false); ?>
</td>
</tr>
<tr valign="top">
<td align="right"><b><?php print_string("correctanswershows", "quiz"); ?>:</b></td>
<td align="left">
<?php choose_from_menu(array('0' => ' 0 ',
'1' => ' 1 ', '2' => ' 2 ', '3' => ' 3 ',
'4' => ' 4 ', '5' => ' 5 ', '6' => ' 6 ',
'7' => ' 7 ', '8' => ' 8 ', '9' => ' 9 '),
'correctanswerlength[]',
$answers[0]->correctanswerlength, false); ?>
<?php choose_from_menu(array('1' => get_string('decimalformat', 'quiz'),
'2' => get_string('significantfiguresformat', 'quiz')),
'correctanswerformat[]',
$answers[0]->correctanswerformat, false); ?>
</td>
</tr>
<tr valign="top">
<td align="right"><b><?php print_string("feedback", "quiz") ?>:</b></td>
<td align="left">
<textarea name="feedback[]" rows="2" cols="50"><?php p($answers[0]->feedback) ?></textarea>
</td>
</tr>
<tr valign="top">
<td align="right"><b><?php print_string("unit", "quiz") ?>:</b></td>
<td align="left">
<input type="hidden" name="multiplier[]" value="1.0" />
<input align="left" type="text" id="defaultunit" name="unit[]"
size="5" value="<?php p($units[0]->unit) ?>"
alt="<?php print_string("unit", "quiz") ?>" />
<b>(<?php print_string("optional", "quiz") ?>)</b>
</td>
</tr>
<tr valign="top">
<td align="left"></td>
<td align="left"><b><?php print_string("alternativeunits", "quiz") ?>:</b></td>
<td align="left"></td>
</tr>
<?php
for ($i=1; $i<count($units); $i++) {
$unit=$units[$i];
?>
<tr valign="top">
<td></td>
<td align="left">
<b><?php print_string("multiplier", "quiz") ?>:</b>
<input type="text" id="<?php p("multiplier$i") ?>" size="10"
align="right" name="multiplier[]"
value="<?php p($unit->multiplier) ?>"
alt="<?php print_string("multiplier", "quiz") ?>" />
<b>&nbsp;&nbsp;&nbsp;<?php print_string("unit", "quiz") ?>:</b>
<input align="left" type="text" id="<?php p("unit$i") ?>"
name="unit[]"
size="5" value="<?php p($unit->unit) ?>"
alt="<?php print_string("unit", "quiz") ?>" />
</td>
</tr>
<?php
} /// END for
$QTYPES[$question->qtype]->print_replacement_options($question, $course, $contextquiz);
$QTYPES[$question->qtype]->print_question_form_end($question,
'onclick="return determineMinAndMax();"',
'<input type="hidden" name="wizardpage" value="question" />');
?>
<script type="text/javascript">
//<![CDATA[
function determineMinAndMax() {
// This client-side script will determine the values for min and max
// based on the input for answer and acceptederror.
with(getElementById('theform')) {
if (formula0.value=='') {
alert('<?php print_string("missingformula","quiz") ?>');
return false;
/* It could perhaps be an idea to parse the formula here
* but as it is necessary at the server anyway, we can
* it leave like this for the moment. */
} else if (''!=defaultunit.value && !isNaN(defaultunit.value)) {
alert('<?php print_string("unitmustnotbenumeric","quiz") ?>');
return false;
} else if (isNaN(tolerance0.value)) {
alert('<?php print_string("tolerancemustbenumeric","quiz") ?>');
return false;
} else if ('2' == getElementById('theform')['correctanswerformat[]'].value
&& '0' == getElementById('theform')['correctanswerlength[]'].value) {
alert('<?php print_string("zerosignificantfiguresnotallowed","quiz") ?>');
return false;
} else {
return true;
}
}
}
//]]>
</script>
<?php // $Id$
// Get a handle to the question type we are dealing with here
$qtypeobj = $QTYPES['calculated'];
if (empty($form)) {
/****************************************************************/
/***** First page in question wizard - editquestion.html.html! **/
/****************************************************************/
// Inside this block everything works as for non-wizardquestions
// The layout of the editing page will only support
// one formula alternative for calculated questions.
// However, the code behind supports up to six formulas
// and the database store and attempt/review framework
// does not have any limit.
$answers= array();
for ($i=0; $i<6; $i++) {
// Make answer slots with default values
$answers[$i]->answer = "";
$answers[$i]->feedback = "";
$answers[$i]->fraction = "1.0";
$answers[$i]->tolerance = "0.01";
$answers[$i]->tolerancetype = "1";
$answers[$i]->correctanswerlength = "2"; // Defaults to two ...
$answers[$i]->correctanswerformat = "1"; // ... decimals
}
if (!empty($question->id)) {
$QTYPES[$question->qtype]->get_question_options($question);
if (!empty($question->options->answers)) {
// Overwrite the default valued answer slots
// with correct values from database
$answersraw = array_values($question->options->answers);
$n = count($answersraw);
for ($i = 0; $i < $n; $i++) {
$answers[$i] = $answersraw[$i];
}
}
}
// Units are handled the same way
// as for numerical questions
$units = array();
for ($i=0 ; $i<6 ; $i++) {
// Make unit slots, default as blank...
$units[$i]->multiplier = '';
$units[$i]->unit = '';
}
if (!empty($question->id) and $unitsraw = get_records(
'question_numerical_units', 'question', $question->id)) {
/// Find default unit and have it put in the zero slot
/// This procedure might be overridden later when
/// the unit is stripped form an answer...
foreach ($unitsraw as $key => $unit) {
if (1.0 == $unit->multiplier) {
/// Default unit found:
$units[0] = $unit;
unset($unitsraw[$key]);
break;
}
}
/// Fill remaining answer slots with whatsever left
if (!empty($unitsraw)) {
$i = 1; // The zero slot got the default unit...
foreach ($unitsraw as $unit) {
$units[$i] = $unit;
$i++;
}
}
} else {
$units[0]->multiplier = 1.0;
}
// Strip trailing zeros from multipliers
foreach ($units as $i => $unit) {
if (ereg('^(.*\\..(.*[^0])?)0+$', $unit->multiplier, $regs1)) {
if (ereg('^(.+)\\.0$', $regs1[1], $regs2)) {
$units[$i]->multiplier = $regs2[1];
} else {
$units[$i]->multiplier = $regs1[1];
}
}
}
print_heading_with_help(get_string("editingcalculated", "quiz"), "calculated", "quiz");
require("$CFG->dirroot/question/type/calculated/editquestion.html");
} else { // $form is not empty
/*********************************************************/
/***** Any subsequent page of the question wizard **/
/*********************************************************/
$qtypeobj->print_next_wizard_page($question, $form, $course);
}
?>
......@@ -185,14 +185,11 @@ class question_dataset_dependent_questiontype extends default_questiontype {
case 'datasetdefinitions':
require("$CFG->dirroot/question/type/datasetdependent/datasetdefinitions_form.php");
$mform =& new question_dataset_dependent_definitions_form("$submiturl?wizardnow=datasetdefinitions", $question);
$mform->heading = print_heading_with_help(get_string("choosedatasetproperties", "quiz"), "questiondatasets", "quiz", '', true);
break;
case 'datasetitems':
require("$CFG->dirroot/question/type/datasetdependent/datasetitems_form.php");
$regenerate = optional_param('forceregeneration', 0, PARAM_BOOL);
$mform =& new question_dataset_dependent_items_form("$submiturl?wizardnow=datasetitems", $question, $regenerate);
$streditdatasets = get_string("editdatasets", "quiz");
$mform->heading = print_heading_with_help($streditdatasets, 'questiondatasets', "quiz", '', true);
break;
default:
error('Incorrect or no wizard page specified!');
......@@ -201,6 +198,35 @@ class question_dataset_dependent_questiontype extends default_questiontype {
return $mform;
}
/**
* This method should be overriden if you want to include a special heading or some other
* html on a question editing page besides the question editing form.
*
* @param question_edit_form $mform a child of question_edit_form
* @param object $question
* @param string $wizardnow is '' for first page.
*/
function display_question_editing_page(&$mform, $question, $wizardnow){
switch ($wizardnow){
case '':
//on first page default display is fine
parent::display_question_editing_page($mform, $question, $wizardnow);
return;
break;
case 'datasetdefinitions':
print_heading_with_help(get_string("choosedatasetproperties", "quiz"), "questiondatasets", "quiz");
break;
case 'datasetitems':
print_heading_with_help(get_string("editdatasets", "quiz"), 'questiondatasets', "quiz");
break;
}
$mform->display();
}
function save_question($question, $form, $course) {
// For dataset dependent questions a wizard is used for editing
// questions. Therefore saving the question is delayed until
......
<?php
// Now continue by preparing for the second page
// in the question wizard: "questiondatasets.html"
// Determine possible and mandatory datasets...
$possibledatasets = $this->find_dataset_names($form->questiontext);
$mandatorydatasets = array();
foreach ($form->answers as $answer) {
$mandatorydatasets += $this
->find_dataset_names($answer);
}
$datasets = $this->construct_dataset_menus(
$form, $mandatorydatasets, $possibledatasets);
// Print the page
print_heading_with_help(get_string("choosedatasetproperties", "quiz"), "questiondatasets", "quiz");
require("$CFG->dirroot/question/type/datasetdependent/questiondatasets.html");
?>
<?php // $Id$
// Allows a teacher to create, edit and delete datasets
// Set up strings
$strdatasetnumber = get_string("datasetnumber", "quiz");
$strnumberinfo = get_string("categoryinfo", "quiz");
$strquestions = get_string("questions", "quiz");
$strpublish = get_string("publish", "quiz");
$strdelete = get_string("remove", "quiz");
$straction = get_string("action");
$stradd = get_string("add");
$strcancel = get_string("cancel");
$strsavechanges = get_string("savechanges");
$strbacktoquiz = get_string("backtoquiz", "quiz");
$streditingquiz = get_string("editingquiz", "quiz");
$streditdatasets = get_string("editdatasets", "quiz");
$strreuseifpossible = get_string('reuseifpossible', 'quiz');
$strforceregeneration = get_string('forceregeneration', 'quiz');
$strdataitemneed = get_string('dataitemneed', 'quiz');
if (empty($question->id)) {
$datasetdefs = $this->get_dataset_definitions(
$SESSION->datasetdependent->definitionform);
} else {
if (empty($question->options)) {
$this->get_question_options($question);
}
$datasetdefs = $this->get_dataset_definitions($form);
}
// Handle generator options...
$olddatasetdefs = fullclone($datasetdefs); // Completely deep copy the array of objects
$datasetdefs = $this->update_dataset_options($olddatasetdefs, $form);
$maxnumber = -1;
$datasets = empty($form->dataset) ? $form->definition : $form->dataset;
foreach ($datasetdefs as $defid => $datasetdef) {
if (isset($datasetdef->id)
&& $datasetdef->options != $olddatasetdefs[$defid]->options) {
// Save the new value for options
update_record('question_dataset_definitions', $datasetdef);
}
// Get maxnumber
if ($maxnumber == -1 || $datasetdef->itemcount < $maxnumber) {
$maxnumber = $datasetdef->itemcount;
}
}
// Handle adding and removing of dataset items
// This twisted condition should effectively stop resubmits caused by reloads
if (isset($form->addbutton) && $maxnumber + 1 == $form->numbertoadd) {
$addeditem->itemnumber = $form->numbertoadd;
foreach ($form->definition as $key => $defid) {
$addeditem->definition = $datasetdefs[$defid]->id;
$addeditem->value = $form->value[$key];
if ($form->itemid[$key]) {
// Reuse an previously used record
$addeditem->id = $form->itemid[$key];
if (!update_record('question_dataset_items', $addeditem)) {
error("Error: Unable to update dataset item");
}
} else {
unset($addeditem->id);
if (!insert_record('question_dataset_items', $addeditem)) {
error("Error: Unable to insert dataset item");
}
}
foreach ($datasetdefs as $key => $newdef) {
if (isset($newdef->id) && $newdef->itemcount <= $maxnumber) {
$newdef->itemcount = $maxnumber+1;
// Save the new value for options
update_record('question_dataset_definitions', $newdef);
}
}
}
// else Success:
$maxnumber = $addeditem->itemnumber;
} else if (isset($form->deletebutton)
&& $maxnumber == $form->numbertodelete) {
// Simply decrease itemcount where == $maxnumber
foreach ($datasetdefs as $datasetdef) {
if ($datasetdef->itemcount == $maxnumber) {
$datasetdef->itemcount--;
if (!update_record('question_dataset_definitions',
$datasetdef)) {
error("Error: Unable to update itemcount");
}
}
}
--$maxnumber;
}
make_upload_directory("$course->id"); // Just in case
$grosscoursefiles = get_directory_list("$CFG->dataroot/$course->id",
"$CFG->moddata");
// Have $coursefiles indexed by file paths:
$coursefiles = array();
foreach ($grosscoursefiles as $coursefile) {
$coursefiles[$coursefile] = $coursefile;
}
// Generate a new dataset item (or reuse an old one)
foreach ($datasetdefs as $defid => $datasetdef) {
if (isset($datasetdef->id)) {
$datasetdefs[$defid]->items = get_records_sql( // Use number as key!!
" SELECT itemnumber, definition, id, value
FROM {$CFG->prefix}question_dataset_items
WHERE definition = $datasetdef->id ");
}
if (isset($datasetdefs[$defid]->items[$maxnumber + 1]) && (
empty($form->forceregeneration) &&
isset($form->regenerateddefid) &&
$form->regenerateddefid != $defid ||
isset($form->deletebutton))) {
// Reuse existing datasets
} else {
$datasetitem = new stdClass;
$datasetitem->id =
isset($datasetdefs[$defid]->items[$maxnumber + 1]->id)
? $datasetdefs[$defid]->items[$maxnumber + 1]->id : '';
$datasetitem->itemnumber = $maxnumber + 1;
if ($this->supports_dataset_item_generation()) {
if (!empty($form->addbutton) || // If we added an item
!isset($form->value) || // If we don't have a value
$form->regenerateddefid == $defid) { // If we explicitly ask for regeneration
$datasetitem->value =
$this->generate_dataset_item($datasetdef->options);
} else {
$definition = array_flip($form->definition);
$datasetitem->value = $form->value[$definition[$defid]];
}
} else {
$datasetitem->value = '';
}
$datasetdefs[$defid]->items[$maxnumber + 1] = clone($datasetitem);
}
}
// Get question header if any
$strquestionheader = $this->comment_header($question);
// Set up the table with the controls for creating new dataset items
$table->head = $addtable->head = array($straction, $strdatasetnumber);
$addtable->align = array("center", "center");
$forceregeneration = '';
if ($this->supports_dataset_item_generation()) {
$force = $reuse = '';
empty($form->forceregeneration)
? $reuse = ' checked="checked" '
: $force = ' checked="checked" ';
$forceregeneration = '<br/><input type="radio" name="forceregeneration" '
. $reuse . ' value="0"/>' . $strreuseifpossible
. '<br/><input type="radio" name="forceregeneration" value="1" '
. $force . ' />' . $strforceregeneration;
}
$addline[] = '<input type="hidden" name="numbertoadd" value="'.
($maxnumber+1).'"/><input type="submit" name="addbutton" '.
'value="'.$stradd.'"/>'.$forceregeneration;
$addline[] = $maxnumber+1;
foreach ($datasetdefs as $defid => $datasetdef) {
if ($datasetdef->name) {
$table->head[] = $datasetdef->name;
$addtable->head[] = $datasetdef->name
. ($this->supports_dataset_item_generation()
? '<br/>' . $this->custom_generator_tools($datasetdef)
: '');
//$table->align[] = "center";
if (isset($datasetdef->items[$maxnumber + 1]->id)) {
$itemid = $datasetdef->items[$maxnumber + 1]->id;
} else {
$itemid = '';
}
$addline[] =
'<input type="hidden" name="itemid[]" value="'.$itemid.'"/>'
. "<input type=\"hidden\" name=\"definition[]\" value=\"$defid\"/>"
. ( 2 != $datasetdef->type
? '<input type="text" size="20" name="value[]" value="'
. $datasetdef->items[$maxnumber + 1]->value
. '"/>'
: choose_from_menu($coursefiles, 'value[]',
$datasetdef->items[$maxnumber + 1]->value,
'', '', '', true));
$data[$datasetdef->name] = $datasetdef->items[$maxnumber + 1]->value;
}
}
if ($strquestionheader) {
$table->head[] = $strquestionheader;
$addtable->head[] = $strquestionheader;
if (empty($question->id) &&
isset($SESSION->datasetdependent->questionform)) {
$tmp = &$SESSION->datasetdependent->questionform;
$answers = array();
foreach ($tmp->answers as $key => $val) {
$answers[$key]->answer = $tmp->answers[$key];
$answers[$key]->tolerance = $tmp->tolerance[$key];
$answers[$key]->tolerancetype = $tmp->tolerancetype[$key];
$answers[$key]->correctanswerlength = $tmp->correctanswerlength[$key];
$answers[$key]->correctanswerformat = $tmp->correctanswerformat[$key];
}
$question->options->answers = $answers;
}
$addline[] = $this->comment_on_datasetitems($question, $data, $maxnumber + 1);
}
// Set up the table showing existing datasets
$table->data = array();
$table->align = $addtable->align;
for ($number = $maxnumber ; $number > 0 ; --$number) {
$columns = array();
if ($maxnumber == $number) {
$columns[] =
"<input type=\"hidden\" name=\"numbertodelete\" value=\"$number\"/>
<input type=\"submit\" name=\"deletebutton\" value=\"$strdelete\"/>";
} else {
$columns[] = '';
}
$columns[] = $number;
foreach ($datasetdefs as $defid => $datasetdef) {
$columns[] =
'<input type="hidden" name="itemid[]" value="'. $datasetdef->items[$number]->id .'"/>'
. "<input type=\"hidden\" name=\"number[]\" value=\"$number\"/>
<input type=\"hidden\" name=\"definition[]\" value=\"$defid\"/>"
. // Set $data:
($data[$datasetdef->name] = $datasetdef->items[$number]->value) ;
}
if ($strquestionheader) {
$columns[] = $this->comment_on_datasetitems($question, $data, $number);
}
$table->data[] = $columns;
}
/// Print heading
print_heading_with_help($streditdatasets, 'questiondatasets', "quiz");
// Print the new-dataset table
$addtable->data = array($addline);
echo "<form id=\"addform\" method=\"post\" action=\"question.php\">
<fieldset class=\"invisiblefieldset\">
<input type=\"hidden\" name=\"regenerateddefid\" value=\"0\"/>
<input type=\"hidden\" name=\"id\" value=\"$question->id\"/>
<input type=\"hidden\" name=\"category\" value=\"$question->category\"/>
<input type=\"hidden\" name=\"qtype\" value=\"$question->qtype\"/>
<input type=\"hidden\" name=\"sesskey\" value=\"".sesskey()."\"/>