Ejemplo n.º 1
0
 public function subquestion(question_attempt $qa, question_display_options $options, qtype_combined_combinable_base $subq, $placeno)
 {
     $question = $subq->question;
     $place = $placeno + 1;
     $group = $question->places[$place];
     $fieldname = $subq->step_data_name($question->field($place));
     $value = $qa->get_last_qt_var($fieldname);
     $attributes = array('id' => str_replace(':', '_', $qa->get_qt_field_name($fieldname)));
     if ($options->readonly) {
         $attributes['disabled'] = 'disabled';
     }
     $orderedchoices = $question->get_ordered_choices($group);
     $selectoptions = array();
     foreach ($orderedchoices as $orderedchoicevalue => $orderedchoice) {
         $selectoptions[$orderedchoicevalue] = $orderedchoice->text;
     }
     $feedbackimage = '';
     if ($options->correctness) {
         $response = $qa->get_last_qt_data();
         if (array_key_exists($fieldname, $response)) {
             $fraction = (int) ($response[$fieldname] == $question->get_right_choice_for($place));
             $attributes['class'] = $this->feedback_class($fraction);
             $feedbackimage = $this->feedback_image($fraction);
         }
     }
     $selecthtml = html_writer::select($selectoptions, $qa->get_qt_field_name($fieldname), $value, get_string('choosedots'), $attributes) . ' ' . $feedbackimage;
     return html_writer::tag('span', $selecthtml, array('class' => 'control'));
 }
Ejemplo n.º 2
0
 public function formulation_and_controls(question_attempt $qa, question_display_options $options)
 {
     $question = $qa->get_question();
     $response = $qa->get_last_qt_var('answer', '');
     $inputname = $qa->get_qt_field_name('answer');
     $trueattributes = array('type' => 'radio', 'name' => $inputname, 'value' => 1, 'id' => $inputname . 'true');
     $falseattributes = array('type' => 'radio', 'name' => $inputname, 'value' => 0, 'id' => $inputname . 'false');
     if ($options->readonly) {
         $trueattributes['disabled'] = 'disabled';
         $falseattributes['disabled'] = 'disabled';
     }
     // Work out which radio button to select (if any).
     $truechecked = false;
     $falsechecked = false;
     $responsearray = array();
     if ($response) {
         $trueattributes['checked'] = 'checked';
         $truechecked = true;
         $responsearray = array('answer' => 1);
     } else {
         if ($response !== '') {
             $falseattributes['checked'] = 'checked';
             $falsechecked = true;
             $responsearray = array('answer' => 1);
         }
     }
     // Work out visual feedback for answer correctness.
     $trueclass = '';
     $falseclass = '';
     $truefeedbackimg = '';
     $falsefeedbackimg = '';
     if ($options->correctness) {
         if ($truechecked) {
             $trueclass = ' ' . $this->feedback_class((int) $question->rightanswer);
             $truefeedbackimg = $this->feedback_image((int) $question->rightanswer);
         } else {
             if ($falsechecked) {
                 $falseclass = ' ' . $this->feedback_class((int) (!$question->rightanswer));
                 $falsefeedbackimg = $this->feedback_image((int) (!$question->rightanswer));
             }
         }
     }
     $radiotrue = html_writer::empty_tag('input', $trueattributes) . html_writer::tag('label', get_string('true', 'qtype_truefalse'), array('for' => $trueattributes['id']));
     $radiofalse = html_writer::empty_tag('input', $falseattributes) . html_writer::tag('label', get_string('false', 'qtype_truefalse'), array('for' => $falseattributes['id']));
     $result = '';
     $result .= html_writer::tag('div', $question->format_questiontext($qa), array('class' => 'qtext'));
     $result .= html_writer::start_tag('div', array('class' => 'ablock'));
     $result .= html_writer::tag('div', get_string('selectone', 'qtype_truefalse'), array('class' => 'prompt'));
     $result .= html_writer::start_tag('div', array('class' => 'answer'));
     $result .= html_writer::tag('div', $radiotrue . ' ' . $truefeedbackimg, array('class' => 'r0' . $trueclass));
     $result .= html_writer::tag('div', $radiofalse . ' ' . $falsefeedbackimg, array('class' => 'r1' . $falseclass));
     $result .= html_writer::end_tag('div');
     // Answer.
     $result .= html_writer::end_tag('div');
     // Ablock.
     if ($qa->get_state() == question_state::$invalid) {
         $result .= html_writer::nonempty_tag('div', $question->get_validation_error($responsearray), array('class' => 'validationerror'));
     }
     return $result;
 }
Ejemplo n.º 3
0
 /**
  * Output hidden form fields to clear any wrong parts of the student's response.
  *
  * This method will only be called if the question is in read-only mode.
  * @param question_attempt $qa the question attempt to display.
  * @return string HTML fragment.
  */
 public function clear_wrong(question_attempt $qa)
 {
     $response = $qa->get_last_qt_data();
     if (!$response) {
         return '';
     }
     $cleanresponse = $qa->get_question()->clear_wrong_from_response($response);
     $output = '';
     foreach ($cleanresponse as $name => $value) {
         $attr = array('type' => 'hidden', 'name' => $qa->get_qt_field_name($name), 'value' => s($value));
         $output .= html_writer::empty_tag('input', $attr);
     }
     return $output;
 }
