//jquery UI stubs to prevent errors
jQuery.fn.extend({
button: function(){},
dialog: function(){}
});
//dom manipulations for Bootstrap styling
$(document).ready(function(){
$("[data-type=chapter]").addClass("container");
$("[data-block_type=row]").addClass("row");
});
$("[data-block_type=row]").each(function(index, element){
$(element).find("[data-type=box]").each(function(index, boxElement){
var block_type = $(boxElement).attr("data-block_type");
if(block_type.indexOf("col") == 0){
//its a special column box and we need to set the bootstrap class
$(boxElement).addClass(block_type);
}
});
});
var Activity_gore = Activity_manuscript_type.extend({
submit_question: function (question_index) {
// the arg may be a number or an event object; in the latter case...
if (typeof question_index == "object") {
// extract the question_index from the object
question_index = question_index.data.question_index;
}
//force all queries to be answered before doing anything.
var allQueriesAnswered = true;
for (var i = 0; i < player.activity.questions[question_index].queries.length; i++) {
var x = player.activity.questions[question_index].queries[i].user_has_answered();
if (!x) {
allQueriesAnswered = false;
}
}
if (!allQueriesAnswered) {
$("
Please answer all of the questions before submitting.
").dialog({
buttons: [{
text: "OK",
click: function () {
$(this).dialog("close");
}
}]
});
//alert("answer all questions!");
return false;
}
this._super(question_index);
// the arg may be a number or an event object; in the latter case...
if (typeof question_index == "object") {
// extract the question_index from the object
question_index = question_index.data.question_index;
}
player.activity.questions[question_index].checkModelUpdateConditionals(question_index);
//var executedNextStep = player.activity.questions[question_index].checkNextStepConditionals(question_index);
//player.sendModelToServer();
//check if we need to show the next button
return false;
},
});
var Player_gore = Player_manuscript_type.extend({
show_navigation: function() {
var html = "
"+ UI_Elements.get_button_html({
id: "next_button",
extra_class: "toolbar_button prev_next_buttons",
label: "Next",
fn: 'player.show_section("next")'
*/
$("[data-type=chapter]").before(html);
// button at the bottom of the manuscript to go on to the next step
var next_button_html = "";
$("[data-type=chapter]").append(next_button_html);
},
update_navigation: function() {
// show/hide the "next" button as appropriate
if (this.last_available_section > this.section_currently_showing && this.showing_last_section() == false) {
UI_Elements.toggle_button("step_button", true);
} else {
UI_Elements.toggle_button("step_button", false);
}
if (this.showing_last_section() && player.activity.answered_all_queries) {
player.show_completion_message();
}
},
});
player = new Player_gore();
//to not show the letters for MC choices
MC_Query = MC_Query.extend({
// mode should be "delivery" or "review"; "delivery" is assumed
getHTML: function (mode) {
// initialize imagemap elements
if (this.imagemap_initialized === false) {
var question_jq = this.jq.parent();
this.im_init(question_jq);
this.imagemap_initialized = true;
}
// start with the query text, if there
var html = this.query_text_html();
// wrap answers in a p tag
html += "
";
// Build answer selection
var is_correct = false;
for (var z = 0; z < this.choices.length; z++) {
var index = this.choice_order[z];
// if this is review mode...
var checked = "";
var disabled = "";
var radio_style = "query_mc_other_choice";
if (mode == 'review' || mode == 'review_correct_incorrect' || mode == 'preview') {
// if it's the correct choice, it should be marked in green
if (index == this.correct_answer_index) {
// but only if we're *not* in review_correct_incorrect mode or this is the user's choice
if (mode != 'review_correct_incorrect' || index == this.user_answer_index) {
radio_style = "query_mc_correct_choice";
}
// if this is what the user chose, he got it correct
if (index == this.user_answer_index) {
is_correct = true;
}
// else if it's the user's choice (and this.md.no_correct_answer is not true), it should be marked in red
} else if (index == this.user_answer_index && this.md.no_correct_answer != "true") {
radio_style = "query_mc_incorrect_user_choice";
}
// and the input should be disabled, unless we're in review_correct_incorrect mode
if (mode != "review_correct_incorrect") {
disabled = "disabled";
}
}
// if this is the choice the user clicked, it's checked (regardless of mode)
if (index == this.user_answer_index) {
checked = "checked";
}
// Create radio button input plus label
html += "
"
+ "
"
+ "
"
//+ "
" + this.choice_ids[z] + ".
"
+ "
"
+ "
";
}
// get a possible feedback string; this fn will take account of mode
html += this.correct_incorrect_feedback(mode, is_correct);
html += "";
return html;
}
});
var DD_Query = Query.extend({
// ========================================
// define and set defaults for variables specific to this query type
choices: new Array(),
choice_order: new Array(),
correct_answer_index: null,
user_answer_index: null,
// ========================================
// initialization
parseSource: function() {
// initialize vars
this.choices = new Array();
this.correct_answer_index = null;
this.user_answer_index = null;
// DD's are always one line only -- if query_text is specified, it's via metadata (see below)
this.query_text = "";
// the line might start with "DD:"; if so, strip it out
var s = jQuery.trim(this.query_source.replace(/^DD:\s*/, ""));
// if line ends with "~~\d+", that's points
if (s.search(/(.*)~~([\.\d]+)$/) > -1) {
s = RegExp.$1;
this.points_possible = RegExp.$2;
}
// if the line starts with "!!", don't scramble
if (s.substr(0, 2) == "!!") {
this.md.never_scramble = "true";
// strip the !! out of answer
s = s.replace(/^\!\!/, "");
}
// if the line ends with "??", any answer is correct
if (s.substr(-2, 2) == "??") {
this.md.no_correct_answer = "true";
// strip the ?? out of answer
s = s.replace(/\?\?$/, "");
}
// if any commas were sent in as "\,", turn them into ,
s = s.replace(/\\,/g, ",");
// likewise, turn "\*" into *
s = s.replace(/\\\*/g, "*");
// we might have "'s indicating double quotes in the answers;
// convert these to actual double quotes so that they display properly (though it might not matter)
s = s.replace(/\"/g, '"');
// answer string should be something like "choice 1, choice2, *correct choice"
// so split it and find the correct answer
var answers = s.split(/,\s*/);
var correctChoice = -1;
for (var i = 0; i < answers.length; ++i) {
var ans = answers[i];
// look for points...
if (ans.search(/^_points:\s*(\d+)/i) > -1) {
this.points_possible = RegExp.$1;
// skip to the next answer
continue;
// or query text
} else if (ans.search(/^_query_text:\s*(.*)/i) > -1) {
this.query_text = RegExp.$1;
// skip to the next answer
continue;
// or metadata -- starts with "_[a-zA-Z]"
} else if (ans.search(/^\_[a-zA-Z]/) > -1) {
this.extractMetadata(ans);
// skip to the next answer
continue;
// if we've found the correct answer...
} else if (ans.substr(0,1) == "*") {
// if we already got a correctChoice, there's an error
if (this.correct_answer_index != null) {
return "error in pulldown answer (too many correct answers): " + s + "";
}
// otherwise this one is correct
this.correct_answer_index = i;
// strip the leading *
ans = ans.substr(1);
}
// convert *s to literal *'s now; also convert commas
ans = ans.replace(/\*/g, '*');
ans = ans.replace(/\,/g, ',');
// transfer to choices, trimming in the process
this.choices.push(jQuery.trim(ans));
}
// note: answers will be coded 0, 1, 2, 3, etc., with correctChoice numbered accordingly
// (e.g. if first answer is correct, correctChoice is 0)
// if we didn't get a correct choice, or if there aren't enough items,
// that's an error
if (this.correct_answer_index == null) {
return "error in pull down answer (no correct answer specified): " + s + "";
} else if (this.choices.length <= 1) {
return "error in pulldown answer (0 or 1 choices specified): " + s + "";
}
// shuffle choices, unless md.never_scramble is true
this.choice_order = new Array();
for (var j = 0; j < this.choices.length; ++j) this.choice_order[j] = j;
if (this.md.never_scramble != "true") {
this.choice_order.shuffle();
}
// deal with error handling...
},
// ========================================
// extend query functions
setQueryData: function(qd) {
this._super(qd);
// for DD queries, if we get query_data, that's the user's answer index
if (qd != "" && qd != null && !isNaN(qd * 1)) {
this.user_answer_index = qd * 1;
}
},
restoreAnswerFromARGA: function(answer) {
// find the choice that the user gave
for (var i = 0; i < this.choices.length; ++i) {
if (this.choices[i] == answer) {
this.user_answer_index = i;
return;
}
}
},
getQueryTypeForARGA: function() {
return 'drop-down';
},
getCorrectAnswerForARGA: function() {
return this.choices[this.correct_answer_index];
},
getUserAnswerForARGA: function() {
if (this.user_answer_index == null || this.choices[this.user_answer_index] == null) {
return 'Not answered';
} else {
return this.choices[this.user_answer_index];
}
},
// mode should be "delivery" or "review" or "review_correct_incorrect"; "delivery" is assumed
getHTML: function(mode) {
var html = "";
// DD's never have query text
// Start a nobr tag for the item
html = '';
// if we're in preview mode or
// (a student answer has been given and we're not in review_correct_incorrect mode),
// or the student got it correct
// disable the select
var disabled = "";
if (mode == 'preview' || (mode != 'review_correct_incorrect' && this.user_answer_index != null) || this.isCorrect()) {
disabled = "disabled";
}
html += ''
html += this.finish_inline_query(this.choices[this.correct_answer_index], mode);
// Close off the nobr tag for the item
html += '';
return html;
},
evaluateAnswer: function() {
// get the user's selected answer, which will be 0-based
this.user_answer_index = $('#query_answer_' + this.query_index).val() * 1;
// set grade accordingly (if this.md.no_correct_answer is true, any answer is correct)
if (this.user_answer_index == this.correct_answer_index || this.md.no_correct_answer == "true") {
this.setGrade(100);
} else {
this.setGrade(0);
}
return true;
}
});