MDL-67814 core_h5p: Update to eslintignore to handle included file.
[moodle.git] / question / type / ddwtos / renderer.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Drag-and-drop words into sentences question renderer class.
19  *
20  * @package   qtype_ddwtos
21  * @copyright 2010 The Open University
22  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
26 defined('MOODLE_INTERNAL') || die();
28 require_once($CFG->dirroot . '/question/type/gapselect/rendererbase.php');
31 /**
32  * Generates the output for drag-and-drop words into sentences questions.
33  *
34  * @copyright  2010 The Open University
35  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36  */
37 class qtype_ddwtos_renderer extends qtype_elements_embedded_in_question_text_renderer {
39     public function formulation_and_controls(question_attempt $qa,
40             question_display_options $options) {
42         $result = parent::formulation_and_controls($qa, $options);
44         $this->page->requires->js_call_amd('qtype_ddwtos/ddwtos', 'init',
45                 [$qa->get_outer_question_div_unique_id(), $options->readonly]);
46         return $result;
47     }
49     protected function post_qtext_elements(question_attempt $qa,
50             question_display_options $options) {
51         $result = '';
52         $question = $qa->get_question();
54         $dragboxs = '';
55         foreach ($question->choices as $group => $choices) {
56             $dragboxs .= $this->drag_boxes($qa, $group,
57                     $question->get_ordered_choices($group), $options);
58         }
60         $classes = array('answercontainer');
61         if ($options->readonly) {
62             $classes[] = 'readonly';
63         }
64         $result .= html_writer::tag('div', $dragboxs, array('class' => implode(' ', $classes)));
66         $classes = array('drags');
67         if ($options->readonly) {
68             $classes[] = 'readonly';
69         }
70         $result .= html_writer::tag('div', '', array('class' => implode(' ', $classes)));
72         // We abuse the clear_wrong method to output the hidden form fields we
73         // want irrespective of whether we are actually clearing the wrong
74         // bits of the response.
75         if (!$options->clearwrong) {
76             $result .= $this->clear_wrong($qa, false);
77         }
78         return $result;
79     }
81     protected function embedded_element(question_attempt $qa, $place,
82             question_display_options $options) {
83         $question = $qa->get_question();
84         $group = $question->places[$place];
85         $boxcontents = '&#160;' . html_writer::tag('span',
86                 get_string('blank', 'qtype_ddwtos'), array('class' => 'accesshide'));
88         $value = $qa->get_last_qt_var($question->field($place));
90         $attributes = array(
91             'class' => 'place' . $place . ' drop group' . $group
92         );
94         if ($options->readonly) {
95             $attributes['class'] .= ' readonly';
96         } else {
97             $attributes['tabindex'] = '0';
98         }
100         $feedbackimage = '';
101         if ($options->correctness) {
102             $response = $qa->get_last_qt_data();
103             $fieldname = $question->field($place);
104             if (array_key_exists($fieldname, $response)) {
105                 $fraction = (int) ($response[$fieldname] ==
106                         $question->get_right_choice_for($place));
107                 $feedbackimage = $this->feedback_image($fraction);
108             }
109         }
111         return html_writer::tag('span', $boxcontents, $attributes) . ' ' . $feedbackimage;
112     }
114     protected function drag_boxes($qa, $group, $choices, question_display_options $options) {
115         $boxes = '';
116         foreach ($choices as $key => $choice) {
117             // Bug 8632: long text entry causes bug in drag and drop field in IE.
118             $content = str_replace('-', '&#x2011;', $choice->text);
119             $content = str_replace(' ', '&#160;', $content);
121             $infinite = '';
122             if ($choice->infinite) {
123                 $infinite = ' infinite';
124             }
126             $boxes .= html_writer::tag('span', $content, array(
127                     'class' => 'draghome choice' . $key . ' group' .
128                             $choice->draggroup . $infinite)) . ' ';
129         }
131         return html_writer::nonempty_tag('div', $boxes,
132                 array('class' => 'draggrouphomes' . $choice->draggroup));
133     }
135     /**
136      * Actually, this question type abuses this method to always output the
137      * hidden fields it needs.
138      *
139      * @param question_attempt $qa the question attempt.
140      * @param bool $reallyclear whether we are really clearing the responses, or just outputting them.
141      * @return string HTML to output.
142      */
143     public function clear_wrong(question_attempt $qa, $reallyclear = true) {
144         $question = $qa->get_question();
145         $response = $qa->get_last_qt_data();
147         if (!empty($response) && $reallyclear) {
148             $cleanresponse = $question->clear_wrong_from_response($response);
149         } else {
150             $cleanresponse = $response;
151         }
153         $output = '';
154         foreach ($question->places as $place => $group) {
155             $fieldname = $question->field($place);
156             if (array_key_exists($fieldname, $response)) {
157                 $value = (string) $response[$fieldname];
158             } else {
159                 $value = '0';
160             }
161             if (array_key_exists($fieldname, $cleanresponse)) {
162                 $cleanvalue = (string) $cleanresponse[$fieldname];
163             } else {
164                 $cleanvalue = '0';
165             }
166             if ($cleanvalue === $value) {
167                 // Normal case: just one hidden input, to store the
168                 // current value and be the value submitted.
169                 $output .= html_writer::empty_tag('input', array(
170                         'type' => 'hidden',
171                         'id' => $this->box_id($qa, 'p' . $place),
172                         'class' => 'placeinput place' . $place . ' group' . $group,
173                         'name' => $qa->get_qt_field_name($fieldname),
174                         'value' => s($value)));
175             } else {
176                 // The case, which only happens when the question is read-only, where
177                 // we want to show the drag item in a given place (first hidden input),
178                 // but when submitted, we want it to go to a different place (second input).
179                 $output .= html_writer::empty_tag('input', array(
180                         'type' => 'hidden',
181                         'id' => $this->box_id($qa, 'p' . $place),
182                         'class' => 'placeinput place' . $place . ' group' . $group,
183                         'value' => s($value))) .
184                         html_writer::empty_tag('input', array(
185                         'type' => 'hidden',
186                         'name' => $qa->get_qt_field_name($fieldname),
187                         'value' => s($cleanvalue)));
188             }
189         }
190         return $output;
191     }