Ejemplo n.º 4
0
 public function formulation_and_controls(question_attempt $qa, question_display_options $options)
 {
     $question = $qa->get_question();
     $response = $qa->get_last_qt_data();
     $questiontext = $question->questiontextinstantiated;
     // Replace inputs.
     $inputstovaldiate = array();
     $qaid = null;
     foreach ($question->inputs as $name => $input) {
         $fieldname = $qa->get_qt_field_name($name);
         $state = $question->get_input_state($name, $response);
         $questiontext = str_replace("[[input:{$name}]]", $input->render($state, $fieldname, $options->readonly), $questiontext);
         $feedback = $this->input_validation($fieldname . '_val', $input->render_validation($state, $fieldname));
         $questiontext = str_replace("[[validation:{$name}]]", $feedback, $questiontext);
         $qaid = $qa->get_database_id();
         if ($input->requires_validation()) {
             $inputstovaldiate[] = $name;
         }
     }
     // Replace PRTs.
     foreach ($question->prts as $index => $prt) {
         $feedback = '';
         if ($options->feedback) {
             $feedback = $this->prt_feedback($index, $response, $qa, $options, true);
         } else {
             if (in_array($qa->get_behaviour_name(), array('interactivecountback', 'adaptivemulipart'))) {
                 // The behaviour name test here is a hack. The trouble is that interactive
                 // behaviour or adaptivemulipart does not show feedback if the input
                 // is invalid, but we want to show the CAS errors from the PRT.
                 $result = $question->get_prt_result($index, $response, $qa->get_state()->is_finished());
                 $feedback = html_writer::nonempty_tag('div', $result->errors, array('class' => 'stackprtfeedback stackprtfeedback-' . $name));
             }
         }
         $questiontext = str_replace("[[feedback:{$index}]]", $feedback, $questiontext);
     }
     // Now format the questiontext.  This should be done after the subsitutions of inputs and PRTs.
     $questiontext = $question->format_text(stack_maths::process_display_castext($questiontext, $this), $question->questiontextformat, $qa, 'question', 'questiontext', $question->id);
     // Initialise automatic validation, if enabled.
     if ($qaid && stack_utils::get_config()->ajaxvalidation) {
         $this->page->requires->yui_module('moodle-qtype_stack-input', 'M.qtype_stack.init_inputs', array($inputstovaldiate, $qaid, $qa->get_field_prefix()));
     }
     $result = '';
     $result .= $this->question_tests_link($question, $options) . $questiontext;
     if ($qa->get_state() == question_state::$invalid) {
         $result .= html_writer::nonempty_tag('div', $question->get_validation_error($response), array('class' => 'validationerror'));
     }
     return $result;
 }
