Allow to submit answers for hotspots - refs #7705

1.10.x
Angel Fernando Quiroz Campos 10 years ago
parent 0e8ee3c56b
commit 8b8fd28e17
  1. 1
      main/exercice/exercise_submit.php
  2. 65
      main/exercice/hotspot_actionscript.as.php
  3. 170
      main/inc/lib/exercise.lib.php
  4. 136
      main/plugin/hotspot2/js/hotspot_user.js

@ -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[] = '<script src="../plugin/hotspot2/js/hotspot_user.js"></script>';
$template = new Template();

@ -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);

@ -1156,153 +1156,37 @@ HTML;
echo '<div class="question_title">' . $current_item . '. ' . $questionName . '</div>';
}
//@todo I need to the get the feedback type
echo '<input type="hidden" name="hidden_hotspot_id" value="' . $questionId . '" />';
echo '<table class="exercise_questions" >
<tr>
<td valign="top" colspan="2">';
echo $questionDescription;
echo '</td></tr>';
echo <<<HOTSPOT
<input type="hidden" name="hidden_hotspot_id" value="$questionId" />
<div class="exercise_questions">
$questionDescription
<div class="row">
HOTSPOT;
}
$canClick = isset($_GET['editQuestion']) ? '0' : (isset($_GET['modifyAnswers']) ? '0' : '1');
$s .= '<script type="text/javascript" src="../plugin/hotspot/JavaScriptFlashGateway.js"></script>
<script src="../plugin/hotspot/hotspot.js" type="text/javascript" ></script>
<script type="text/javascript">
<!--
// Globals
// Major version of Flash required
var requiredMajorVersion = 7;
// Minor version of Flash required
var requiredMinorVersion = 0;
// Minor version of Flash required
var requiredRevision = 0;
// the version of javascript supported
var jsVersion = 1.0;
// -->
</script>
<script language="VBScript" type="text/vbscript">
<!-- // Visual basic helper required to detect Flash Player ActiveX control version information
Function VBGetSwfVer(i)
on error resume next
Dim swControl, swVersion
swVersion = 0
set swControl = CreateObject("ShockwaveFlash.ShockwaveFlash." + CStr(i))
if (IsObject(swControl)) then
swVersion = swControl.GetVariable("$version")
end if
VBGetSwfVer = swVersion
End Function
// -->
</script>
<script language="JavaScript1.1" type="text/javascript">
<!-- // Detect Client Browser type
var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
jsVersion = 1.1;
// JavaScript helper required to detect Flash Player PlugIn version information
function JSGetSwfVer(i) {
// NS/Opera version >= 3 check for Flash plugin in plugin array
if (navigator.plugins != null && navigator.plugins.length > 0) {
if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
descArray = flashDescription.split(" ");
tempArrayMajor = descArray[2].split(".");
versionMajor = tempArrayMajor[0];
versionMinor = tempArrayMajor[1];
if ( descArray[3] != "" ) {
tempArrayMinor = descArray[3].split("r");
} else {
tempArrayMinor = descArray[4].split("r");
}
versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0;
flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
} else {
flashVer = -1;
}
}
// MSN/WebTV 2.6 supports Flash 4
else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
// WebTV 2.5 supports Flash 3
else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
// older WebTV supports Flash 2
else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
// Can\'t detect in all other cases
else
{
flashVer = -1;
}
return flashVer;
}
// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) {
reqVer = parseFloat(reqMajorVer + "." + reqRevision);
// loop backwards through the versions until we find the newest version
for (i=25;i>0;i--) {
if (isIE && isWin && !isOpera) {
versionStr = VBGetSwfVer(i);
} else {
versionStr = JSGetSwfVer(i);
}
if (versionStr == -1 ) {
return false;
} else if (versionStr != 0) {
if(isIE && isWin && !isOpera) {
tempArray = versionStr.split(" ");
tempString = tempArray[1];
versionArray = tempString .split(",");
} else {
versionArray = versionStr.split(".");
}
versionMajor = versionArray[0];
versionMinor = versionArray[1];
versionRevision = versionArray[2];
versionString = versionMajor + "." + versionRevision; // 7.0r24 == 7.24
versionNum = parseFloat(versionString);
// is the major.revision >= requested major.revision AND the minor version >= requested minor
if ( (versionMajor > reqMajorVer) && (versionNum >= reqVer) ) {
return true;
} else {
return ((versionNum >= reqVer && versionMinor >= reqMinorVer) ? true : false );
}
}
}
}
// -->
</script>';
$s .= '<tr><td valign="top" colspan="2" width="520"><table><tr><td width="520">
<script>
<!--
// Version check based upon the values entered above in "Globals"
var hasReqestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);
// Check to see if the version meets the requirements for playback
if (hasReqestedVersion) { // if we\'ve detected an acceptable version
var oeTags = \'<object type="application/x-shockwave-flash" data="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&canClick:' . $canClick . '" width="600" height="' . $swf_height . '">\'
+ \'<param name="wmode" value="transparent">\'
+ \'<param name="movie" value="../plugin/hotspot/' . $swf_file . '.swf?modifyAnswers=' . $questionId . '&canClick:' . $canClick . '" />\'
+ \'<\/object>\';
document.write(oeTags); // embed the Flash Content SWF when all tests are passed
} else { // flash is too old or we can\'t detect the plugin
var alternateContent = "Error<br \/>"
+ "Hotspots requires Macromedia Flash 7.<br \/>"
+ "<a href=\"http://www.macromedia.com/go/getflash/\">Get Flash<\/a>";
document.write(alternateContent); // insert non-flash content
}
// -->
</script>
</td>
<td valign="top" align="left">' . $answer_list . '</td></tr>
</table>
</td></tr>';
echo $s;
echo '</table>';
$s .= <<<HOTSPOT
<div class="col-sm-8 col-md-9">
<div class="hotspot-image"></div>
<script>
$(document).on('ready', function () {
HotSpotUser.init({
questionId: $questionId,
selector: '#question_div_' + $questionId + ' .hotspot-image'
});
});
</script>
</div>
<div class="col-sm-4 col-md-3">
$answer_list
</div>
HOTSPOT;
echo <<<HOTSPOT
$s
</div>
</div>
HOTSPOT;
}
return $nbrAnswers;
}

@ -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 = $('<input>').attr({
type: 'hidden',
name: 'hotspot[' + config.questionId + '][' + hotspots[points.length - 1].id + ']'
}).val([x, y].join(';'));
var txtChoice = $('<input>').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);
}
};
})();
Loading…
Cancel
Save