Fix sequence ordering see #7846

1.10.x
Julio Montoya 9 years ago
parent 16620dab75
commit 4b043729c3
  1. 13
      main/exercice/answer.class.php
  2. 20
      main/exercice/exercise.class.php
  3. 6
      main/exercice/exercise_submit.php
  4. 18
      main/inc/lib/exercise.lib.php
  5. 10
      main/inc/lib/template.lib.php
  6. 440
      main/template/default/exercise/submit.js.tpl

@ -206,7 +206,14 @@ class Answer
$sql = "SELECT type FROM $TBL_QUIZ
WHERE c_id = {$this->course_id} AND id = $questionId";
$result_question = Database::query($sql);
$question_type = Database::fetch_array($result_question);
$questionType = Database::fetch_array($result_question);
if ($questionType['type'] == DRAGGABLE) {
// Random is done by submit.js.tpl
$this->read();
return true;
}
$sql = "SELECT
answer,
@ -229,7 +236,7 @@ class Answer
// while a record is found
$doubt_data = null;
while ($object = Database::fetch_object($result)) {
if ($question_type['type'] == UNIQUE_ANSWER_NO_OPTION && $object->position == 666) {
if ($questionType['type'] == UNIQUE_ANSWER_NO_OPTION && $object->position == 666) {
$doubt_data = $object;
continue;
}
@ -243,7 +250,7 @@ class Answer
$i++;
}
if ($question_type['type'] == UNIQUE_ANSWER_NO_OPTION && !empty($doubt_data)) {
if ($questionType['type'] == UNIQUE_ANSWER_NO_OPTION && !empty($doubt_data)) {
$this->answer[$i] = $doubt_data->answer;
$this->correct[$i] = $doubt_data->correct;
$this->comment[$i] = $doubt_data->comment;

@ -2866,6 +2866,7 @@ class Exercise
exe_id = '$exeId' AND
question_id = '$questionId' AND
position = '$i_answer_id_auto'";
$res_user_answer = Database::query($sql);
if (Database::num_rows($res_user_answer) > 0) {
@ -2879,19 +2880,22 @@ class Exercise
$user_answer = '';
if (!empty($s_user_answer)) {
if ($s_user_answer == $i_answer_correct_answer) {
$questionScore += $i_answerWeighting;
$totalScore += $i_answerWeighting;
if ($answerType == DRAGGABLE) {
if ($answerType == DRAGGABLE) {
if ($s_user_answer == $i_answer_correct_answer) {
$questionScore += $i_answerWeighting;
$totalScore += $i_answerWeighting;
$user_answer = Display::label(get_lang('Correct'), 'success');
} else {
$user_answer = Display::label(get_lang('Incorrect'), 'danger');
}
} else {
if ($s_user_answer == $i_answer_correct_answer) {
$questionScore += $i_answerWeighting;
$totalScore += $i_answerWeighting;
if (isset($real_list[$i_answer_id])) {
$user_answer = Display::span($real_list[$i_answer_id]);
}
}
} else {
if ($answerType == DRAGGABLE) {
$user_answer = Display::label(get_lang('Incorrect'), 'danger');
} else {
$user_answer = Display::span(
$real_list[$s_user_answer],

@ -62,8 +62,6 @@ $htmlHeadXtra[] = api_get_js('epiclock/renderers/minute/epiclock.minute.js');
$template = new Template();
$htmlHeadXtra[] = $template->fetch('default/exercise/submit.js.tpl');
// General parameters passed via POST/GET
$learnpath_id = isset($_REQUEST['learnpath_id']) ? intval($_REQUEST['learnpath_id']) : 0;
@ -94,7 +92,7 @@ $exercise_attempt_table = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_ATT
/* Teacher takes an exam and want to see a preview,
we delete the objExercise from the session in order to get the latest
changes in the exercise */
if (api_is_allowed_to_edit(null,true) && isset($_GET['preview']) && $_GET['preview'] == 1 ) {
if (api_is_allowed_to_edit(null, true) && isset($_GET['preview']) && $_GET['preview'] == 1 ) {
Session::erase('objExercise');
}
@ -145,6 +143,8 @@ if ($objExercise->review_answers) {
exit;
}
}
$template->assign('shuffle_answers', $objExercise->random_answers);
$htmlHeadXtra[] = $template->fetch('default/exercise/submit.js.tpl');
$current_timestamp = time();
$my_remind_list = array();

@ -39,6 +39,7 @@ class ExerciseLib
$exercise_feedback = null,
$show_answers = false
) {
$course_id = api_get_course_int_id();
// Change false to true in the following line to enable answer hinting
$debug_mark_answer = $show_answers;
@ -86,9 +87,8 @@ class ExerciseLib
// construction of the Answer object (also gets all answers details)
$objAnswerTmp = new Answer($questionId);
$nbrAnswers = $objAnswerTmp->selectNbrAnswers();
$course_id = api_get_course_int_id();
$quiz_question_options = Question::readQuestionOption(
$questionId,
$course_id
@ -124,8 +124,6 @@ HTML;
for ($answerId = 1; $answerId <= $nbrAnswers; $answerId++) {
$answerCorrect = $objAnswerTmp->isCorrect($answerId);
$numAnswer = $objAnswerTmp->selectAutoId($answerId);
$answer = $objAnswerTmp->selectAnswer($answerId);
if ($answerCorrect == 0) {
// options (A, B, C, ...) that will be put into the list-box
// have the "correct" field set to 0 because they are answer
@ -631,7 +629,8 @@ HTML;
$trackAttempts = Database::get_main_table(
TABLE_STATISTIC_TRACK_E_ATTEMPT
);
$sqlTrackAttempt = 'SELECT answer FROM ' . $trackAttempts . ' WHERE exe_id=' . $exe_id . ' AND question_id=' . $questionId;
$sqlTrackAttempt = 'SELECT answer FROM ' . $trackAttempts . '
WHERE exe_id=' . $exe_id . ' AND question_id=' . $questionId;
$rsLastAttempt = Database::query($sqlTrackAttempt);
$rowLastAttempt = Database::fetch_array($rsLastAttempt);
$answer = $rowLastAttempt['answer'];
@ -789,9 +788,6 @@ HTML;
if (isset($user_choice_array_position[$numAnswer]) && $val['id'] == $user_choice_array_position[$numAnswer]) {
$selected = 'selected="selected"';
}
/*if (isset($user_choice_array[$matching_correct_answer]) && $val['id'] == $user_choice_array[$matching_correct_answer]['answer']) {
$selected = 'selected="selected"';
}*/
$s .= '<option value="' . $val['id'] . '" ' . $selected . '>' . $val['letter'] . '</option>';
} // end foreach()
@ -825,6 +821,11 @@ HTML;
} elseif ($answerType == DRAGGABLE) {
if ($answerCorrect != 0) {
$parsed_answer = $answer;
/*$lines_count = '';
$data = $objAnswerTmp->getAnswerByAutoId($numAnswer);
$data = $objAnswerTmp->getAnswerByAutoId($data['correct']);
$lines_count = $data['answer'];*/
$windowId = $questionId . '_' . $lines_count;
$s .= '<li class="touch-items" id="' . $windowId . '">';
@ -901,7 +902,6 @@ JAVASCRIPT;
while (isset($select_items[$lines_count])) {
$s .= Display::tag('b', $select_items[$lines_count]['letter']);
$s .= $select_items[$lines_count]['answer'];
$lines_count++;
}
}

@ -614,7 +614,7 @@ class Template
public function set_js_files()
{
global $disable_js_and_css_files, $htmlHeadXtra;
$isoCode = api_get_language_isocode();
//JS files
@ -1092,12 +1092,12 @@ class Template
}
/**
* @param $tpl_var
* @param null $value
* @param string $variable
* @param mixed $value
*/
public function assign($tpl_var, $value = null)
public function assign($variable, $value = '')
{
$this->params[$tpl_var] = $value;
$this->params[$variable] = $value;
}
/**

@ -1,243 +1,267 @@
<script>
var DraggableAnswer = {
gallery: null,
trash: null,
deleteItem: function (item, insertHere) {
if (insertHere.find(".exercise-draggable-answer-option").length > 0) {
return false;
}
item.fadeOut(function () {
var $list = $('<div class="gallery ui-helper-reset"/>').appendTo(insertHere);
var DraggableAnswer = {
gallery: null,
trash: null,
deleteItem: function (item, insertHere) {
if (insertHere.find(".exercise-draggable-answer-option").length > 0) {
return false;
}
item.find('a.btn').remove();
item.fadeOut(function () {
var $list = $('<div class="gallery ui-helper-reset"/>').appendTo(insertHere);
var droppedId = item.attr('id'),
dropedOnId = insertHere.attr('id'),
originSelectId = 'window_' + droppedId + '_select',
value = dropedOnId.split('_')[2];
item.find('a.btn').remove();
$('#' + originSelectId + ' option')
.filter(function (index) {
return index === parseInt(value);
})
.attr("selected", true);
var recycleButton = $('<a>')
.attr('href', '#')
.addClass('btn btn-default btn-xs')
.append(
"{{ "Undo" | get_lang }} ",
$('<i>').addClass('fa fa-undo')
)
.on('click', function (e) {
e.preventDefault();
var droppedId = item.attr('id'),
dropedOnId = insertHere.attr('id'),
originSelectId = 'window_' + droppedId + '_select',
value = dropedOnId.split('_')[2];
$('#' + originSelectId + ' option')
.filter(function (index) {
return index === parseInt(value);
})
.attr("selected", true);
var recycleButton = $('<a>')
.attr('href', '#')
.addClass('btn btn-default btn-xs')
.append(
"{{ "Undo" | get_lang }} ",
$('<i>').addClass('fa fa-undo')
)
.on('click', function (e) {
e.preventDefault();
var liParent = $(this).parent();
DraggableAnswer.recycleItem(liParent);
});
var liParent = $(this).parent();
item.append(recycleButton).appendTo($list).fadeIn();
});
},
recycleItem: function (item) {
item.fadeOut(function () {
item
.find('a.btn')
.remove()
.end()
.find("img")
.end()
.appendTo(DraggableAnswer.gallery)
.fadeIn();
});
var droppedId = item.attr('id'),
originSelectId = 'window_' + droppedId + '_select';
$('#' + originSelectId + ' option:first').attr('selected', 'selected');
},
init: function (gallery, trash) {
this.gallery = gallery;
this.trash = trash;
$("li", DraggableAnswer.gallery).draggable({
cancel: "a.ui-icon",
revert: "invalid",
containment: "document",
helper: "clone",
cursor: "move"
});
DraggableAnswer.trash.droppable({
accept: ".exercise-draggable-answer > li",
hoverClass: "ui-state-active",
drop: function (e, ui) {
DraggableAnswer.deleteItem(ui.draggable, $(this));
}
});
DraggableAnswer.recycleItem(liParent);
});
DraggableAnswer.gallery.droppable({
drop: function (e, ui) {
DraggableAnswer.recycleItem(ui.draggable, $(this));
}
});
}
};
var MatchingDraggable = {
colorDestination: '#316B31',
curviness: 0,
connectorType: 'Straight',
initialized: false,
init: function (questionId) {
var windowQuestionSelector = '.window' + questionId + '_question',
countConnections = $(windowQuestionSelector).length,
colorArray = [],
colorArrayDestination = [];
if (countConnections > 0) {
colorArray = $.xcolor.analogous("#da0", countConnections);
colorArrayDestination = $.xcolor.analogous("#51a351", countConnections);
} else {
colorArray = $.xcolor.analogous("#da0", 10);
colorArrayDestination = $.xcolor.analogous("#51a351", 10);
}
item.append(recycleButton).appendTo($list).fadeIn();
});
},
recycleItem: function (item) {
item.fadeOut(function () {
item
.find('a.btn')
.remove()
.end()
.find("img")
.end()
.appendTo(DraggableAnswer.gallery)
.fadeIn();
});
jsPlumb.importDefaults({
DragOptions: {cursor: 'pointer', zIndex: 2000},
PaintStyle: {strokeStyle: '#000'},
EndpointStyle: {strokeStyle: '#316b31'},
Endpoint: 'Rectangle',
Anchors: ['TopCenter', 'TopCenter']
});
var exampleDropOptions = {
tolerance: 'touch',
hoverClass: 'dropHover',
activeClass: 'dragActive'
};
var destinationEndPoint = {
endpoint: ["Dot", {radius: 15}],
paintStyle: {fillStyle: MatchingDraggable.colorDestination},
isSource: false,
connectorStyle: {strokeStyle: MatchingDraggable.colorDestination, lineWidth: 8},
connector: [
MatchingDraggable.connectorType,
{curviness: MatchingDraggable.curviness}
],
maxConnections: 1000,
isTarget: true,
dropOptions: exampleDropOptions,
beforeDrop: function (params) {
jsPlumb.select({source: params.sourceId}).each(function (connection) {
jsPlumb.detach(connection);
});
var droppedId = item.attr('id'),
originSelectId = 'window_' + droppedId + '_select';
$('#' + originSelectId + ' option:first').attr('selected', 'selected');
},
init: function (gallery, trash) {
this.gallery = gallery;
this.trash = trash;
$("li", DraggableAnswer.gallery).draggable({
cancel: "a.ui-icon",
revert: "invalid",
containment: "document",
helper: "clone",
cursor: "move"
});
var selectId = params.sourceId + "_select";
var value = params.targetId.split("_")[2];
DraggableAnswer.trash.droppable({
accept: ".exercise-draggable-answer > li",
hoverClass: "ui-state-active",
drop: function (e, ui) {
DraggableAnswer.deleteItem(ui.draggable, $(this));
}
});
$("#" + selectId + " option")
.removeAttr('selected')
.filter(function (index) {
return index === parseInt(value);
})
.attr("selected", true);
DraggableAnswer.gallery.droppable({
drop: function (e, ui) {
DraggableAnswer.recycleItem(ui.draggable, $(this));
}
});
}
};
var MatchingDraggable = {
colorDestination: '#316B31',
curviness: 0,
connectorType: 'Straight',
initialized: false,
init: function (questionId) {
var windowQuestionSelector = '.window' + questionId + '_question',
countConnections = $(windowQuestionSelector).length,
colorArray = [],
colorArrayDestination = [];
if (countConnections > 0) {
colorArray = $.xcolor.analogous("#da0", countConnections);
colorArrayDestination = $.xcolor.analogous("#51a351", countConnections);
} else {
colorArray = $.xcolor.analogous("#da0", 10);
colorArrayDestination = $.xcolor.analogous("#51a351", 10);
return true;
}
};
jsPlumb.importDefaults({
DragOptions: {cursor: 'pointer', zIndex: 2000},
PaintStyle: {strokeStyle: '#000'},
EndpointStyle: {strokeStyle: '#316b31'},
Endpoint: 'Rectangle',
Anchors: ['TopCenter', 'TopCenter']
});
var count = 0;
var sourceDestinationArray = [];
var exampleDropOptions = {
tolerance: 'touch',
hoverClass: 'dropHover',
activeClass: 'dragActive'
};
$(windowQuestionSelector).each(function (index) {
var windowId = $(this).attr("id");
var scope = windowId + "scope";
var destinationColor = colorArray[count].getHex();
var destinationEndPoint = {
endpoint: ["Dot", {radius: 15}],
paintStyle: {fillStyle: MatchingDraggable.colorDestination},
isSource: false,
connectorStyle: {strokeStyle: MatchingDraggable.colorDestination, lineWidth: 8},
var sourceEndPoint = {
endpoint: [
"Dot",
{radius: 15}
],
paintStyle: {
fillStyle: destinationColor
},
isSource: true,
connectorStyle: {
strokeStyle: "#8a8888",
lineWidth: 8
},
connector: [
MatchingDraggable.connectorType,
{curviness: MatchingDraggable.curviness}
],
maxConnections: 1000,
isTarget: true,
maxConnections: 1,
isTarget: false,
dropOptions: exampleDropOptions,
beforeDrop: function (params) {
jsPlumb.select({source: params.sourceId}).each(function (connection) {
jsPlumb.detach(connection);
});
scope: scope
};
var selectId = params.sourceId + "_select";
var value = params.targetId.split("_")[2];
sourceDestinationArray[count + 1] = sourceEndPoint;
$("#" + selectId + " option")
.removeAttr('selected')
.filter(function (index) {
return index === parseInt(value);
})
.attr("selected", true);
count++;
return true;
}
};
jsPlumb.addEndpoint(
windowId,
{
anchor: ['RightMiddle', 'RightMiddle', 'RightMiddle', 'RightMiddle']
},
sourceEndPoint
);
var count = 0;
var sourceDestinationArray = [];
var destinationCount = 0;
$(windowQuestionSelector).each(function (index) {
var windowId = $(this).attr("id");
var scope = windowId + "scope";
var destinationColor = colorArray[count].getHex();
var sourceEndPoint = {
endpoint: [
"Dot",
{radius: 15}
],
paintStyle: {
fillStyle: destinationColor
},
isSource: true,
connectorStyle: {
strokeStyle: "#8a8888",
lineWidth: 8
},
connector: [
MatchingDraggable.connectorType,
{curviness: MatchingDraggable.curviness}
],
maxConnections: 1,
isTarget: false,
dropOptions: exampleDropOptions,
scope: scope
};
sourceDestinationArray[count + 1] = sourceEndPoint;
count++;
var windowDestinationId = $(this).attr("id");
destinationEndPoint.scope = scope;
destinationEndPoint.paintStyle.fillStyle = colorArrayDestination[destinationCount].getHex();
destinationCount++;
jsPlumb.addEndpoint(
windowId,
windowDestinationId + "_answer",
{
anchor: ['RightMiddle', 'RightMiddle', 'RightMiddle', 'RightMiddle']
anchors: ['LeftMiddle', 'LeftMiddle', 'LeftMiddle', 'LeftMiddle']
},
sourceEndPoint
destinationEndPoint
);
var destinationCount = 0;
$(windowQuestionSelector).each(function (index) {
var windowDestinationId = $(this).attr("id");
destinationEndPoint.scope = scope;
destinationEndPoint.paintStyle.fillStyle = colorArrayDestination[destinationCount].getHex();
destinationCount++;
jsPlumb.addEndpoint(
windowDestinationId + "_answer",
{
anchors: ['LeftMiddle', 'LeftMiddle', 'LeftMiddle', 'LeftMiddle']
},
destinationEndPoint
);
});
});
});
MatchingDraggable.attachBehaviour();
},
attachBehaviour: function () {
if (!MatchingDraggable.initialized) {
MatchingDraggable.initialized = true;
}
}
};
jsPlumb.ready(function () {
if ($(".drag_question").length > 0) {
MatchingDraggable.init();
$(document).scroll(function () {
jsPlumb.repaintEverything();
});
$(window).resize(function () {
jsPlumb.repaintEverything();
});
MatchingDraggable.attachBehaviour();
},
attachBehaviour: function () {
if (!MatchingDraggable.initialized) {
MatchingDraggable.initialized = true;
}
});
$(document).on('ready', function () {
DraggableAnswer.init(
$(".exercise-draggable-answer"),
$(".droppable")
);
});
}
};
jsPlumb.ready(function () {
if ($(".drag_question").length > 0) {
MatchingDraggable.init();
$(document).scroll(function () {
jsPlumb.repaintEverything();
});
$(window).resize(function () {
jsPlumb.repaintEverything();
});
}
});
$(document).on('ready', function () {
DraggableAnswer.init(
$(".exercise-draggable-answer"),
$(".droppable")
);
// if shuffle answers
if ('{{ shuffle_answers }}' == '1') {
$('.exercise-draggable-answer').each(function(){
// get current ul
var $ul = $(this);
// get array of list items in current ul
var $liArr = $ul.children('li');
// sort array of list items in current ul randomly
$liArr.sort(function(a,b){
// Get a random number between 0 and 10
var temp = parseInt( Math.random()*100 );
// Get 1 or 0, whether temp is odd or even
var isOddOrEven = temp%2;
// Get +1 or -1, whether temp greater or smaller than 5
var isPosOrNeg = temp>5 ? 1 : -1;
// Return -1, 0, or +1
return( isOddOrEven*isPosOrNeg );
})
// append list items to ul
.appendTo($ul);
});
}
});
</script>

Loading…
Cancel
Save