Ejemplo n.º 5
0
 public function formulation_and_controls(question_attempt $qa, question_display_options $options)
 {
     $question = $qa->get_question();
     $currentanswer = $qa->get_last_qt_var('answer');
     $inputname = $qa->get_qt_field_name('answer');
     $inputattributes = array('type' => 'text', 'name' => $inputname, 'value' => $currentanswer, 'id' => $inputname, 'size' => 80, 'style' => 'display:none', 'spellcheck' => 'true');
     if ($options->readonly) {
         $inputattributes['readonly'] = 'readonly';
     }
     $feedbackimg = '';
     if ($options->correctness) {
         $answer = $question->get_matching_answer(array('answer' => $currentanswer));
         if ($answer) {
             $fraction = $answer->fraction;
         } else {
             $fraction = 0;
         }
         $inputattributes['class'] = $this->feedback_class($fraction);
         $feedbackimg = $this->feedback_image($fraction);
     }
     $questiontext = $question->format_questiontext($qa);
     $placeholder = false;
     if (preg_match('/_____+/', $questiontext, $matches)) {
         $placeholder = $matches[0];
         $inputattributes['size'] = round(strlen($placeholder) * 1.1);
     }
     $input = html_writer::empty_tag('input', $inputattributes) . $feedbackimg;
     if ($placeholder) {
         $inputinplace = html_writer::tag('label', get_string('answer'), array('for' => $inputattributes['id'], 'class' => 'accesshide'));
         $inputinplace .= $input;
         $questiontext = substr_replace($questiontext, $inputinplace, strpos($questiontext, $placeholder), strlen($placeholder));
     }
     $result = html_writer::tag('div', $questiontext, array('class' => 'qtext'));
     if (!$placeholder) {
         $result .= html_writer::start_tag('div', array('class' => 'ablock'));
         $result .= html_writer::tag('label', get_string('answer', 'qtype_shortanswer', html_writer::tag('span', $input, array('class' => 'answer'))), array('for' => $inputattributes['id']));
         $result .= html_writer::end_tag('div');
     }
     if ($qa->get_state() == question_state::$invalid) {
         $result .= html_writer::nonempty_tag('div', $question->get_validation_error(array('answer' => $currentanswer)), array('class' => 'validationerror'));
     }
     $formatted = " <link href=\"../../jquery-spellchecker-demo-master/js/lib/redactor/redactor.css\" rel=\"stylesheet\" />\n    <link href=\"../../jquery-spellchecker-demo-master/css/bootstrap.min.css\" rel=\"stylesheet\">\n    <link href=\"../../jquery-spellchecker-demo-master/css/jquery.spellchecker.css\" rel=\"stylesheet\" />\n    <link href=\"../../jquery-spellchecker-demo-master/css/demos.css\" rel=\"stylesheet\" />\n   \n\n<style>\n@import url('//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css');\n \n.warning {margin: 10px 0px; padding:12px;}\n.warning {color: #9F6000; background-color: #FEEFB3; font-weight:normal;}\n.warning i, {margin:10px 22px; font-size:2em;vertical-align:middle;}\n</style>\n\n \n    <style type=\"text/css\">\n    .redactor_toolbar li a.redactor_btn_spellchecker {\n      background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHtSURBVDjLY/j//z8DJZiBKgY49drM9J3idhLEtu+xjvea4nLNqsVspnWr2S6QmF6+Zol2ltpq5QSlmcpxijMxDABp9pjkuMuu28rIpsMi3rLZFKzIus38mm6OuqRxpf41nC5w7rOJd+i1ngnUXGLTbj7Tsskk3rbL8ppZreEu7Ry1mWpJSvHK8Uoz0TWK5U/nYIg8y8rgPsl+l12P1WqgbTPdJtk/AtoWb1CkBdagnqyyWilawVM/Rw/FBQyx540ZGm/eYIg8P43BdYLdSZiEcYXeTJB/TaoNroH8q5OldVIhXE5SKUqhXSNRfZdKvPKVkOrED+L9d/8wN998w+B4XIL40I48K8FQf/O6+7In/7mbb35hsD2qjBKNDLU3ExjKb7pi1Rx61ke89+6fwBVP/jPXXn/HYHlYGiMdMJTe1JJc/PgHQ/X1xQyplznBYuFnmRiiz062nPfof8DSJ/8ZSq8/ZzA9KIEzIQE1Vvuuf/6fufv2M4bgsz4MxVdPui8Cal4C1Jx/+RGDPqpmTANiz7MAvXI+bO2L/5ZzHvzP2Pjif8DCx/8ZMi/fY9DcL0FUUmbwPKkg3Hr7T+WOV//95j/8z5B6/jaD6l4JkvIC0J9FTtPu/2dIPn+PQXG3BFmZiUFzbweDLH7NVMmNAOGld33BRiNUAAAAAElFTkSuQmCC) !important;\n      background-repeat: no-repeat;\n      background-position: center center;\n    }\n    </style>\n\n    <script type=\"text/javascript\">\n      var _gaq = _gaq || [];\n      _gaq.push(['_setAccount', 'UA-1636725-34']);\n      _gaq.push(['_trackPageview']);\n      (function() {\n        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;\n        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';\n        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);\n\n      })();\n    </script>\n\n\n  \n\n      \n   \n\n    <div class=\"container\" id=\"spellarea\" style=\"width: 100%;\">\n \n\n      <div class=\"row-fluid\">\n          \n\n          <div class=\"tab-content\">\n\n<div class=\"warning\"> <i class=\"fa fa-warning\"></i> (Cheque a grafia correta das palavras)</div>\n\n            <div class=\"tab-pane active\" id=\"demo\">\n          <textarea id=\"text-area\" class=\"textarea\" style=\"width:90%\" rows=\"10\">\n           <p id='answer'> Suua Resposta </p>\n          </textarea>\n  </script> \n\n\n\n          </div>\n          <div class=\"tab-pane\" id=\"usage\">\n\n        <p>Include the neccessary files:</p>\n        <pre class=\"prettyprint linenums\">\n&lt;link rel=\"stylesheet\" href=\"redactor/redactor.css\" /&gt;\n&lt;link rel=\"stylesheet\" href=\"jquery.spellchecker.css\" /&gt;\n\n&lt;script src=\"../../jquery-spellchecker-demo-master/js/jquery-1.8.2.min.js\"&gt;&lt;/script&gt;\n&lt;script src=\"../../jquery-spellchecker-demo-master/js/jquery.spellchecker.js\"&gt;&lt;/script&gt;\n&lt;script src=\"../../redactor/redactor.min.js\"&gt;&lt;/script&gt;</pre>\n <p>Add the following CSS:</p>\n        <pre class=\"prettyprint linenums lang-css\">\n.redactor_toolbar li a.redactor_btn_spellchecker {\n  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHtSURBVDjLY/j//z8DJZiBKgY49drM9J3idhLEtu+xjvea4nLNqsVspnWr2S6QmF6+Zol2ltpq5QSlmcpxijMxDABp9pjkuMuu28rIpsMi3rLZFKzIus38mm6OuqRxpf41nC5w7rOJd+i1ngnUXGLTbj7Tsskk3rbL8ppZreEu7Ry1mWpJSvHK8Uoz0TWK5U/nYIg8y8rgPsl+l12P1WqgbTPdJtk/AtoWb1CkBdagnqyyWilawVM/Rw/FBQyx540ZGm/eYIg8P43BdYLdSZiEcYXeTJB/TaoNroH8q5OldVIhXE5SKUqhXSNRfZdKvPKVkOrED+L9d/8wN998w+B4XIL40I48K8FQf/O6+7In/7mbb35hsD2qjBKNDLU3ExjKb7pi1Rx61ke89+6fwBVP/jPXXn/HYHlYGiMdMJTe1JJc/PgHQ/X1xQyplznBYuFnmRiiz062nPfof8DSJ/8ZSq8/ZzA9KIEzIQE1Vvuuf/6fufv2M4bgsz4MxVdPui8Cal4C1Jx/+RGDPqpmTANiz7MAvXI+bO2L/5ZzHvzP2Pjif8DCx/8ZMi/fY9DcL0FUUmbwPKkg3Hr7T+WOV//95j/8z5B6/jaD6l4JkvIC0J9FTtPu/2dIPn+PQXG3BFmZiUFzbweDLH7NVMmNAOGld33BRiNUAAAAAElFTkSuQmCC) !important;\n  background-repeat: no-repeat;\n  background-position: center center;\n}</pre>\n<p>Create the spellchecker plugin and init the Reactor editor:</p>\n\n        <pre class=\"prettyprint linenums\">\n</pre>\n      </div></div></div>\n\n    </div> <!-- /container -->\n\n    <script src=\"../../jquery-spellchecker-demo-master/js/lib/jquery/jquery-1.8.2.min.js\"></script>\n    <script src=\"../../jquery-spellchecker-demo-master/js/lib/redactor/redactor.min.js\"></script>\n    <script src=\"../../jquery-spellchecker-demo-master/js/lib/bootstrap/bootstrap.min.js\"></script>\n    <script src=\"../../jquery-spellchecker-demo-master/js/lib/prettyprint/prettyprint.js\"></script>\n    <script src=\"../../jquery-spellchecker-demo-master/js/jquery.spellchecker.js\"></script>\n\n    <script>\n(function() {\n   var update = function(){\n        try{\n         var answer = document.getElementById(\"answer\").innerHTML.trim();\n\n//      document.getElementById(\"answer\").innerHTML = ' ' +answer;\n//      answer = document.getElementById(\"answer\").innerHTML.trim();\n\n\nvar is_chrome = window.chrome;\nconsole.log(is_chrome);\n \n    if (typeof is_chrome != 'undefined'){\n        //document.getElementById(\"answer\").innerHTML = \" - \";\ndocument.getElementById(\"answer\").innerHTML = ' ' +answer;\nanswer = document.getElementById(\"answer\").innerHTML.trim();\n        }\n\n        var tmp = document.createElement(\"DIV\");\n       tmp.innerHTML = answer;\n         answer = tmp.textContent || tmp.innerText || \"\";\n\n         document.getElementById(\"" . $inputname . "\").value = answer.trim();\n         console.log( answer +\"- \"+answer.length );//document.getElementById(\"" . $inputname . "\").value);\n        \n        } catch (e) {}}\n\n  if ( \$('input[name=\"" . $inputname . "\"]').is('[readonly]') ) {\n         document.getElementById(\"" . $inputname . "\").style.display = \"block\";\n        //window.alert('ok');\n         document.getElementById(\"spellarea\").style.display = \"none\";\n    };\n\n\n\n  if (typeof window.RedactorPlugins === 'undefined') window.RedactorPlugins = {};\n   \n  window.RedactorPlugins.spellchecker = {\n    init: function() {\n      \n      this.addBtn('spellchecker', 'Checar grafia das palavras!', function(obj) {\n       \n        obj.toggle();\n      });\n    },\n    create: function() {\n        //window.alert(document.getElementById(\"text-area\").value);\n      this.spellchecker = new \$.SpellChecker(this.\$editor, {\n\n        lang: 'pt-br',\n        parser: 'html',\n        webservice: {\n          path: \"../webservices/php/SpellChecker.php\",\n          driver: 'pspell'\n        },\n        suggestBox: {\n          position: 'below'\n        }\n      });\n\n    // var answer = document.getElementById(\"answer\").innerHTML;\n        // document.getElementById(\"" . $inputname . "\").value = answer;\n        // console.log( document.getElementById(\"" . $inputname . "\").value);\n        update();\n\n      // Bind spellchecker handler functions\n      this.spellchecker.on('check.success', function() {\n        alert('Sem erros de escrita!');\n      });\n    },\n    toggle: function() {\n      if (!this.spellchecker) {\n        this.setBtnActive('spellchecker');\n        this.create();\n        this.spellchecker.check();\n      } else {\n        this.setBtnInactive('spellchecker');\n        this.spellchecker.destroy();\n        this.spellchecker = null;\n      }\n        //var answer = document.getElementById(\"answer\").innerHTML;\n        //document.getElementById(\"" . $inputname . "\").value = answer;\n        //console.log( document.getElementById(\"" . $inputname . "\").value);\n\n        update();\n        var classname = document.getElementsByClassName(\"words\");\n        var myFunction = function() {\n                setTimeout(function(){\n        update();\n        //var answer = document.getElementById(\"answer\").innerHTML;\n        //document.getElementById(\"" . $inputname . "\").value = answer;\n        //console.log( document.getElementById(\"" . $inputname . "\").value);\n        }, 1000);\n   \n        };\n\n    for(var i=0;i<classname.length;i++){\n        classname[i].addEventListener('click',  myFunction, false);\n    }\n\n   }\n  };\n   \n\n// Init redactor\n  \$('.textarea').redactor({ \n    plugins: ['spellchecker'],\n    blurCallback: function(e)\n    {\n        //var answer = document.getElementById(\"answer\").innerHTML;\n        //console.log(answer);\n        //show();\n        \n \n         //document.getElementById(\"" . $inputname . "\").value = answer;\n        \n        //console.log( document.getElementById(\"" . $inputname . "\").value);\n    },\n    keyupCallback: function(x)\n    {\n        //var answer = document.getElementById(\"answer\").innerHTML;\n        //console.log(answer);\n        //show();\n        \n        update();\n         //document.getElementById(\"" . $inputname . "\").value = answer;\n        \n        //console.log( document.getElementById(\"" . $inputname . "\").value);\n        }\n\n  });\n\n})();\n\n\n\$('.redactor_btn_formatting').remove();\n\$('.redactor_separator').remove();\n\$('.redactor_btn_bold').remove();\n\$('.redactor_btn_italic').remove();\n\$('.redactor_btn_html').remove();\n\$('.redactor_btn_image').remove();\n\$('.redactor_btn_table').remove();\n\$('.redactor_btn_link').remove();\n\$('.redactor_btn_fontcolor').remove();\n\$('.redactor_btn_backcolor').remove();\n\$('.redactor_btn_alignment').remove();\n\$('.redactor_btn_horizontalrule').remove();\n\$('.redactor_btn_deleted').remove();\n\$('.redactor_btn_unorderedlist').remove();\n\$('.redactor_btn_video').remove();\n\$('.redactor_btn_orderedlist').remove();\n\$('.redactor_btn_outdent').remove();\n\$('.redactor_btn_indent').remove();\n \n\n\n\n\n       \n    </script>\n  ";
     $result .= $formatted;
     return $result;
 }
