| Línea 39... |
Línea 39... |
| 39 |
*/
|
39 |
*/
|
| 40 |
define([
|
40 |
define([
|
| 41 |
'jquery',
|
41 |
'jquery',
|
| 42 |
'core/dragdrop',
|
42 |
'core/dragdrop',
|
| 43 |
'core/key_codes',
|
43 |
'core/key_codes',
|
| 44 |
'core_form/changechecker'
|
44 |
'core_form/changechecker',
|
| - |
|
45 |
'core_filters/events',
|
| 45 |
], function(
|
46 |
], function(
|
| 46 |
$,
|
47 |
$,
|
| 47 |
dragDrop,
|
48 |
dragDrop,
|
| 48 |
keys,
|
49 |
keys,
|
| 49 |
FormChangeChecker
|
50 |
FormChangeChecker,
|
| - |
|
51 |
filterEvent
|
| 50 |
) {
|
52 |
) {
|
| Línea 51... |
Línea 53... |
| 51 |
|
53 |
|
| Línea 52... |
Línea 54... |
| 52 |
"use strict";
|
54 |
"use strict";
|
| Línea 57... |
Línea 59... |
| 57 |
* @param {String} containerId id of the outer div for this question.
|
59 |
* @param {String} containerId id of the outer div for this question.
|
| 58 |
* @param {boolean} readOnly whether the question is being displayed read-only.
|
60 |
* @param {boolean} readOnly whether the question is being displayed read-only.
|
| 59 |
* @constructor
|
61 |
* @constructor
|
| 60 |
*/
|
62 |
*/
|
| 61 |
function DragDropToTextQuestion(containerId, readOnly) {
|
63 |
function DragDropToTextQuestion(containerId, readOnly) {
|
| - |
|
64 |
const thisQ = this;
|
| 62 |
this.containerId = containerId;
|
65 |
this.containerId = containerId;
|
| 63 |
this.questionAnswer = {};
|
66 |
this.questionAnswer = {};
|
| - |
|
67 |
this.questionDragDropWidthHeight = [];
|
| 64 |
if (readOnly) {
|
68 |
if (readOnly) {
|
| 65 |
this.getRoot().addClass('qtype_ddwtos-readonly');
|
69 |
this.getRoot().addClass('qtype_ddwtos-readonly');
|
| 66 |
}
|
70 |
}
|
| 67 |
this.resizeAllDragsAndDrops();
|
71 |
this.resizeAllDragsAndDrops();
|
| 68 |
this.cloneDrags();
|
72 |
this.cloneDrags();
|
| 69 |
this.positionDrags();
|
73 |
this.positionDrags();
|
| - |
|
74 |
// Wait for all dynamic content loaded by filter to be completed.
|
| - |
|
75 |
document.addEventListener(filterEvent.eventTypes.filterContentRenderingComplete, (elements) => {
|
| - |
|
76 |
elements.detail.nodes.forEach((element) => {
|
| - |
|
77 |
thisQ.changeAllDragsAndDropsToFilteredContent(element);
|
| - |
|
78 |
});
|
| - |
|
79 |
});
|
| 70 |
}
|
80 |
}
|
| Línea 71... |
Línea 81... |
| 71 |
|
81 |
|
| 72 |
/**
|
82 |
/**
|
| 73 |
* In each group, resize all the items to be the same size.
|
83 |
* In each group, resize all the items to be the same size.
|
| Línea 85... |
Línea 95... |
| 85 |
*
|
95 |
*
|
| 86 |
* @param {int} group the group number.
|
96 |
* @param {int} group the group number.
|
| 87 |
*/
|
97 |
*/
|
| 88 |
DragDropToTextQuestion.prototype.resizeAllDragsAndDropsInGroup = function(group) {
|
98 |
DragDropToTextQuestion.prototype.resizeAllDragsAndDropsInGroup = function(group) {
|
| 89 |
var thisQ = this,
|
99 |
var thisQ = this,
|
| 90 |
dragHomes = this.getRoot().find('.draggrouphomes' + group + ' span.draghome'),
|
100 |
dragDropItems = this.getRoot().find('span.group' + group),
|
| 91 |
maxWidth = 0,
|
101 |
maxWidth = 0,
|
| 92 |
maxHeight = 0;
|
102 |
maxHeight = 0;
|
| Línea 93... |
Línea 103... |
| 93 |
|
103 |
|
| 94 |
// Find the maximum size of any drag in this groups.
|
104 |
// Find the maximum size of any drag in this groups.
|
| 95 |
dragHomes.each(function(i, drag) {
|
105 |
dragDropItems.each(function(i, drag) {
|
| 96 |
maxWidth = Math.max(maxWidth, Math.ceil(drag.offsetWidth));
|
106 |
maxWidth = Math.max(maxWidth, Math.ceil(drag.offsetWidth));
|
| 97 |
maxHeight = Math.max(maxHeight, Math.ceil(0 + drag.offsetHeight));
|
107 |
maxHeight = Math.max(maxHeight, Math.ceil(0 + drag.offsetHeight));
|
| Línea 98... |
Línea 108... |
| 98 |
});
|
108 |
});
|
| 99 |
|
109 |
|
| 100 |
// The size we will want to set is a bit bigger than this.
|
110 |
// The size we will want to set is a bit bigger than this.
|
| 101 |
maxWidth += 8;
|
- |
|
| - |
|
111 |
maxWidth += 8;
|
| 102 |
maxHeight += 2;
|
112 |
maxHeight += 2;
|
| 103 |
|
113 |
thisQ.questionDragDropWidthHeight[group] = {maxWidth: maxWidth, maxHeight: maxHeight};
|
| 104 |
// Set each drag home to that size.
|
114 |
// Set each drag home to that size.
|
| 105 |
dragHomes.each(function(i, drag) {
|
115 |
dragDropItems.each(function(i, drag) {
|
| - |
|
116 |
thisQ.setElementSize(drag, maxWidth, maxHeight);
|
| Línea -... |
Línea 117... |
| - |
|
117 |
});
|
| - |
|
118 |
};
|
| - |
|
119 |
|
| - |
|
120 |
/**
|
| - |
|
121 |
* Change all the drags and drops related to the item that has been changed by filter to correct size and content.
|
| - |
|
122 |
*
|
| - |
|
123 |
* @param {object} filteredElement the element has been modified by filter.
|
| - |
|
124 |
*/
|
| - |
|
125 |
DragDropToTextQuestion.prototype.changeAllDragsAndDropsToFilteredContent = function(filteredElement) {
|
| - |
|
126 |
let currentFilteredItem = $(filteredElement);
|
| - |
|
127 |
const parentIsDD = currentFilteredItem.parent().closest('span').hasClass('placed') ||
|
| - |
|
128 |
currentFilteredItem.parent().closest('span').hasClass('draghome');
|
| - |
|
129 |
const isDD = currentFilteredItem.hasClass('placed') || currentFilteredItem.hasClass('draghome');
|
| - |
|
130 |
// The filtered element or parent element should a drag or drop item.
|
| - |
|
131 |
if (!parentIsDD && !isDD) {
|
| - |
|
132 |
return;
|
| - |
|
133 |
}
|
| 106 |
thisQ.setElementSize(drag, maxWidth, maxHeight);
|
134 |
if (parentIsDD) {
|
| - |
|
135 |
currentFilteredItem = currentFilteredItem.parent().closest('span');
|
| - |
|
136 |
}
|
| - |
|
137 |
const thisQ = this;
|
| - |
|
138 |
if (thisQ.getRoot().find(currentFilteredItem).length <= 0) {
|
| - |
|
139 |
// If the DD item doesn't belong to this question
|
| - |
|
140 |
// In case we have multiple questions in the same page.
|
| - |
|
141 |
return;
|
| - |
|
142 |
}
|
| - |
|
143 |
const group = thisQ.getGroup(currentFilteredItem),
|
| 107 |
});
|
144 |
choice = thisQ.getChoice(currentFilteredItem);
|
| - |
|
145 |
let listOfModifiedDragDrop = [];
|
| - |
|
146 |
// Get the list of drag and drop item within the same group and choice.
|
| - |
|
147 |
this.getRoot().find('.group' + group + '.choice' + choice).each(function(i, node) {
|
| - |
|
148 |
// Same modified item, skip it.
|
| - |
|
149 |
if ($(node).get(0) === currentFilteredItem.get(0)) {
|
| 108 |
|
150 |
return;
|
| - |
|
151 |
}
|
| - |
|
152 |
const originalClass = $(node).attr('class');
|
| - |
|
153 |
const originalStyle = $(node).attr('style');
|
| - |
|
154 |
// We want to keep all the handler and event for filtered item, so using clone is the only choice.
|
| - |
|
155 |
const filteredDragDropClone = currentFilteredItem.clone();
|
| - |
|
156 |
// Replace the class and style of the drag drop item we want to replace for the clone.
|
| - |
|
157 |
filteredDragDropClone.attr('class', originalClass);
|
| - |
|
158 |
filteredDragDropClone.attr('style', originalStyle);
|
| - |
|
159 |
// Insert into DOM.
|
| - |
|
160 |
$(node).before(filteredDragDropClone);
|
| - |
|
161 |
// Add the item has been replaced to a list so we can remove it later.
|
| - |
|
162 |
listOfModifiedDragDrop.push(node);
|
| - |
|
163 |
});
|
| 109 |
// Set each drop to that size.
|
164 |
|
| - |
|
165 |
listOfModifiedDragDrop.forEach(function(node) {
|
| - |
|
166 |
$(node).remove();
|
| - |
|
167 |
});
|
| - |
|
168 |
// Save the current height and width.
|
| - |
|
169 |
const currentHeight = currentFilteredItem.height();
|
| - |
|
170 |
const currentWidth = currentFilteredItem.width();
|
| - |
|
171 |
// Set to auto so we can get the real height and width of the filtered item.
|
| - |
|
172 |
currentFilteredItem.height('auto');
|
| - |
|
173 |
currentFilteredItem.width('auto');
|
| - |
|
174 |
// We need to set display block so we can get height and width.
|
| - |
|
175 |
// Some browser can't get the offsetWidth/Height if they are an inline element like span tag.
|
| - |
|
176 |
if (!filteredElement.offsetWidth || !filteredElement.offsetHeight) {
|
| - |
|
177 |
filteredElement.classList.add('d-block');
|
| - |
|
178 |
}
|
| - |
|
179 |
if (thisQ.questionDragDropWidthHeight[group].maxWidth < Math.ceil(filteredElement.offsetWidth) ||
|
| - |
|
180 |
thisQ.questionDragDropWidthHeight[group].maxHeight < Math.ceil(0 + filteredElement.offsetHeight)) {
|
| - |
|
181 |
// Remove the d-block class before calculation.
|
| - |
|
182 |
filteredElement.classList.remove('d-block');
|
| - |
|
183 |
// Now resize all the items in the same group if we have new maximum width or height.
|
| - |
|
184 |
thisQ.resizeAllDragsAndDropsInGroup(group);
|
| - |
|
185 |
} else {
|
| - |
|
186 |
// Return the original height and width in case the real height and width is not the maximum.
|
| - |
|
187 |
currentFilteredItem.height(currentHeight);
|
| - |
|
188 |
currentFilteredItem.width(currentWidth);
|
| 110 |
this.getRoot().find('span.drop.group' + group).each(function(i, drop) {
|
189 |
}
|
| Línea 111... |
Línea 190... |
| 111 |
thisQ.setElementSize(drop, maxWidth, maxHeight);
|
190 |
// Remove the d-block class after resize.
|
| 112 |
});
|
191 |
filteredElement.classList.remove('d-block');
|
| 113 |
};
|
192 |
};
|