From 8b8fd28e1758977ce8558028511d75929bb54412 Mon Sep 17 00:00:00 2001 From: Angel Fernando Quiroz Campos Date: Mon, 30 Nov 2015 17:26:00 -0500 Subject: [PATCH] Allow to submit answers for hotspots - refs #7705 --- main/exercice/exercise_submit.php | 1 + main/exercice/hotspot_actionscript.as.php | 65 ++++++--- main/inc/lib/exercise.lib.php | 170 ++++------------------ main/plugin/hotspot2/js/hotspot_user.js | 136 +++++++++++++++++ 4 files changed, 209 insertions(+), 163 deletions(-) create mode 100755 main/plugin/hotspot2/js/hotspot_user.js diff --git a/main/exercice/exercise_submit.php b/main/exercice/exercise_submit.php index 7da3dc9e23..316b6f18d3 100755 --- a/main/exercice/exercise_submit.php +++ b/main/exercice/exercise_submit.php @@ -60,6 +60,7 @@ $htmlHeadXtra[] = api_get_css(api_get_path(WEB_LIBRARY_PATH).'javascript/epicloc $htmlHeadXtra[] = api_get_js('epiclock/javascript/jquery.dateformat.min.js'); $htmlHeadXtra[] = api_get_js('epiclock/javascript/jquery.epiclock.min.js'); $htmlHeadXtra[] = api_get_js('epiclock/renderers/minute/epiclock.minute.js'); +$htmlHeadXtra[] = ''; $template = new Template(); diff --git a/main/exercice/hotspot_actionscript.as.php b/main/exercice/hotspot_actionscript.as.php index 30751fdd99..51e68308cb 100755 --- a/main/exercice/hotspot_actionscript.as.php +++ b/main/exercice/hotspot_actionscript.as.php @@ -24,11 +24,6 @@ $pictureSize = getimagesize($picturePath.'/'.$objQuestion->selectPicture()); $pictureWidth = $pictureSize[0]; $pictureHeight = $pictureSize[1]; -$courseLang = $_course['language']; -$courseCode = $_course['sysCode']; -$coursePath = $_course['path']; - - $course_id = api_get_course_int_id(); // Query db for answers @@ -40,39 +35,64 @@ if ($answer_type==HOT_SPOT_DELINEATION) { WHERE c_id = $course_id AND question_id = ".intval($questionId)." ORDER BY id"; } $result = Database::query($sql); -// Init -$output = "hotspot_lang=$courseLang&hotspot_image=$pictureName&hotspot_image_width=$pictureWidth&hotspot_image_height=$pictureHeight&courseCode=$coursePath"; + +$data = []; +$data['lang'] = [ + 'Square' => get_lang('square'), + 'Circle' => get_lang('circle'), + 'Poly' => get_lang('poly'), + 'Status1' => get_lang('status1'), + 'Status2_poly' => get_lang('status2_poly'), + 'Status2_other' => get_lang('status2_other'), + 'Status3' => get_lang('status3'), + 'ShowUserPoints' => get_lang('showUserPoints'), + 'LabelPolyMenu' => get_lang('labelPolyMenu'), + 'Triesleft' => get_lang('triesleft'), + 'ExeFinished' => get_lang('exeFinished'), + 'NextAnswer' => get_lang('nextAnswer'), + 'Delineation' => get_lang('delineation'), + 'LabelDelineationMenu' => get_lang('labelDelineationMenu'), + 'Oar' => get_lang('oar') +]; +$data['image'] = $objQuestion->selectPicturePath(); +$data['image_width'] = $pictureWidth; +$data['image_height'] = $pictureHeight; +$data['courseCode'] = $_course['path']; +$data['hotspots'] = []; + $i = 0; $nmbrTries = 0; while ($hotspot = Database::fetch_assoc($result)) { - $output .= "&hotspot_".$hotspot['id']."=true"; - $output .= "&hotspot_".$hotspot['id']."_answer=".str_replace('&','{amp}',$hotspot['answer']); + $hotSpot = []; + $hotSpot['id'] = $hotspot['id']; + $hotSpot['answer'] = $hotspot['answer']; + // Square or rectancle if ($hotspot['hotspot_type'] == 'square' ) { - $output .= "&hotspot_".$hotspot['id']."_type=square"; + $hotSpot['type'] = 'square'; } // Circle or ovale if ($hotspot['hotspot_type'] == 'circle') { - $output .= "&hotspot_".$hotspot['id']."_type=circle"; + $hotSpot['type'] = 'circle'; } // Polygon if ($hotspot['hotspot_type'] == 'poly') { - $output .= "&hotspot_".$hotspot['id']."_type=poly"; + $hotSpot['type'] = 'poly'; } // Delineation if ($hotspot['hotspot_type'] == 'delineation') { - $output .= "&hotspot_".$hotspot['id']."_type=delineation"; + $hotSpot['type'] = 'delineation'; } // No error if ($hotspot['hotspot_type'] == 'noerror') { - $output .= "&hotspot_".$hotspot['id']."_type=noerror"; + $hotSpot['type'] = 'noerror'; } // This is a good answer, count + 1 for nmbr of clicks @@ -80,14 +100,19 @@ while ($hotspot = Database::fetch_assoc($result)) { $nmbrTries++; } - $output .= "&hotspot_".$hotspot['id']."_coord=".$hotspot['hotspot_coordinates'].""; + unset($hotSpot['type']); + //$hotSpot['coord'] = $hotspot['hotspot_coordinates']; $i++; + + $data['hotspots'][] = $hotSpot; } // Generate empty $i++; -for ($i; $i <= 12; $i++) { - $output .= "&hotspot_".$i."=false"; -} -// Output -echo $output."&nmbrTries=".$nmbrTries."&done=done"; + +$data['nmbrTries'] = $nmbrTries; +$data['done'] = 'done'; + +header('Content-Type: application/json'); + +echo json_encode($data); diff --git a/main/inc/lib/exercise.lib.php b/main/inc/lib/exercise.lib.php index e860fbf23c..637450e010 100644 --- a/main/inc/lib/exercise.lib.php +++ b/main/inc/lib/exercise.lib.php @@ -1156,153 +1156,37 @@ HTML; echo '
' . $current_item . '. ' . $questionName . '
'; } //@todo I need to the get the feedback type - echo ''; - echo ' - - '; + echo << +
+ $questionDescription +
+HOTSPOT; } $canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1'); - $s .= ' - - - - - '; - $s .= '
'; - echo $s; - echo '
'; - echo $questionDescription; - echo '
- -
- - ' . $answer_list . '
-
'; + $s .= << +
+ + +
+ $answer_list +
+HOTSPOT; + echo << + +HOTSPOT; } return $nbrAnswers; } diff --git a/main/plugin/hotspot2/js/hotspot_user.js b/main/plugin/hotspot2/js/hotspot_user.js new file mode 100755 index 0000000000..3d474635d0 --- /dev/null +++ b/main/plugin/hotspot2/js/hotspot_user.js @@ -0,0 +1,136 @@ +var HotSpotUser = (function () { + var config, lang, canvas, image, hotspots; + + config = {questionId: 0, selector: ''}; + + var canvas = (function () { + var points = [], + messageText = document.createElement('div'); + + return { + el: document.createElementNS('http://www.w3.org/2000/svg', 'svg'), + render: function () { + var self = this; + + var imageSvg = document.createElementNS('http://www.w3.org/2000/svg', 'image'); + imageSvg.setAttributeNS('http://www.w3.org/1999/xlink', 'href', image.src); + imageSvg.setAttribute('width', image.width); + imageSvg.setAttribute('height', image.height); + + canvas.el.setAttribute('version', '1.1'); + canvas.el.setAttribute('viewBox', '0 0 ' + image.width + ' ' + image.height); + canvas.el.appendChild(imageSvg); + canvas.el.addEventListener('dragstart', function (e) { + e.preventDefault(); + }, false); + canvas.el.addEventListener('click', function (e) { + e.preventDefault(); + + if (points.length >= hotspots.length) { + return; + } + + var point = getPointOnImage(e.clientX, e.clientY); + + self.addPoint(point.x, point.y); + }, false); + + $(messageText).text(lang.NextAnswer + ' ' + hotspots[0].answer); + + $(config.selector).prepend(messageText); + + return this; + }, + addPoint: function (x, y) { + points.push([x, y]); + + var pointSVG = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); + pointSVG.setAttribute('cx', x); + pointSVG.setAttribute('cy', y); + pointSVG.setAttribute('r', 15); + pointSVG.setAttribute('fill', '#00677C'); + + var textSVG = document.createElementNS('http://www.w3.org/2000/svg', 'text'); + textSVG.setAttribute('x', x); + textSVG.setAttribute('y', y); + textSVG.setAttribute('dy', 5); + textSVG.setAttribute('font-family', 'sans-serif'); + textSVG.setAttribute('text-anchor', 'middle'); + textSVG.setAttribute('fill', 'white'); + textSVG.textContent = points.length; + + var txtHotSpot = $('').attr({ + type: 'hidden', + name: 'hotspot[' + config.questionId + '][' + hotspots[points.length - 1].id + ']' + }).val([x, y].join(';')); + + var txtChoice = $('').attr({ + type: 'hidden', + name: 'choice[' + config.questionId + '][' + hotspots[points.length - 1].id + ']' + }).val(1); + + $(canvas.el).append(pointSVG); + $(canvas.el).append(textSVG); + $(config.selector).append(txtHotSpot); + $(config.selector).append(txtChoice); + + if (points.length === hotspots.length) { + $(messageText).text(lang.ExeFinished); + + return; + } + + $(messageText).text(lang.NextAnswer + ' ' + hotspots[points.length].answer); + } + }; + })(); + + var startQuestion = function (hotSpotQuestionInfo) { + image = new Image(); + image.onload = function () { + $(config.selector) + .css('width', this.width + 'px') + .append(canvas.render().el); + }; + image.src = hotSpotQuestionInfo.image; + + hotspots = hotSpotQuestionInfo.hotspots; + + lang = hotSpotQuestionInfo.lang; + }; + + var getPointOnImage = function (x, y) { + var pointerPosition = { + left: x + window.scrollX, + top: y + window.scrollY + }, + canvasOffset = { + x: canvas.el.getBoundingClientRect().x + window.scrollX, + y: canvas.el.getBoundingClientRect().y + window.scrollY + }; + + return { + x: Math.round(pointerPosition.left - canvasOffset.x), + y: Math.round(pointerPosition.top - canvasOffset.y) + }; + }; + + return { + init: function (settings) { + config = $.extend({ + questionId: 0, + selector: '' + }, settings); + + if (!config.questionId || !config.selector) { + return; + } + + var xhrHotSpotQuestion = $.getJSON('/main/exercice/hotspot_actionscript.as.php', { + modifyAnswers: parseInt(config.questionId) + }); + + $.when(xhrHotSpotQuestion).done(startQuestion); + } + }; +})();