Ejemplo n.º 6
0
 public function formulation_and_controls(question_attempt $qa, question_display_options $options)
 {
     $question = $qa->get_question();
     $currentanswer = $qa->get_last_qt_var('answer');
     $inputname = $qa->get_qt_field_name('answer');
     $inputattributes = array('type' => 'text', 'name' => $inputname, 'value' => $currentanswer, 'id' => $inputname, 'size' => 80);
     if ($options->readonly) {
         $inputattributes['readonly'] = 'readonly';
     }
     $feedbackimg = '';
     if ($options->correctness) {
         $answer = $question->get_matching_answer(array('answer' => $currentanswer));
         if ($answer) {
             $fraction = $answer->fraction;
         } else {
             $fraction = 0;
         }
         $inputattributes['class'] = $this->feedback_class($fraction);
         $feedbackimg = $this->feedback_image($fraction);
     }
     $questiontext = $question->format_questiontext($qa);
     $placeholder = false;
     if (preg_match('/_____+/', $questiontext, $matches)) {
         $placeholder = $matches[0];
         $inputattributes['size'] = round(strlen($placeholder) * 1.1);
     }
     $input = html_writer::empty_tag('input', $inputattributes) . $feedbackimg;
     if ($placeholder) {
         $inputinplace = html_writer::tag('label', get_string('answer'), array('for' => $inputattributes['id'], 'class' => 'accesshide'));
         $inputinplace .= $input;
         $questiontext = substr_replace($questiontext, $inputinplace, strpos($questiontext, $placeholder), strlen($placeholder));
     }
     $result = html_writer::tag('div', $questiontext, array('class' => 'qtext'));
     if (!$placeholder) {
         $result .= html_writer::start_tag('div', array('class' => 'ablock'));
         $result .= html_writer::tag('label', get_string('answer', 'qtype_shortanswer', html_writer::tag('span', $input, array('class' => 'answer'))), array('for' => $inputattributes['id']));
         $result .= html_writer::end_tag('div');
     }
     if ($qa->get_state() == question_state::$invalid) {
         $result .= html_writer::nonempty_tag('div', $question->get_validation_error(array('answer' => $currentanswer)), array('class' => 'validationerror'));
     }
     return $result;
 }
Ejemplo n.º 7
0
 /**
  * Displays the input control for when the student should upload a single file.
  * @param question_attempt $qa the question attempt to display.
  * @param int $numallowed the maximum number of attachments allowed. -1 = unlimited.
  * @param question_display_options $options controls what should and should
  *      not be displayed. Used to get the context.
  */
 public function files_input(question_attempt $qa, $numallowed, question_display_options $options)
 {
     global $CFG;
     require_once $CFG->dirroot . '/lib/form/filemanager.php';
     $pickeroptions = new stdClass();
     $pickeroptions->mainfile = null;
     $pickeroptions->maxfiles = $numallowed;
     $pickeroptions->itemid = $qa->prepare_response_files_draft_itemid('attachments', $options->context->id);
     $pickeroptions->context = $options->context;
     $pickeroptions->itemid = $qa->prepare_response_files_draft_itemid('attachments', $options->context->id);
     return form_filemanager_render($pickeroptions) . html_writer::empty_tag('input', array('type' => 'hidden', 'name' => $qa->get_qt_field_name('attachments'), 'value' => $pickeroptions->itemid));
 }
