2022-05-26 11:22:09 +02:00
|
|
|
// © 2022 Uniwersytet im. Adama Mickiewicza w Poznaniu
|
|
|
|
|
|
|
|
// Biblioteka pozwala na zapisywanie różnych informacji o aktywnościach studenta.
|
|
|
|
|
2022-05-23 10:52:50 +02:00
|
|
|
var contentFrameReference = null;
|
|
|
|
var courseWindowReference = null;
|
|
|
|
const scoReadyTime = getTimeAsStringShort();
|
|
|
|
var allInteractionsForLinksInitialized = false;
|
|
|
|
var allInteractionsForQuizInitialized = false;
|
|
|
|
var allInteractionsForFillInInitialized = false;
|
|
|
|
var allInteractionsForFillInNumericInitialized = false;
|
|
|
|
var allInteractionsForDragAndDropInitialized = false;
|
|
|
|
var quizClicksArr = [];
|
|
|
|
var interactiondIDList = [];
|
|
|
|
|
|
|
|
$(function() {
|
|
|
|
quizClicksArr = [];
|
|
|
|
interactiondIDList = [];
|
|
|
|
|
|
|
|
let interactionsCountSet = false;
|
|
|
|
|
|
|
|
$(window).scroll(function(){
|
|
|
|
if (!interactionsCountSet) {
|
|
|
|
const result = prepare(interactionsCountSet, null);
|
|
|
|
interactionsCountSet = result.interactionsCountSet;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if ($("a[target='popup']").size() > 0) {
|
|
|
|
$("a[target='popup']").click(function() {
|
|
|
|
let interactionId = -1;
|
|
|
|
const interactionName = $(this).text() + " url:" + $(this).attr("href") + " sco: " + getScoName() + " (" + getScoId() + ")";
|
|
|
|
|
|
|
|
const result = prepare(interactionsCountSet, interactionName);
|
|
|
|
interactionsCountSet = result.interactionsCountSet;
|
|
|
|
interactionId = result.interactionId;
|
|
|
|
|
|
|
|
if (interactionId != -1) {
|
|
|
|
saveData(interactionId, "clicked", "neutral");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($(".el-draganddrop-buttons-container").size() > 0) {
|
|
|
|
$(".el-draganddrop-buttons-container").each(function() {
|
|
|
|
let container$ = $(this);
|
|
|
|
container$.find(".el-draganddrop-checkbutton").click(function() {
|
|
|
|
let interactionId = -1;
|
|
|
|
|
|
|
|
const header = $(this).find(".el-element-header-text") != undefined ? "header: " + $(this).find(".el-element-header-text").text() : "";
|
|
|
|
const interactionName = "type: matching " + header + " sco: " + getScoName() + " (" + getScoId() + ")";
|
|
|
|
|
|
|
|
const result = prepare(interactionsCountSet, interactionName);
|
|
|
|
interactionsCountSet = result.interactionsCountSet;
|
|
|
|
interactionId = result.interactionId;
|
|
|
|
console.log("interactionId dd: " + interactionId);
|
|
|
|
|
|
|
|
if (interactionId != -1) {
|
|
|
|
let d = $(this).closest(".eduexe-library-draganddrop-container");
|
|
|
|
let answers = "";
|
|
|
|
let correctness = "correct";
|
|
|
|
|
|
|
|
d.find(".el-draganddrop-draggable").each(function() {
|
|
|
|
let draggableId = $(this).attr("data-drag-id");
|
|
|
|
let draggableDivQuery = 'div[data-drag-id=\"'.concat(draggableId).concat('\"]');
|
|
|
|
let draggableDiv = container$.find(draggableDivQuery);
|
|
|
|
let draggableDivText = draggableDiv.text();
|
|
|
|
|
|
|
|
let droppedonDivQuery = 'div[data-droppedon-id=\"'.concat(draggableId).concat('\"]');
|
|
|
|
let droppedonDiv = container$.find(droppedonDivQuery);
|
|
|
|
|
|
|
|
let dropDivQuery = 'div[data-drop-id=\"'.concat(draggableId).concat('\"]');
|
|
|
|
let dropDiv = container$.find(dropDivQuery);
|
|
|
|
let dropDivKeywordText = dropDiv.prevAll(".el-draganddrop-keyword:first").text();
|
|
|
|
|
|
|
|
if (droppedonDiv.length) {
|
|
|
|
var droppedonDivPairId = droppedonDiv.attr("data-drop-id");
|
|
|
|
if (droppedonDivPairId == draggableId) {
|
|
|
|
// Element draggable upuszczono na właściwy element droppable
|
|
|
|
draggableDiv.css("border", "2px solid green");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Element draggable upuszczono na niewłaściwy element droppable
|
|
|
|
draggableDiv.css("border", "2px solid red");
|
|
|
|
correctness = "incorrect";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (dropDiv.length) {
|
|
|
|
// Element draggable pozostawiono nieupuszczony, ale była do niego para
|
|
|
|
draggableDiv.css("border", "2px solid red");
|
|
|
|
correctness = "incorrect";
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Element draggable pozostawiono nieupuszczony i nie było do niego pary
|
|
|
|
draggableDiv.css("border", "2px solid green");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
answers = answers + dropDivKeywordText + "[.]" + draggableDivText + "[,]"; // puste dropDivKeywordText i draggableDivText ?! :(
|
|
|
|
});
|
|
|
|
|
|
|
|
answers = answers.substring(0, answers.length - 3);
|
|
|
|
|
|
|
|
saveData(interactionId, answers, correctness);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($(".eduexe-library-quiz-container form").size() > 0) {
|
|
|
|
$(".eduexe-library-quiz-container form").click(function() {
|
|
|
|
let interactionId = -1;
|
|
|
|
|
|
|
|
const header = $(this).parent().parent().parent().parent().find(".el-element-header-text") != undefined ? "header: " + $(this).parent().parent().parent().parent().find(".el-element-header-text").text() : "";
|
|
|
|
const interactionName = "type: quiz " + header
|
|
|
|
+ " introduction:" + $(this).parent().parent().parent().parent().find("el-quiz-introduction").text() + " question:"
|
|
|
|
+ $(this).parent().parent().parent().parent().find(".el-quiz-question").text() + " sco: " + getScoName() + " (" + getScoId() + ")";
|
|
|
|
|
|
|
|
const result = prepare(interactionsCountSet, interactionName);
|
|
|
|
interactionsCountSet = result.interactionsCountSet;
|
|
|
|
interactionId = result.interactionId;
|
|
|
|
|
|
|
|
if (interactionId != -1) {
|
|
|
|
if (quizClicksArr.includes(interactionId)) {
|
|
|
|
const index = quizClicksArr.indexOf(interactionId);
|
|
|
|
if (index > -1) {
|
|
|
|
quizClicksArr.splice(index, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
let answers = "";
|
|
|
|
let correctness = "correct";
|
|
|
|
let correctN = 0;
|
|
|
|
let k = 0;
|
|
|
|
const selector = $(this).parent().parent().find(".el-checkbox").size() > 0 ? ".el-checkbox" : ".el-radio";
|
|
|
|
|
|
|
|
$(this).find(selector).each(function() {
|
|
|
|
if ($(this).find("input").attr("data-val") == "true") {
|
|
|
|
correctN++;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
let answersCorrectN = 0;
|
|
|
|
const n = $(this).find(selector + " input:checked").size();
|
|
|
|
$(this).find(selector).each(function() {
|
|
|
|
if ($(this).find("input").is(":checked")) {
|
|
|
|
answers += $(this).find("p").text();
|
|
|
|
|
|
|
|
if (k < n - 1) {
|
|
|
|
answers += ";";
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($(this).find("input").attr("data-val") == "false") {
|
|
|
|
correctness = "incorrect";
|
|
|
|
} else {
|
|
|
|
answersCorrectN++;
|
|
|
|
}
|
|
|
|
|
|
|
|
k++;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if (answers.length == 0) {
|
|
|
|
correctness = "incorrect";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (correctN != answersCorrectN) {
|
|
|
|
correctness = "incorrect";
|
|
|
|
}
|
|
|
|
|
|
|
|
saveData(interactionId, answers, correctness);
|
|
|
|
} else {
|
|
|
|
quizClicksArr.push(interactionId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($(".eduexe-library-fillin-container form input").size() > 0) {
|
|
|
|
const $input = $('.eduexe-library-fillin-container form input');
|
|
|
|
|
|
|
|
$input.each(function() {
|
|
|
|
const that = $(this);
|
|
|
|
|
|
|
|
let typingTimer; //timer identifier
|
|
|
|
const doneTypingInterval = 500; //time in ms, 0.5 second
|
|
|
|
|
|
|
|
that.on('keyup', function(event) {
|
|
|
|
const keyCode = event.keyCode || event.which;
|
|
|
|
|
|
|
|
clearTimeout(typingTimer);
|
|
|
|
typingTimer = setTimeout(function() {
|
|
|
|
let $target = $(event.target);
|
|
|
|
if (keyCode == 9) {
|
|
|
|
$target = $target.parent().parent().prev().find("input");
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($target) {
|
|
|
|
interactionsCountSet = doneTypingFillIn($target, interactionsCountSet);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (keyCode == 9) {
|
|
|
|
let nextInput = $(event.target);
|
|
|
|
if (nextInput) {
|
|
|
|
nextInput.focus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, doneTypingInterval);
|
|
|
|
});
|
|
|
|
|
|
|
|
that.on('keydown', function() {
|
|
|
|
clearTimeout(typingTimer);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($(".eduexe-library-numeric-container form input").size() > 0) {
|
|
|
|
const $inputNumeric = $('.eduexe-library-numeric-container form input');
|
|
|
|
|
|
|
|
$inputNumeric.each(function() {
|
|
|
|
const that = $(this);
|
|
|
|
|
|
|
|
let typingTimerNumeric; //timer identifier
|
|
|
|
const doneTypingIntervalNumeric = 500; //time in ms, 0.5 second
|
|
|
|
|
|
|
|
that.on('keyup', function(event) {
|
|
|
|
const keyCode = event.keyCode || event.which;
|
|
|
|
|
|
|
|
clearTimeout(typingTimerNumeric);
|
|
|
|
typingTimerNumeric = setTimeout(function() {
|
|
|
|
let $target = $(event.target);
|
|
|
|
if (keyCode == 9) {
|
|
|
|
$target = $target.parent().parent().prev().find("input");
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($target) {
|
|
|
|
interactionsCountSet = doneChangingFillInNumeric(that, interactionsCountSet);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (keyCode == 9) {
|
|
|
|
let nextInput = $(event.target);
|
|
|
|
if (nextInput) {
|
|
|
|
nextInput.focus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, doneTypingIntervalNumeric);
|
|
|
|
});
|
|
|
|
|
|
|
|
that.on('keydown', function() {
|
|
|
|
clearTimeout(typingTimerNumeric);
|
|
|
|
});
|
|
|
|
|
|
|
|
let typingTimerNumericMouse; //timer identifier
|
|
|
|
const doneTypingIntervalNumericMouse = 500; //time in ms, 0.5 second
|
|
|
|
|
|
|
|
that.on('click', function() {
|
|
|
|
clearTimeout(typingTimerNumericMouse);
|
|
|
|
typingTimerNumericMouse = setTimeout(function() {
|
|
|
|
interactionsCountSet = doneChangingFillInNumeric(that, interactionsCountSet);
|
|
|
|
}, doneTypingIntervalNumericMouse);
|
|
|
|
});
|
|
|
|
|
|
|
|
let typingTimerNumericMouseWheel; //timer identifier
|
|
|
|
const doneTypingIntervalNumericMouseWheel = 500; //time in ms, 0.5 second
|
|
|
|
|
|
|
|
that.on('wheel', function() {
|
|
|
|
clearTimeout(typingTimerNumericMouseWheel);
|
|
|
|
typingTimerNumericMouseWheel = setTimeout(function() {
|
|
|
|
interactionsCountSet = doneChangingFillInNumeric(that, interactionsCountSet);
|
|
|
|
}, doneTypingIntervalNumericMouseWheel);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
function doneChangingFillInNumeric(that, interactionsCountSet) {
|
|
|
|
let interactionId = -1;
|
|
|
|
const header = that.parent().parent().parent().parent().parent().parent().find(".el-element-header-text") != undefined ? "header: " + that.parent().parent().parent().parent().parent().parent().find(".el-element-header-text").text() : "";
|
|
|
|
const interactionName = "type: fill-in numeric " + header + " question: " + that.parent().find(".el-slide-content-header").text() + " sco: " + getScoName() + " (" + getScoId() + ")";
|
|
|
|
|
|
|
|
let result = prepare(interactionsCountSet, interactionName);
|
|
|
|
interactionsCountSet = result.interactionsCountSet;
|
|
|
|
interactionId = result.interactionId;
|
|
|
|
|
|
|
|
if (interactionId != -1) {
|
|
|
|
let correctness = "correct";
|
|
|
|
|
|
|
|
const answerCorrect = that.attr("data-val");
|
|
|
|
const answerRange = that.attr("data-range");
|
|
|
|
const userAnswer = that.val();
|
|
|
|
const answer = that.val();
|
|
|
|
|
|
|
|
that.attr("data-userans", userAnswer);
|
|
|
|
// walidacja odpowiedzi
|
|
|
|
if (answerCorrect == userAnswer) {
|
|
|
|
// wpisano dobrą odpowiedź
|
|
|
|
correctness = "correct";
|
|
|
|
} else {
|
|
|
|
if (answerRange !== undefined && Math.abs(answerCorrect - userAnswer) <= answerRange) {
|
|
|
|
// wpisano niedokładną odpowiedź, ale mieszczącą się w dopuszczalnym zakresie błędu
|
|
|
|
correctness = "correct";
|
|
|
|
} else {
|
|
|
|
// wpisano złą odpowiedź
|
|
|
|
correctness = "incorrect";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
saveData(interactionId, answer, correctness);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function doneTypingFillIn(that, interactionsCountSet) {
|
|
|
|
let interactionId = -1;
|
|
|
|
const header = that.parent().parent().parent().parent().parent().parent().find(".el-element-header-text") != undefined ? "header: " + that.parent().parent().parent().parent().parent().parent().find(".el-element-header-text").text() : "";
|
|
|
|
const interactionName = "type: fill-in " + header + " question: " + that.parent().find(".el-slide-content-header").text() + " sco: " + getScoName() + " (" + getScoId() + ")";
|
|
|
|
|
|
|
|
const result = prepare(interactionsCountSet, interactionName);
|
|
|
|
interactionsCountSet = result.interactionsCountSet;
|
|
|
|
interactionId = result.interactionId;
|
|
|
|
|
|
|
|
if (interactionId != -1) {
|
|
|
|
let correctness = "correct";
|
|
|
|
|
|
|
|
let answerCorrect = that.attr("data-val");
|
|
|
|
let userAnswer = that.val();
|
|
|
|
const answer = that.val();
|
|
|
|
|
|
|
|
// zastosuj małe litery
|
|
|
|
answerCorrect = answerCorrect.toLowerCase();
|
|
|
|
userAnswer = userAnswer.toLowerCase();
|
|
|
|
|
|
|
|
// walidacja odpowiedzi
|
|
|
|
const answerCorrectArr = answerCorrect.split(";");
|
|
|
|
let userAnswerWasCorrect = false;
|
|
|
|
for (let i = 0; i < answerCorrectArr.length; i++) {
|
|
|
|
if (answerCorrectArr[i] == userAnswer) {
|
|
|
|
// wpisano dobrą odpowiedź
|
|
|
|
userAnswerWasCorrect = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// wpisano złą odpowiedź
|
|
|
|
if (!userAnswerWasCorrect) {
|
|
|
|
correctness = "incorrect";
|
|
|
|
}
|
|
|
|
|
|
|
|
saveData(interactionId, answer, correctness);
|
|
|
|
}
|
|
|
|
|
|
|
|
return interactionsCountSet;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getContentFrameReference() {
|
|
|
|
if (document.getElementById('page-content-frame') != null) {
|
|
|
|
contentFrameReference = document.getElementById('page-content-frame').contentWindow;
|
|
|
|
} else {
|
|
|
|
contentFrameReference = window;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getCourseWindowReference() {
|
|
|
|
if (typeof window.parent.coursejson !== 'undefined') {
|
|
|
|
courseWindowReference = window.parent;
|
|
|
|
} else {
|
|
|
|
courseWindowReference = window;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*function countInteractions() {
|
|
|
|
const isPlainSCORM = courseWindowReference.getParsedCourseJson().scormPlain;
|
|
|
|
const scosNumber = courseWindowReference.getParsedCourseJson().children.length;
|
|
|
|
let numberOfInteractions = 0;
|
|
|
|
|
|
|
|
for (let i = 1; i <= scosNumber; i++) {
|
|
|
|
if (isPlainSCORM && i != getScoId()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
let currentSCOManifest = courseWindowReference.manifestDataCopy.structure['sco_' + i];
|
|
|
|
let interactions = currentSCOManifest.interactions;
|
|
|
|
numberOfInteractions += interactions.length;
|
|
|
|
|
|
|
|
for (let j = 0; j < interactions.length; j++) {
|
|
|
|
let inter = interactions[j].id;
|
|
|
|
if (interactiondIDList.indexOf(inter) == -1) {
|
|
|
|
interactiondIDList.push(inter);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return numberOfInteractions;
|
|
|
|
}*/
|
|
|
|
|
|
|
|
function countInteractionsFunction() {
|
|
|
|
console.log("countInteractionsFunction");
|
|
|
|
let i = 0;
|
|
|
|
let inter = contentFrameReference.doGetValue("cmi.interactions.0.id");
|
|
|
|
|
|
|
|
while (inter != "") {
|
|
|
|
if (interactiondIDList.indexOf(inter) == -1) {
|
|
|
|
interactiondIDList.push(inter);
|
|
|
|
}
|
|
|
|
|
|
|
|
i++;
|
|
|
|
inter = contentFrameReference.doGetValue("cmi.interactions." + i + ".id");
|
|
|
|
}
|
|
|
|
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
function initAllInteractionsForFillInNumeric(interactionsCount) {
|
|
|
|
if ($(".eduexe-library-numeric-container form input").size() > 0) {
|
|
|
|
const scoId = getScoId();
|
|
|
|
const scoTitle = getScoName();
|
|
|
|
|
|
|
|
$(".eduexe-library-numeric-container form input").each(function() {
|
|
|
|
const header = $(this).parent().parent().parent().parent().parent().parent().find(".el-element-header-text") != undefined ? "header: " + $(this).parent().parent().parent().parent().parent().parent().find(".el-element-header-text").text() : "";
|
|
|
|
const interactionName = "type: fill-in numeric " + header + " question: " + $(this).parent().find(".el-slide-content-header").text() + " sco: " + getScoName() + " (" + getScoId() + ")";
|
|
|
|
|
|
|
|
initOtherInteraction(
|
|
|
|
interactionsCount, interactionName,
|
|
|
|
scoId, scoTitle, $(this).text(), "numeric"
|
|
|
|
);
|
|
|
|
|
|
|
|
interactionsCount++;
|
|
|
|
});
|
|
|
|
|
|
|
|
// contentFrameReference.doCommit();
|
|
|
|
|
|
|
|
allInteractionsForFillInNumericInitialized = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return interactionsCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
function initAllInteractionsForFillIn(interactionsCount) {
|
|
|
|
if ($(".eduexe-library-fillin-container form input").size() > 0) {
|
|
|
|
const scoId = getScoId();
|
|
|
|
const scoTitle = getScoName();
|
|
|
|
|
|
|
|
$(".eduexe-library-fillin-container form input").each(function() {
|
|
|
|
const header = $(this).parent().parent().parent().parent().parent().parent().find(".el-element-header-text") != undefined ? "header: " + $(this).parent().parent().parent().parent().parent().parent().find(".el-element-header-text").text() : "";
|
|
|
|
const interactionName = "type: fill-in " + header + " question: " + $(this).parent().find(".el-slide-content-header").text() + " sco: " + getScoName() + " (" + getScoId() + ")";
|
|
|
|
|
|
|
|
initOtherInteraction(
|
|
|
|
interactionsCount, interactionName,
|
|
|
|
scoId, scoTitle, $(this).text(), "fill-in"
|
|
|
|
);
|
|
|
|
|
|
|
|
interactionsCount++;
|
|
|
|
});
|
|
|
|
|
|
|
|
// contentFrameReference.doCommit();
|
|
|
|
|
|
|
|
allInteractionsForFillInInitialized = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return interactionsCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
function initAllInteractionsForQuiz(interactionsCount) {
|
|
|
|
if ($(".eduexe-library-quiz-container").size() > 0) {
|
|
|
|
const scoId = getScoId();
|
|
|
|
const scoTitle = getScoName();
|
|
|
|
|
|
|
|
$(".eduexe-library-quiz-container").each(function() {
|
|
|
|
const header = $(this).find(".el-element-header-text") != undefined ? "header: " + $(this).find(".el-element-header-text").text() : "";
|
|
|
|
const introduction = $(this).find("el-quiz-introduction") != undefined ? " introduction:" + $(this).find("el-quiz-introduction").text() : "";
|
|
|
|
const interactionName = "type: quiz " + header + introduction + " question:" + $(this).find(".el-quiz-question").text() + " sco: " + getScoName() + " (" + getScoId() + ")";
|
|
|
|
const type = $(this).find(".el-quiz").find(".el-checkbox").size() > 0 ? "multiple-choice" : "single-choice";
|
|
|
|
|
|
|
|
initOtherInteraction(
|
|
|
|
interactionsCount, interactionName,
|
|
|
|
scoId, scoTitle, $(this).text(), type
|
|
|
|
);
|
|
|
|
|
|
|
|
interactionsCount++;
|
|
|
|
});
|
|
|
|
|
|
|
|
// contentFrameReference.doCommit();
|
|
|
|
|
|
|
|
allInteractionsForQuizInitialized = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return interactionsCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
function initAllInteractionsForDragAndDrop(interactionsCount) {
|
|
|
|
if ($(".eduexe-library-draganddrop-container").size() > 0) {
|
|
|
|
const scoId = getScoId();
|
|
|
|
const scoTitle = getScoName();
|
|
|
|
|
|
|
|
$(".eduexe-library-draganddrop-container").each(function() {
|
|
|
|
const header = $(this).find(".el-element-header-text") != undefined ? "header: " + $(this).find(".el-element-header-text").text() : "";
|
|
|
|
const interactionName = "type: matching " + header + " sco: " + getScoName() + " (" + getScoId() + ")";
|
|
|
|
|
|
|
|
initOtherInteraction(
|
|
|
|
interactionsCount, interactionName,
|
|
|
|
scoId, scoTitle, $(this).text(), "matching"
|
|
|
|
);
|
|
|
|
|
|
|
|
interactionsCount++;
|
|
|
|
});
|
|
|
|
|
|
|
|
// contentFrameReference.doCommit();
|
|
|
|
|
|
|
|
allInteractionsForDragAndDropInitialized = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return interactionsCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
function initAllInteractionsForLinks(interactionsCount) {
|
|
|
|
if ($("a[target='popup']").size() > 0) {
|
|
|
|
const scoId = getScoId();
|
|
|
|
const scoTitle = getScoName();
|
|
|
|
|
|
|
|
$("a[target='popup']").each(function() {
|
|
|
|
const interactionName = $(this).text() + " url:" + $(this).attr("href") + " sco: " + getScoName() + " (" + getScoId() + ")";
|
|
|
|
|
|
|
|
initOtherInteraction(
|
|
|
|
interactionsCount, interactionName,
|
|
|
|
scoId, scoTitle, $(this).prop('outerHTML'), "other"
|
|
|
|
);
|
|
|
|
|
|
|
|
interactionsCount++;
|
|
|
|
});
|
|
|
|
|
|
|
|
// contentFrameReference.doCommit();
|
|
|
|
|
|
|
|
allInteractionsForLinksInitialized = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return interactionsCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getCurrentInteractionId(interactionName) {
|
|
|
|
return interactiondIDList.indexOf(btoa(encodeURIComponent(interactionName)));
|
|
|
|
}
|
|
|
|
|
|
|
|
function prepare(interactionsCountSet, interactionName) {
|
|
|
|
let interactionsCount = 0;
|
|
|
|
|
|
|
|
console.log("interactionsCountSet:" + interactionsCountSet);
|
|
|
|
if (!interactionsCountSet) {
|
|
|
|
getContentFrameReference();
|
|
|
|
getCourseWindowReference();
|
|
|
|
interactionsCount = countInteractionsFunction();
|
|
|
|
} else {
|
|
|
|
interactionsCount = interactiondIDList.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
interactionsCountSet = true;
|
|
|
|
|
|
|
|
if (!allInteractionsForLinksInitialized) {
|
|
|
|
interactionsCount = initAllInteractionsForLinks(interactionsCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!allInteractionsForQuizInitialized) {
|
|
|
|
interactionsCount = initAllInteractionsForQuiz(interactionsCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!allInteractionsForFillInInitialized) {
|
|
|
|
interactionsCount = initAllInteractionsForFillIn(interactionsCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!allInteractionsForFillInNumericInitialized) {
|
|
|
|
interactionsCount = initAllInteractionsForFillInNumeric(interactionsCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!allInteractionsForDragAndDropInitialized) {
|
|
|
|
interactionsCount = initAllInteractionsForDragAndDrop(interactionsCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
let interactionId = null;
|
|
|
|
if (interactionName != null) {
|
|
|
|
interactionId = getCurrentInteractionId(interactionName);
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = {
|
|
|
|
interactionsCountSet: interactionsCountSet,
|
|
|
|
interactionId: interactionId
|
|
|
|
};
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getScoId() {
|
|
|
|
return "sco_" + $("body").attr("data-sco-id").trim();
|
|
|
|
}
|
|
|
|
|
|
|
|
function getScoName() {
|
|
|
|
return $(".eduexe-sco-title").first().text().trim();
|
|
|
|
}
|
|
|
|
|
|
|
|
function initOtherInteraction(interactionID, interactionName, scoId, scoTitle, content, type) {
|
|
|
|
const interEncoded = btoa(encodeURIComponent(interactionName));
|
|
|
|
if (interactiondIDList.indexOf(interEncoded) == -1) {
|
|
|
|
interactiondIDList.push(interEncoded);
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionID + '.id', interEncoded);
|
|
|
|
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionID + '.type', "other");
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionID + '.timestamp', scoReadyTime);
|
|
|
|
contentFrameReference.CMI.encodeAndSetValue('cmi.interactions.' + interactionID + '.description', content);
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionID + '.weighting', 0.0);
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionID + '.objectives.0.id', '0:learning_object');
|
|
|
|
|
|
|
|
const scoTitleSafe = btoa(encodeURIComponent(scoTitle));
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionID + '.objectives.1.id', '1:' + scoTitleSafe);
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionID + '.objectives.2.id', '2:' + scoId);
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionID + '.objectives.3.id', '3:' + type);
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionID + '.objectives.4.id', '4:');
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionID + '.objectives.5.id', '5:drawn');
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionID + '.objectives.6.id', '6:');
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionID + '.objectives.7.id', '7:');
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionID + '.objectives.8.id', '8:');
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionID + '.objectives.9.id', '9:');
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionID + '.objectives.10.id', '10:');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function saveData(interactionId, answer, result) {
|
|
|
|
updateLearnerResponse(interactionId, answer);
|
|
|
|
updateResult(interactionId, result);
|
|
|
|
saveInteractionChangeTime(interactionId, answer, result);
|
|
|
|
saveTimeSpentInInteractions(interactionId);
|
|
|
|
// contentFrameReference.doCommit();
|
|
|
|
}
|
|
|
|
|
|
|
|
function saveInteractionLatency(interactionId) {
|
|
|
|
const latencyFromCMI = contentFrameReference.doGetValue("cmi.interactions." + interactionId + ".latency");
|
|
|
|
|
|
|
|
if (latencyFromCMI == "") {
|
|
|
|
const testStartTime = Date.parse(doGetValue("cmi.interactions." + interactionId + ".timestamp") + ".000Z");
|
|
|
|
const currentTime = contentFrameReference.getTimeAsTimestamp();
|
|
|
|
const lacencyTime = currentTime - testStartTime;
|
|
|
|
const lacencyTimeSeconds = Math.round(lacencyTime / 1000);
|
|
|
|
const latencyFormatted = "PT" + lacencyTimeSeconds + "S";
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionId + '.latency', latencyFormatted);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateNumberOfAnswerChanges(interactionId) {
|
|
|
|
const dataOfObjectives8Raw = contentFrameReference.doGetValue("cmi.interactions." + interactionId + ".objectives.8.id");
|
|
|
|
let numberOfAnswerChanges = dataOfObjectives8Raw.substr(2);
|
|
|
|
|
|
|
|
if (numberOfAnswerChanges == "") {
|
|
|
|
contentFrameReference.doSetValue("cmi.interactions." + interactionId + ".objectives.8.id", "8:1");
|
|
|
|
} else {
|
|
|
|
numberOfAnswerChanges = parseInt(numberOfAnswerChanges) + 1;
|
|
|
|
contentFrameReference.doSetValue("cmi.interactions." + interactionId + ".objectives.8.id", "8:" + numberOfAnswerChanges.toString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateLearnerResponse(interactionId, answer) {
|
|
|
|
contentFrameReference.CMI.encodeAndSetValue('cmi.interactions.' + interactionId + '.learner_response', answer);
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateResult(interactionId, result) {
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionId + '.result', result);
|
|
|
|
}
|
|
|
|
|
|
|
|
function saveInteractionChangeTime(interactionId, answer, result) {
|
|
|
|
const dataOfObjectives9Raw = contentFrameReference.doGetValue("cmi.interactions." + interactionId + ".objectives.9.id");
|
|
|
|
const changesArrayStr = dataOfObjectives9Raw.substr(2);
|
|
|
|
|
|
|
|
let changesArrayObj = [];
|
|
|
|
if (changesArrayStr != "") {
|
|
|
|
changesArrayObj = JSON.parse(contentFrameReference.CMI.eduexeDecodeText(changesArrayStr));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (answer.length > 0 && ((changesArrayObj.length > 0 && changesArrayObj[changesArrayObj.length - 1].answer != answer && answer != "clicked") || changesArrayObj.length == 0)) {
|
|
|
|
changesArrayObj.push({ "time": contentFrameReference.getTimeAsTimestamp(), "answer": answer, "result": result });
|
|
|
|
saveInteractionLatency(interactionId);
|
|
|
|
updateNumberOfAnswerChanges(interactionId);
|
|
|
|
contentFrameReference.doSetValue("cmi.interactions." + interactionId + ".objectives.9.id", "9:"
|
|
|
|
+ contentFrameReference.CMI.eduexeEncodeText(JSON.stringify(changesArrayObj)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function saveTimeSpentInInteractions(interactionId) {
|
|
|
|
const currentTime = Date.now();
|
|
|
|
const intStarted = contentFrameReference.doGetValue('cmi.interactions.' + interactionId + '.timestamp');
|
|
|
|
const intStartedDate = new Date(intStarted + '.000Z');
|
|
|
|
let timeSpent = currentTime - intStartedDate.getTime();
|
|
|
|
timeSpent = Math.round(timeSpent / 1000);
|
|
|
|
let timeSpentPrevious = contentFrameReference.doGetValue('cmi.interactions.' + interactionId + '.objectives.10.id');
|
|
|
|
timeSpentPrevious = timeSpentPrevious.substr(3);
|
|
|
|
if (timeSpentPrevious == "") {
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionId + '.objectives.10.id', "10:" + timeSpent.toString());
|
|
|
|
} else {
|
|
|
|
timeSpent += parseInt(timeSpentPrevious);
|
|
|
|
contentFrameReference.doSetValue('cmi.interactions.' + interactionId + '.objectives.10.id', "10:" + timeSpent.toString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function getTimeAsStringShort() {
|
|
|
|
const date = new Date();
|
|
|
|
return dateStr = date.toISOString().split(".")[0];
|
|
|
|
}
|