MDL-20636 Finish making ddwtos work, mostly. Also various other JS fixes.
[moodle.git] / question / type / ddwtos / renderer.php
CommitLineData
c3e6bd18
TH
1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18
19/**
20 * Drag-and-drop words into sentences question renderer class.
21 *
22 * @package qtype_ddwtos
23 * @copyright 2010 The Open University
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
26
27require_once($CFG->dirroot . '/question/type/gapselect/rendererbase.php');
28
29
30/**
31 * Generates the output for drag-and-drop words into sentences questions.
32 *
33 * @copyright 2010 The Open University
34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
35 */
36class qtype_ddwtos_renderer extends qtype_elements_embedded_in_question_text_renderer {
37
38 protected function qtext_classname(){
39 return 'qtext ddwtos_questionid_for_javascript';
40 }
41
42 protected function post_qtext_elements(question_attempt $qa, question_display_options $options){
43 $result = '';
44 $question = $qa->get_question();
45 $dragboxs = '';
46 foreach ($question->choices as $group => $choices) {
47 $dragboxs .= $this->drag_boxes($qa, $group,
48 $question->get_ordered_choices($group), $options);
49 }
50 $result .= html_writer::tag('div', $dragboxs,
51 array('class' => 'answercontainer'));
52 // We abuse the clear_wrong method to output the hidden form fields we
53 // want irrespective of whether we are actually clearing the wrong
54 // bits of the response.
55 if (!$options->clearwrong) {
56 $result .= $this->clear_wrong($qa, false);
57 }
58 return $result;
59 }
60
61 /**
62 * Modify the contents of a drag/drop box to fix some IE-related problem.
63 * Unfortunately I don't have more details than that.
64 * @param string $string the box contents.
65 * @return string the box contents modified.
66 */
67 protected function dodgy_ie_fix($string) {
68 return '<sub>&#160;</sub>' . $string . '<sup>&#160;</sup>';
69 }
70
71 protected function embedded_element(question_attempt $qa, $place, question_display_options $options) {
72 $question = $qa->get_question();
73 $group = $question->places[$place];
74 $boxcontents = $this->dodgy_ie_fix('&#160;');
75
76 $value = $qa->get_last_qt_var($question->field($place));
77
78 $attributes = array(
79 'id' => $this->box_id($qa, 'p' . $place, $group),
80 'class' => 'slot group' . $group
81 );
82
83 if ($options->readonly) {
84 $attributes['class'] .= ' readonly';
85 } else {
86 $attributes['tabindex'] = '0';
87 }
88
89 $feedbackimage = '';
90 if ($options->correctness) {
91 $response = $qa->get_last_qt_data();
92 $fieldname = $question->field($place);
93 if (array_key_exists($fieldname, $response)) {
94 $fraction = (int) ($response[$fieldname] == $question->get_right_choice_for($place));
95 $attributes['class'] .= ' ' . $this->feedback_class($fraction);
96 $feedbackimage = $this->feedback_image($fraction);
97 }
98 }
99
100 return html_writer::tag('span', $boxcontents, $attributes) . ' ' . $feedbackimage;
101 }
102
103 protected function drag_boxes($qa, $group, $choices, question_display_options $options) {
104 $readonly = '';
105 if ($options->readonly) {
106 $readonly = ' readonly';
107 }
108
109 $boxes = '';
110 foreach ($choices as $key => $choice) {
111 //Bug 8632 - long text entry causes bug in drag and drop field in IE
112 $content = str_replace('-', '&#x2011;', $choice->text);
113 $content = $this->dodgy_ie_fix(str_replace(' ', '&#160;', $content));
114
115 $infinite = '';
116 if ($choice->isinfinite) {
117 $infinite = ' infinite';
118 }
119
120 $boxes .= html_writer::tag('span', $content, array(
121 'id' => $this->box_id($qa, $key, $choice->draggroup),
122 'class' => 'player group' . $choice->draggroup . $infinite . $readonly)) . ' ';
123 }
124
125 return html_writer::nonempty_tag('div', $boxes, array('class' => 'answertext'));
126 }
127
128
129 public function head_code(question_attempt $qa) {
0fafed0f
TH
130 $this->page->requires->yui2_lib('dom');
131 $this->page->requires->yui2_lib('event');
132 $this->page->requires->yui2_lib('dragdrop');
c3e6bd18
TH
133 return parent::head_code($qa);
134 }
135
136 /**
137 * Actually, this question type abuses this method to always ouptut the
138 * hidden fields it needs.
139 */
140 public function clear_wrong(question_attempt $qa, $reallyclear = true) {
141 $question = $qa->get_question();
142 $response = $qa->get_last_qt_data();
143
144 if (!empty($response) && $reallyclear) {
145 $cleanresponse = $question->clear_wrong_from_response($response);
146 } else {
147 $cleanresponse = $response;
148 }
149
150 $output = '';
151 foreach ($question->places as $place => $group) {
152 $fieldname = $question->field($place);
153 if (array_key_exists($fieldname, $response)) {
154 $value = $response[$fieldname];
155 } else {
156 $value = '0';
157 }
158 if (array_key_exists($fieldname, $cleanresponse)) {
159 $cleanvalue = $cleanresponse[$fieldname];
160 } else {
161 $cleanvalue = '0';
162 }
163 if ($cleanvalue != $value) {
164 $output .= html_writer::empty_tag('input', array(
165 'type' => 'hidden',
166 'id' => $this->box_id($qa, 'p' . $place, $group) . '_hidden',
167 'value' => s($value))) .
168 html_writer::empty_tag('input', array(
169 'type' => 'hidden',
170 'name' => $qa->get_qt_field_name($fieldname),
171 'value' => s($cleanvalue)));
172 } else {
173 $output .= html_writer::empty_tag('input', array(
174 'type' => 'hidden',
175 'id' => $this->box_id($qa, 'p' . $place, $group) . '_hidden',
176 'name' => $qa->get_qt_field_name($fieldname),
177 'value' => s($value)));
178 }
179 }
180 return $output;
181 }
182
183}