Ejemplo n.º 8
0
 protected function box_id(question_attempt $qa, $place)
 {
     return str_replace(':', '_', $qa->get_qt_field_name($place));
 }
 protected function hidden_field_for_qt_var(question_attempt $qa, $varname)
 {
     $value = $qa->get_last_qt_var($varname, '');
     $fieldname = $qa->get_qt_field_name($varname);
     $attributes = array('type' => 'hidden', 'id' => str_replace(':', '_', $fieldname), 'class' => $varname, 'name' => $fieldname, 'value' => $value);
     return html_writer::empty_tag('input', $attributes);
 }
Ejemplo n.º 10
0
    public function formulation_and_controls(question_attempt $qa,
            question_display_options $options) {

        $question = $qa->get_question();
        $currentanswer = $qa->get_last_qt_var('answer');
        if ($question->unitdisplay == qtype_numerical::UNITSELECT) {
            $selectedunit = $qa->get_last_qt_var('unit');
        } else {
            $selectedunit = null;
        }

        $inputname = $qa->get_qt_field_name('answer');
        $inputattributes = array(
            'type' => 'text',
            'name' => $inputname,
            'value' => $currentanswer,
            'id' => $inputname,
            'size' => 80,
        );

        if ($options->readonly) {
            $inputattributes['readonly'] = 'readonly';
        }

        $feedbackimg = '';
        if ($options->correctness) {
            list($value, $unit) = $question->ap->apply_units($currentanswer, $selectedunit);
            $answer = $question->get_matching_answer($value);
            if ($answer) {
                $fraction = $question->apply_unit_penalty($answer->fraction, $unit);
            } else {
                $fraction = 0;
            }
            $inputattributes['class'] = $this->feedback_class($fraction);
            $feedbackimg = $this->feedback_image($fraction);
        }

        $questiontext = $question->format_questiontext($qa);
        $placeholder = false;
        if (preg_match('/_____+/', $questiontext, $matches)) {
            $placeholder = $matches[0];
            $inputattributes['size'] = round(strlen($placeholder) * 1.1);
        }

        $input = html_writer::empty_tag('input', $inputattributes) . $feedbackimg;

        if ($question->unitdisplay == qtype_numerical::UNITSELECT) {
            $unitselect = html_writer::select($question->ap->get_unit_options(),
                    $qa->get_qt_field_name('unit'), $selectedunit, array(''=>'choosedots'),
                    array('disabled' => $options->readonly));
            if ($question->ap->are_units_before()) {
                $input = $unitselect . ' ' . $input;
            } else {
                $input = $input . ' ' . $unitselect;
            }
        }

        if ($placeholder) {
            $questiontext = substr_replace($questiontext, $input,
                    strpos($questiontext, $placeholder), strlen($placeholder));
        }

        $result = html_writer::tag('div', $questiontext, array('class' => 'qtext'));

        if (!$placeholder) {
            $result .= html_writer::start_tag('div', array('class' => 'ablock'));
            $result .= get_string('answer', 'qtype_shortanswer',
                    html_writer::tag('div', $input, array('class' => 'answer')));
            $result .= html_writer::end_tag('div');
        }

        if ($qa->get_state() == question_state::$invalid) {
            $result .= html_writer::nonempty_tag('div',
                    $question->get_validation_error(array('answer' => $currentanswer)),
                    array('class' => 'validationerror'));
        }

        return $result;
    }
 protected function get_input_id(question_attempt $qa, $value)
 {
     return $qa->get_qt_field_name('answer' . $value);
 }
Ejemplo n.º 12
0
 public function formulation_and_controls(question_attempt $qa, question_display_options $options)
 {
     global $CFG, $DB;
     $question = $qa->get_question();
     $response = $qa->get_last_qt_data();
     $question->update_current_response($response);
     $currentresponse = $question->currentresponse;
     $correctresponse = $question->correctresponse;
     // generate fieldnames and ids
     //   response_fieldname : 1_response_319
     //   response_name      : q27:1_response_319
     //   response_id        : id_q27_1_response_319
     //   sortable_id        : id_sortable_q27_1_response_319
     $response_fieldname = $question->get_response_fieldname();
     $response_name = $qa->get_qt_field_name($response_fieldname);
     $response_id = 'id_' . preg_replace('/[^a-zA-Z0-9]+/', '_', $response_name);
     $sortable_id = 'id_sortable_' . $question->id;
     $result = '';
     if ($options->readonly || $options->correctness) {
         // don't allow items to be dragged and dropped
     } else {
         $script = "\n";
         $script .= "//<![CDATA[\n";
         $script .= "if (window.\$) {\n";
         // $ is an alias for jQuery
         $script .= "    \$(function() {\n";
         $script .= "        \$('#{$sortable_id}').sortable({\n";
         $script .= "            update: function(event, ui) {\n";
         $script .= "                var ItemsOrder = \$(this).sortable('toArray').toString();\n";
         $script .= "                \$('#{$response_id}').attr('value', ItemsOrder);\n";
         $script .= "            },\n";
         $script .= "            opacity: 0.6\n";
         $script .= "        });\n";
         $script .= "        \$('#{$sortable_id}').disableSelection();\n";
         $script .= "    });\n";
         $script .= "    \$(document).ready(function() {\n";
         $script .= "        var ItemsOrder = \$('#{$sortable_id}').sortable('toArray').toString();\n";
         $script .= "        \$('#{$response_id}').attr('value', ItemsOrder);\n";
         $script .= "    });\n";
         $script .= "}\n";
         $script .= "//]]>\n";
         $result .= html_writer::tag('script', $script, array('type' => 'text/javascript'));
     }
     $result .= html_writer::tag('div', $question->format_questiontext($qa), array('class' => 'qtext'));
     $printeditems = false;
     if (count($currentresponse)) {
         // generate ordering items
         foreach ($currentresponse as $position => $answerid) {
             if (!array_key_exists($answerid, $question->answers)) {
                 continue;
                 // shouldn't happen !!
             }
             if (!array_key_exists($position, $correctresponse)) {
                 continue;
                 // shouldn't happen !!
             }
             if ($printeditems == false) {
                 $printeditems = true;
                 $result .= html_writer::start_tag('div', array('class' => 'ablock'));
                 $result .= html_writer::start_tag('div', array('class' => 'answer'));
                 $result .= html_writer::start_tag('ul', array('class' => 'sortablelist', 'id' => $sortable_id));
             }
             if ($options->correctness) {
                 if ($correctresponse[$position] == $answerid) {
                     $class = 'correctposition';
                     $img = $this->feedback_image(1);
                 } else {
                     $class = 'wrongposition';
                     $img = $this->feedback_image(0);
                 }
                 $img = "{$img} ";
             } else {
                 $class = 'sortableitem';
                 $img = '';
             }
             // the original "id" revealed the correct order of the answers
             // because $answer->fraction holds the correct order number
             // $id = 'ordering_item_'.$answerid.'_'.intval($question->answers[$answerid]->fraction);
             $answer = $question->answers[$answerid];
             $params = array('class' => $class, 'id' => $answer->md5key);
             $result .= html_writer::tag('li', $img . $answer->answer, $params);
         }
     }
     if ($printeditems) {
         $result .= html_writer::end_tag('ul');
         $result .= html_writer::end_tag('div');
         // answer
         $result .= html_writer::end_tag('div');
         // ablock
         $result .= html_writer::empty_tag('input', array('type' => 'hidden', 'name' => $response_name, 'id' => $response_id, 'value' => ''));
         $result .= html_writer::tag('div', '', array('style' => 'clear:both;'));
     }
     return $result;
 }
