Skip to content

Commit

Permalink
Changes to preview page
Browse files Browse the repository at this point in the history
  • Loading branch information
AnupamaSarjoshi committed Sep 10, 2024
1 parent 568a1d6 commit 9cc1530
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 82 deletions.
2 changes: 1 addition & 1 deletion amd/build/Line.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion amd/build/Line.min.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion amd/build/question.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion amd/build/question.min.js.map

Large diffs are not rendered by default.

22 changes: 17 additions & 5 deletions amd/src/Line.js
Original file line number Diff line number Diff line change
Expand Up @@ -411,17 +411,17 @@ define(function() {

/**
* Move the g element between the dropzones and dragHomes.
* @param {SVGElement} svgDrags Svg element containing the drags.
* @param {SVGElement} svgDragsHome Svg element containing the drags.
* @param {SVGElement} svgDropZones Svg element containing the dropZone.
* @param {SVGElement} selectedElement The element selected for dragging.
* @param {int} dropX
* @param {int} dropY
*/
Line.prototype.addToDropZone = function(svgDrags, svgDropZones, selectedElement, dropX, dropY) {
Line.prototype.addToDropZone = function(svgDragsHome, svgDropZones, selectedElement, dropX, dropY) {
var maxY = 0;
var dropzoneNo = selectedElement.getAttribute('data-dropzone-no');

if (this.isInsideSVG(svgDrags, dropX, dropY)) {
var classattributes = '';
if (this.isInsideSVG(svgDragsHome, dropX, dropY)) {
// Append the element to the second SVG
// Get the height of the dropZone SVG.
maxY = svgDropZones.height.baseVal.value;
Expand All @@ -437,9 +437,15 @@ define(function() {
this.y1 = maxY - (2 * this.startRadius);
this.centre2.y = maxY - (2 * this.endRadius);
this.y2 = maxY - (2 * this.endRadius);

// Update the class attributes to 'placed' if the line is in the svgDropZone.
classattributes = selectedElement.getAttribute('class');
classattributes = classattributes.replace('inactive', 'placed');
selectedElement.setAttribute('class', classattributes);

} else if (this.isInsideSVG(svgDropZones, dropX, dropY)) {
// Append the element to the first SVG (to ensure it stays in the same SVG if dropped there)
svgDrags.appendChild(selectedElement);
svgDragsHome.appendChild(selectedElement);

// We want to drop the lines from the top, depending on the line number.
// Calculate the position of line drop.
Expand All @@ -449,7 +455,13 @@ define(function() {
this.centre2.x = 200;
this.centre2.y = this.endRadius + (dropzoneNo * 50);
this.y2 = this.endRadius + (dropzoneNo * 50);

// Update the class attributes to 'inactive' if the line is in the svg draghome.
classattributes = selectedElement.getAttribute('class');
classattributes = classattributes.replace('placed', 'inactive');
selectedElement.setAttribute('class', classattributes);
}
return '';
};

/**
Expand Down
152 changes: 108 additions & 44 deletions amd/src/question.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,30 +82,74 @@ define([
}
};

/**
* Parse the coordinates from a particular string.
* @param {String} coordinates The coordinates to be parsed. The values are in the format: x1,y1 x2,y2.
* Except for infinite line type where it's in the format x1,y1 x2,y2, x3,y3, x4,y4.
* Here, x1,y1 and x4,y4 are the two very end points of the infinite line and
* x2,y2 and x3,y3 are the pints with the handles.
* @param {String} lineType The type of the line.
*/
DrawlinesQuestion.prototype.parseCoordinates = function(coordinates, lineType) {
var bits = coordinates.split(' ');
if (lineType === 'lineinfinite') {
// Remove the first and last coordinates.
bits = bits.slice(1, -1);
}
if (bits.length !== 2) {
throw new Error(coordinates + ' is not a valid point');
}
return bits;
};

/**
* Draws the svg lines of any drop zones.
* @param {Object[]} questionLines
*/
DrawlinesQuestion.prototype.drawSVGLines = function(questionLines) {
var bgImage = document.querySelector('img.dropbackground');
var bgImage = document.querySelector('img.dropbackground'),
height, startcoordinates, endcoordinates, draginitialcoords;

var drags = document.querySelector('.draghomes');
drags.innerHTML =
'<svg xmlns="http://www.w3.org/2000/svg" class="drags" ' +
'id= "que-dlines-svg-drags" ' +
'<svg xmlns="http://www.w3.org/2000/svg" class="dragshome" ' +
'id= "que-dlines-svg-dragshome" ' +
'width="' + bgImage.width + '" ' +
'height="' + questionLines.length * 50 + '"' +
'></svg>';

var dragsSvg = document.getElementById('que-dlines-svg-drags');
var initialHeight = 25;
var draghomeSvg = document.getElementById('que-dlines-svg-dragshome');
var dropzoneSvg = document.getElementById('que-dlines-svg');
var initialHeight = 25,
dragSVG, bits;
for (let line = 0; line < questionLines.length; line++) {
var height = initialHeight + line * 50;
var startcoordinates = '50,' + height + ';10';
var endcoordinates = '200,' + height + ';10';
height = initialHeight + line * 50;
startcoordinates = '50,' + height + ';10';
endcoordinates = '200,' + height + ';10';


// Check if the lines are to be set with initial coordinates.
// The visibleDropZones array holds the response in the format x1,y1 x2,y2;placed - if the line is in the svgdropzone
// else x1,y1 x2,y2;inactive - if the line is in the svg draghomes.
dragSVG = '';
draginitialcoords = this.visibleDropZones['c' + line];
if (draginitialcoords !== undefined && draginitialcoords !== '') {
bits = draginitialcoords.split(';');
dragSVG = bits[1];
var coords = this.parseCoordinates(bits[0], questionLines[line].type);
if (dragSVG === 'placed') {
startcoordinates = coords[0] + ';10';
endcoordinates = coords[1] + ';10';
}
}

this.lines[line] = Lines.make([startcoordinates, endcoordinates],
[questionLines[line].labelstart, questionLines[line].labelend], questionLines[line].type);
this.addToSvg(line, dragsSvg);
if (dragSVG === 'placed') {
this.addToSvg(line, dropzoneSvg);
} else {
this.addToSvg(line, draghomeSvg);
}
}
};

Expand Down Expand Up @@ -275,7 +319,7 @@ define([
var imageCoords = [],
val = $(inputNode).val();
if (val !== '') {
var coordsStrings = val.split(';');
var coordsStrings = val.split(' ');
for (var i = 0; i < coordsStrings.length; i++) {
imageCoords[i] = Lines.Point.parse(coordsStrings[i]);
}
Expand Down Expand Up @@ -448,8 +492,12 @@ define([
if (!this.lineSVGs[lineNumber]) {
return;
}
this.lineSVGs[lineNumber].setAttribute('class', 'dropzone');
this.lineSVGs[lineNumber].setAttribute('data-dropzone-no', lineNumber);
if (svg.getAttribute('class') === 'dropzones') {
this.lineSVGs[lineNumber].setAttribute('class', 'dropzone choice' + lineNumber + ' placed');
} else {
this.lineSVGs[lineNumber].setAttribute('class', 'dropzone choice' + lineNumber + ' inactive');
}
};

/**
Expand Down Expand Up @@ -485,6 +533,7 @@ define([
lastX = pageX;
lastY = pageY;
movingDropZone.updateSvgEl(dropzoneNo);
movingDropZone.saveCoordsForChoice(dropzoneNo);
}, function() {
document.body.removeChild(dragProxy);
});
Expand All @@ -505,12 +554,15 @@ define([
lastX = info.x,
lastY = info.y,
dragProxy = this.makeDragProxy(info.x, info.y),
svgDrags = document.querySelector('svg.drags'),
svgDragsHome = document.querySelector('svg.dragshome'),
svgDropZones = document.querySelector('svg.dropzones'),
maxX = svgDrags.width.baseVal.value,
maxY = svgDrags.height.baseVal.value,
maxX = svgDragsHome.width.baseVal.value,
maxY = svgDragsHome.height.baseVal.value,
whichSVG = "",
bgImage = document.querySelector('img.dropbackground');
bgImage = document.querySelector('img.dropbackground'),
isMoveFromDragsToDropzones,
isMoveFromDropzonesToDrags,
svgClass = '';

var selectedElement = this.lineSVGs[dropzoneNo];
const dropX = e.clientX;
Expand All @@ -521,23 +573,23 @@ define([
// Check if the drags need to be moved from one svg to another.
// If true, the drag is moved from draghomes SVG to dropZone SVG.
var closeTo = selectedElement.closest('svg');
var svgClass = closeTo.getAttribute('class');
svgClass = closeTo.getAttribute('class');

// Moving the drags between the SVG's.
var isMoveFromDragsToDropzones = (svgClass === "drags") &&
isMoveFromDragsToDropzones = (svgClass === "dragshome") &&
(movingDrag.lines[dropzoneNo].centre1.y === 10);
var isMoveFromDropzonesToDrags = (svgClass === 'dropzones') &&
isMoveFromDropzonesToDrags = (svgClass === 'dropzones') &&
(movingDrag.lines[dropzoneNo].centre1.y > (bgImage.height - 20));
if (isMoveFromDragsToDropzones || isMoveFromDropzonesToDrags) {
movingDrag.lines[dropzoneNo].addToDropZone(svgDrags, svgDropZones, selectedElement,
movingDrag.lines[dropzoneNo].addToDropZone(svgDragsHome, svgDropZones, selectedElement,
dropX, dropY);
}

// Drag the lines within the SVG
closeTo = selectedElement.closest('svg');
if (closeTo.getAttribute('class') === 'drags') {
maxX = svgDrags.width.baseVal.value;
maxY = svgDrags.height.baseVal.value;
if (closeTo.getAttribute('class') === 'dragshome') {
maxX = svgDragsHome.width.baseVal.value;
maxY = svgDragsHome.height.baseVal.value;
whichSVG = "DragsSVG";
} else {
maxX = svgDropZones.width.baseVal.value;
Expand All @@ -551,6 +603,7 @@ define([
lastY = pageY;

movingDrag.updateSvgEl(dropzoneNo);
movingDrag.saveCoordsForChoice(dropzoneNo);
}, function() {
document.body.removeChild(dragProxy);
});
Expand Down Expand Up @@ -578,34 +631,44 @@ define([
/**
* Save the coordinates for a dropped item in the form field.
* @param {Number} choiceNo which copy of the choice this was.
*/
**/
DrawlinesQuestion.prototype.saveCoordsForChoice = function(choiceNo) {
let imageCoords = [];
var items = this.getRoot().find('div.droparea span.marker.choice' + choiceNo),
thiQ = this,
bgRatio = this.bgRatio();

var items = this.getRoot().find('svg g.choice' + choiceNo),
gEleClassAttributes = '';
// thiQ = this,
// bgRatio = this.bgRatio();
if (items.length) {
items.each(function() {
var drag = $(this);
if (!drag.hasClass('beingdragged') && !drag.data('imageCoords')) {
if (drag.data('scaleRatio') !== bgRatio) {
// The scale ratio for the draggable item was changed. We need to update that.
drag.data('pagex', drag.offset().left).data('pagey', drag.offset().top);
}
var dragXY = new Lines.Point(drag.data('pagex'), drag.data('pagey'));
if (thiQ.coordsInBgImg(dragXY)) {
var bgImgXY = thiQ.convertToBgImgXY(dragXY);
bgImgXY = new Lines.Point(bgImgXY.x / bgRatio, bgImgXY.y / bgRatio);
imageCoords[imageCoords.length] = bgImgXY;
}
} else if (drag.data('imageCoords')) {
imageCoords[imageCoords.length] = drag.data('imageCoords');
}
imageCoords = drag.children('polyline').attr('points');
gEleClassAttributes = drag.attr('class');
// if (drag.data('scaleRatio') !== bgRatio) {
// // The scale ratio for the draggable item was changed. We need to update that.
// drag.data('pagex', drag.offset().left).data('pagey', drag.offset().top);
// }
// var dragXY = new Lines.Point(drag.data('pagex'), drag.data('pagey'));
// window.console.log("dragXY:" + dragXY);
//
// window.console.log("thiQ:" + thiQ);
// if (thiQ.coordsInBgImg(dragXY)) {
// var bgImgXY = thiQ.convertToBgImgXY(dragXY);
// bgImgXY = new Lines.Point(bgImgXY.x / bgRatio, bgImgXY.y / bgRatio);
// imageCoords[imageCoords.length] = bgImgXY;
// window.console.log("bgImgXY:" + bgImgXY);
// }
// } else if (drag.data('imageCoords')) {
// imageCoords[imageCoords.length] = drag.data('imageCoords');
// }

});
}

this.getRoot().find('input.choice' + choiceNo).val(imageCoords.join(';'));
// this.getRoot().find('input.choice' + choiceNo).val(imageCoords);
if (gEleClassAttributes !== '' && gEleClassAttributes.includes('placed')) {
this.getRoot().find('input.choice' + choiceNo).val(imageCoords + ';' + 'placed');
} else if (gEleClassAttributes !== '' && gEleClassAttributes.includes('inactive')) {
this.getRoot().find('input.choice' + choiceNo).val(imageCoords + ';' + 'inactive');
}
if (this.isQuestionInteracted()) {
// The user has interacted with the draggable items. We need to mark the form as dirty.
questionManager.handleFormDirty();
Expand Down Expand Up @@ -987,7 +1050,7 @@ define([
// We now have all images. Carry on, but only after giving the layout a chance to settle down.
this.allImagesLoaded = true;
this.cloneDrags();
this.repositionDrags();
//this.repositionDrags();
this.drawDropzone();
};

Expand Down Expand Up @@ -1145,6 +1208,7 @@ define([
dropzoneElement = event.target.closest('g');
dropzoneNo = dropzoneElement.dataset.dropzoneNo;
question.handleDragMove(event, dropzoneNo);
question.saveCoordsForChoice(dropzoneNo);
}
},

Expand Down
47 changes: 29 additions & 18 deletions question.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ public function check_file_access($qa, $options, $component, $filearea, $args, $

#[\Override]
public function get_expected_data() {
$expecteddata = [];
foreach($this->choices as $key =>$choice) {
$expecteddata[$key]= PARAM_RAW;
$expecteddata =[];
foreach ($this->lines as $line) {
$expecteddata[$this->choice($line->number - 1)] = PARAM_NOTAGS;
}
return $expecteddata;
}
Expand Down Expand Up @@ -159,12 +159,12 @@ public function total_number_of_items_dragged(array $response): int {

#[\Override]
public function is_complete_response(array $response): bool {
foreach ($this->choices as $choiceno => $notused) {
if (!isset($response[$choiceno])) {
return false;
foreach ($this->lines as $choiceno => $line) {
if (isset($response[$this->choice($choiceno)])) {
return true;
}
}
return true;
return false;
}

#[\Override]
Expand Down Expand Up @@ -390,22 +390,33 @@ public function get_correct_response() {
public function summarise_response(array $response): ?string {
$responsewords = [];
$answers = [];
foreach ($this->lines as $line) {
$linestartresponse = $line->labelstart . '' . $line->zonestart;
$lineendresponse = $line->labelend . '' . $line->zoneend;
if (array_key_exists('c' . $line->number, $response)) {
$answers[] = $line->labelstart . '' . $line->zonestart;
}
if (array_key_exists('c' . $line->number, $response)) {
$answers[] = $line->labelend . '' . $line->zoneend;
}
if (count($answers) > 0) {
$responsewords[] = "Line $line->number " . implode(', ', $answers);
foreach ($this->lines as $key => $line) {
if (array_key_exists($this->choice($key), $response) && $response[$this->choice($key)] != '') {
$answer = $this->parse_coordinates($response[$this->choice($key)]);
if ($answer['inplace'] === 'placed') {
$answers[] = 'Line ' . $line->number . ': ' . $answer['coords'];
}
}
}
if (count($answers) > 0) {
$responsewords[] = implode(', ', $answers);
}
return implode('; ', $responsewords);
}

/**
* Return the coordinates from the response.
* @param string $responsechoice the response coordinates.
* @return array $coordinates The array of parsed coordinates.
*/
public function parse_coordinates(string $responsechoice): array {
$coordinates = [];
$bits = explode(';', $responsechoice);
$coordinates['coords'] = $bits[0];
$coordinates['inplace'] = $bits[1];
return $coordinates;
}

#[\Override]
public function get_random_guess_score() {
return null;
Expand Down
Loading

0 comments on commit 9cc1530

Please sign in to comment.