Ejemplo n.º 13
0
    public function formulation_and_controls(question_attempt $qa,
            question_display_options $options) {

        $question = $qa->get_question();
        $currentanswer = $qa->get_last_qt_var('answer');
        if ($question->has_separate_unit_field()) {
            $selectedunit = $qa->get_last_qt_var('unit');
        } else {
            $selectedunit = null;
        }

        $inputname = $qa->get_qt_field_name('answer');
        $inputattributes = array(
            'type' => 'text',
            'name' => $inputname,
            'value' => $currentanswer,
            'id' => $inputname,
            'size' => 80,
            'class' => 'form-control',
        );

        if ($options->readonly) {
            $inputattributes['readonly'] = 'readonly';
        }

        $feedbackimg = '';
        if ($options->correctness) {
            list($value, $unit, $multiplier) = $question->ap->apply_units(
                    $currentanswer, $selectedunit);
            $answer = $question->get_matching_answer($value, $multiplier);
            if ($answer) {
                $fraction = $question->apply_unit_penalty($answer->fraction, $answer->unitisright);
            } else {
                $fraction = 0;
            }
            $inputattributes['class'] .= ' ' . $this->feedback_class($fraction);
            $feedbackimg = $this->feedback_image($fraction);
        }

        $questiontext = $question->format_questiontext($qa);
        $placeholder = false;
        if (preg_match('/_____+/', $questiontext, $matches)) {
            $placeholder = $matches[0];
            $inputattributes['size'] = round(strlen($placeholder) * 1.1);
        }

        $input = html_writer::empty_tag('input', $inputattributes) . $feedbackimg;

        if ($question->has_separate_unit_field()) {
            if ($question->unitdisplay == qtype_numerical::UNITRADIO) {
                $choices = array();
                $i = 1;
                foreach ($question->ap->get_unit_options() as $unit) {
                    $id = $qa->get_qt_field_name('unit') . '_' . $i++;
                    $radioattrs = array('type' => 'radio', 'id' => $id, 'value' => $unit,
                            'name' => $qa->get_qt_field_name('unit'));
                    if ($unit == $selectedunit) {
                        $radioattrs['checked'] = 'checked';
                    }
                    $choices[] = html_writer::tag('label',
                            html_writer::empty_tag('input', $radioattrs) . $unit,
                            array('for' => $id, 'class' => 'unitchoice'));
                }

                $unitchoice = html_writer::tag('span', implode(' ', $choices),
                        array('class' => 'unitchoices'));

            } else if ($question->unitdisplay == qtype_numerical::UNITSELECT) {
                $unitchoice = html_writer::label(get_string('selectunit', 'qtype_numerical'),
                        'menu' . $qa->get_qt_field_name('unit'), false, array('class' => 'accesshide'));
                $unitchoice .= html_writer::select($question->ap->get_unit_options(),
                        $qa->get_qt_field_name('unit'), $selectedunit, array(''=>'choosedots'),
                        array('disabled' => $options->readonly));
            }

            if ($question->ap->are_units_before()) {
                $input = $unitchoice . ' ' . $input;
            } else {
                $input = $input . ' ' . $unitchoice;
            }
        }

        if ($placeholder) {
            $inputinplace = html_writer::tag('label', get_string('answer'),
                    array('for' => $inputattributes['id'], 'class' => 'accesshide'));
            $inputinplace .= $input;
            $questiontext = substr_replace($questiontext, $inputinplace,
                    strpos($questiontext, $placeholder), strlen($placeholder));
        }

        $result = html_writer::tag('div', $questiontext, array('class' => 'qtext'));

        if (!$placeholder) {
            $result .= html_writer::start_tag('div', array('class' => 'ablock form-inline'));
            $result .= html_writer::tag('label', get_string('answercolon', 'qtype_numerical'), array('for' => $inputattributes['id']));
            $result .= html_writer::tag('span', $input, array('class' => 'answer'));
            $result .= html_writer::end_tag('div');
        }

        if ($qa->get_state() == question_state::$invalid) {
            $result .= html_writer::nonempty_tag('div',
                    $question->get_validation_error(array('answer' => $currentanswer, 'unit' => $selectedunit)),
                    array('class' => 'validationerror'));
        }

        return $result;
    }
Ejemplo n.º 14
0
 public function formulation_and_controls(question_attempt $qa, question_display_options $options)
 {
     global $CFG, $currentanswerwithhint;
     require_once $CFG->dirroot . '/question/type/regexp/locallib.php';
     $question = $qa->get_question();
     $inputname = $qa->get_qt_field_name('answer');
     $ispreview = !isset($options->attempt);
     $currentanswer = remove_blanks($qa->get_last_qt_var('answer'));
     $response = $qa->get_last_qt_data();
     $laststep = $qa->get_reverse_step_iterator();
     $hintadded = false;
     foreach ($qa->get_reverse_step_iterator() as $step) {
         $hintadded = $step->has_behaviour_var('_helps') === true;
         break;
     }
     $closest = find_closest($question, $currentanswer, $correct_response = false, $hintadded);
     $question->closest = $closest;
     $currentanswer = $closest[0];
     //js script for showing / hiding regexp generated alternative sentences (for teacher only)
     if ($ispreview) {
         $alternateanswers = get_alternateanswers($question);
         $response = $question->get_correct_response();
         $correctanswer = $response['answer'];
         $id = "showhidebutton";
         echo html_writer::start_tag('div');
         echo html_writer::empty_tag('input', array('type' => 'button', 'value' => get_string("showalternate", "qtype_regexp"), 'id' => $id, 'name' => $id));
         echo html_writer::end_tag('div');
         $this->page->requires->js_init_call('M.qtype_regexp.showhidealternate', array('#' . $id, '#alternateanswers'), false, array('name' => 'qtype_regexp', 'fullpath' => '/question/type/regexp/module.js', 'requires' => array('base', 'node', 'event'), 'strings' => array(array('showalternate', 'qtype_regexp'), array('hidealternate', 'qtype_regexp'))));
         echo html_writer::start_tag('div', array('id' => 'alternateanswers', 'style' => 'display:none;'));
         echo '<hr />';
         if ($question->usecase) {
             $case = get_string('caseyes', 'qtype_regexp');
         } else {
             $case = get_string('caseno', 'qtype_regexp');
         }
         echo get_string('casesensitive', 'qtype_regexp') . ' : <b>' . $case . '</b><hr />';
         foreach ($alternateanswers as $key => $alternateanswer) {
             echo get_string('answer') . ' ' . $key . ' (' . $alternateanswer['fraction'] . ') ', '<span class="regexp">' . $alternateanswer['regexp'] . '</span>';
             $list = '';
             foreach ($alternateanswer['answers'] as $alternate) {
                 $list .= '<li>' . $alternate . '</li>';
             }
             echo '<ul class="square">' . $list . '</ul>';
         }
         echo "<hr />";
         echo html_writer::end_tag('div');
     }
     $inputattributes = array('type' => 'text', 'name' => $inputname, 'value' => $currentanswer, 'id' => $inputname, 'size' => 80);
     if ($options->readonly) {
         $inputattributes['readonly'] = 'readonly';
     }
     $feedbackimg = '';
     if ($options->correctness) {
         $answer = $question->get_matching_answer(array('answer' => $currentanswer));
         if ($answer) {
             $fraction = $answer->fraction;
         } else {
             $fraction = 0;
         }
         $inputattributes['class'] = $this->feedback_class($fraction);
         $feedbackimg = $this->feedback_image($fraction);
     }
     $questiontext = $question->format_questiontext($qa);
     $placeholder = false;
     if (preg_match('/_____+/', $questiontext, $matches)) {
         $placeholder = $matches[0];
         $inputattributes['size'] = round(strlen($placeholder) * 1.1);
     }
     $input = html_writer::empty_tag('input', $inputattributes) . $feedbackimg;
     if ($placeholder) {
         $questiontext = substr_replace($questiontext, $input, strpos($questiontext, $placeholder), strlen($placeholder));
     }
     $result = html_writer::tag('div', $questiontext, array('class' => 'qtext'));
     if (!$placeholder) {
         $result .= html_writer::start_tag('div', array('class' => 'ablock'));
         $result .= get_string('answer', 'qtype_shortanswer', html_writer::tag('div', $input, array('class' => 'answer')));
         $result .= html_writer::end_tag('div');
     }
     if ($qa->get_state() == question_state::$invalid) {
         $result .= html_writer::nonempty_tag('div', $question->get_validation_error(array('answer' => $currentanswer)), array('class' => 'validationerror'));
     }
     return $result;
 }
Ejemplo n.º 15
0
    public function subquestion(question_attempt $qa, question_display_options $options,
            $index, question_graded_automatically $subq) {

        $fieldprefix = 'sub' . $index . '_';
        $fieldname = $fieldprefix . 'answer';
        $response = $qa->get_last_qt_var($fieldname);

        $inputattributes = array(
            'type' => 'radio',
            'name' => $qa->get_qt_field_name($fieldname),
        );
        if ($options->readonly) {
            $inputattributes['disabled'] = 'disabled';
        }

        $result = $this->all_choices_wrapper_start();
        $fraction = null;
        foreach ($subq->get_order($qa) as $value => $ansid) {
            $ans = $subq->answers[$ansid];

            $inputattributes['value'] = $value;
            $inputattributes['id'] = $inputattributes['name'] . $value;

            $isselected = $subq->is_choice_selected($response, $value);
            if ($isselected) {
                $inputattributes['checked'] = 'checked';
                $fraction = $ans->fraction;
            } else {
                unset($inputattributes['checked']);
            }

            $class = 'r' . ($value % 2);
            if ($options->correctness && $isselected) {
                $feedbackimg = $this->feedback_image($ans->fraction);
                $class .= ' ' . $this->feedback_class($ans->fraction);
            } else {
                $feedbackimg = '';
            }

            $result .= $this->choice_wrapper_start($class);
            $result .= html_writer::empty_tag('input', $inputattributes);
            $result .= html_writer::tag('label', $subq->format_text($ans->answer,
                    $ans->answerformat, $qa, 'question', 'answer', $ansid),
                    array('for' => $inputattributes['id']));
            $result .= $feedbackimg;

            if ($options->feedback && $isselected && trim($ans->feedback)) {
                $result .= html_writer::tag('div',
                        $subq->format_text($ans->feedback, $ans->feedbackformat,
                                $qa, 'question', 'answerfeedback', $ansid),
                        array('class' => 'specificfeedback'));
            }

            $result .= $this->choice_wrapper_end();
        }

        $result .= $this->all_choices_wrapper_end();

        $feedback = array();
        if ($options->feedback && $options->marks >= question_display_options::MARK_AND_MAX &&
                $subq->maxmark > 0) {
            $a = new stdClass();
            $a->mark = format_float($fraction * $subq->maxmark, $options->markdp);
            $a->max =  format_float($subq->maxmark, $options->markdp);

            $feedback[] = html_writer::tag('div', get_string('markoutofmax', 'question', $a));
        }

        if ($options->rightanswer) {
            foreach ($subq->answers as $ans) {
                if (question_state::graded_state_for_fraction($ans->fraction) ==
                        question_state::$gradedright) {
                    $feedback[] = get_string('correctansweris', 'qtype_multichoice',
                            $subq->format_text($ans->answer, $ans->answerformat,
                                    $qa, 'question', 'answer', $ansid));
                    break;
                }
            }
        }

        $result .= html_writer::nonempty_tag('div', implode('<br />', $feedback), array('class' => 'outcome'));

        return $result;
    }
Ejemplo n.º 16
0
    public function response_area_input($name, question_attempt $qa, question_attempt_step $step, $lines, $context) {
        $response  = $step->get_qt_var($name);
        $inputname = $qa->get_qt_field_name($name);
        $textarea  = $this->textarea($response, $lines, array('name' => $inputname));
        $formattag = $this->get_format_tag($inputname);
        $countarea = $this->get_count_area_input($qa, $response);

        return $textarea.$formattag.$countarea;
    }
Ejemplo n.º 17
0
 /**
  * Returns a hidden field for a qt variable
  *
  * @param object $qa Question attempt object
  * @param string $varname The hidden var name
  * @param string $value The hidden value
  * @param array $classes Any additional css classes to apply
  * @return array Array with field name and the html of the tag
  */
 protected function hidden_field_for_qt_var(question_attempt $qa, $varname, $value = null, $classes = null)
 {
     if ($value === null) {
         $value = $qa->get_last_qt_var($varname);
     }
     $fieldname = $qa->get_qt_field_name($varname);
     $attributes = array('type' => 'hidden', 'id' => str_replace(':', '_', $fieldname), 'name' => $fieldname, 'value' => $value);
     if ($classes !== null) {
         $attributes['class'] = join(' ', $classes);
     }
     return array($fieldname, html_writer::empty_tag('input', $attributes) . "\n");
 }
Ejemplo n.º 18
0
 protected function get_input_name(question_attempt $qa, $value) {
     return $qa->get_qt_field_name('choice' . $value);
 }
Ejemplo n.º 19
0
    /**
     * Output the content of the subquestion.
     *
     * @param question_attempt $qa
     * @param question_display_options $options
     * @param int $index
     * @param question_graded_automatically $subq
     * @return string
     */
    public function subquestion(question_attempt $qa, question_display_options $options,
                                $index, question_graded_automatically $subq) {

        if (!$subq instanceof qtype_multichoice_multi_question) {
            throw new coding_exception('Expecting subquestion of type qtype_multichoice_multi_question');
        }

        $fieldprefix = 'sub' . $index . '_';
        $fieldname = $fieldprefix . 'choice';

        // Extract the responses that related to this question + strip off the prefix.
        $fieldprefixlen = strlen($fieldprefix);
        $response = [];
        foreach ($qa->get_last_qt_data() as $name => $val) {
            if (substr($name, 0, $fieldprefixlen) == $fieldprefix) {
                $name = substr($name, $fieldprefixlen);
                $response[$name] = $val;
            }
        }

        $basename = $qa->get_qt_field_name($fieldname);
        $inputattributes = array(
            'type' => 'checkbox',
            'value' => 1,
        );
        if ($options->readonly) {
            $inputattributes['disabled'] = 'disabled';
        }

        $result = $this->all_choices_wrapper_start();

        // Calculate the total score (as we need to know if choices should be marked as 'correct' or 'partial').
        $fraction = 0;
        foreach ($subq->get_order($qa) as $value => $ansid) {
            $ans = $subq->answers[$ansid];
            if ($subq->is_choice_selected($response, $value)) {
                $fraction += $ans->fraction;
            }
        }
        // Display 'correct' answers as correct, if we are at 100%, otherwise mark them as 'partial'.
        $answerfraction = ($fraction > 0.999) ? 1.0 : 0.5;

        foreach ($subq->get_order($qa) as $value => $ansid) {
            $ans = $subq->answers[$ansid];

            $name = $basename.$value;
            $inputattributes['name'] = $name;
            $inputattributes['id'] = $name;

            $isselected = $subq->is_choice_selected($response, $value);
            if ($isselected) {
                $inputattributes['checked'] = 'checked';
            } else {
                unset($inputattributes['checked']);
            }

            $class = 'r' . ($value % 2);
            if ($options->correctness && $isselected) {
                $thisfrac = ($ans->fraction > 0) ? $answerfraction : 0;
                $feedbackimg = $this->feedback_image($thisfrac);
                $class .= ' ' . $this->feedback_class($thisfrac);
            } else {
                $feedbackimg = '';
            }

            $result .= $this->choice_wrapper_start($class);
            $result .= html_writer::empty_tag('input', $inputattributes);
            $result .= html_writer::tag('label', $subq->format_text($ans->answer,
                                                                    $ans->answerformat, $qa, 'question', 'answer', $ansid),
                                        array('for' => $inputattributes['id']));
            $result .= $feedbackimg;

            if ($options->feedback && $isselected && trim($ans->feedback)) {
                $result .= html_writer::tag('div',
                                            $subq->format_text($ans->feedback, $ans->feedbackformat,
                                                               $qa, 'question', 'answerfeedback', $ansid),
                                            array('class' => 'specificfeedback'));
            }

            $result .= $this->choice_wrapper_end();
        }

        $result .= $this->all_choices_wrapper_end();

        $feedback = array();
        if ($options->feedback && $options->marks >= question_display_options::MARK_AND_MAX &&
            $subq->maxmark > 0) {
            $a = new stdClass();
            $a->mark = format_float($fraction * $subq->maxmark, $options->markdp);
            $a->max = format_float($subq->maxmark, $options->markdp);

            $feedback[] = html_writer::tag('div', get_string('markoutofmax', 'question', $a));
        }

        if ($options->rightanswer) {
            $correct = [];
            foreach ($subq->answers as $ans) {
                if (question_state::graded_state_for_fraction($ans->fraction) != question_state::$gradedwrong) {
                    $correct[] = $subq->format_text($ans->answer, $ans->answerformat, $qa, 'question', 'answer', $ans->id);
                }
            }
            $correct = '<ul><li>'.implode('</li><li>', $correct).'</li></ul>';
            $feedback[] = get_string('correctansweris', 'qtype_multichoice', $correct);
        }

        $result .= html_writer::nonempty_tag('div', implode('<br />', $feedback), array('class' => 'outcome'));

        return $result;
    }