var Activity_ays = Activity_manuscript.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
safe_log(player.get_current_section_jq().find(".next_section_button").attr("role"));
player.get_current_section_jq().find(".next_section_button").show();
//STG set focus on continue butotn, so 'continue' button shows up in the window, not below
$('button.next_section_button').focus();
//insert any variables that may be newly displayed in the question feedback
player.show_variables();
//move the feedback into a nice popup
$("[data-question_index=" + question_index + "]").find(".query_mc_feedback_correct_incorrect").dialog({
buttons: [{
text: "OK",
click: function () {
$(this).dialog("close");
}
}]
});
//look for any advanced answer choice feedback and show it as a dialog
// player.process_question_feedback_conditional_display();
$("#next_button2").show();
return false;
},
});
var Player_ays = Player_manuscript.extend({
model: {},
update_section_status: function(){
this._super();
player.show_variables();
//handle the next button;
var section = this.get_current_section_jq();
if (section.find("[data-type=question]").length > 0) {
$("#next_button2").hide();
} else {
//make sure its not the last section
if (player.get_current_section() < player.sections.length) {
$("#next_button2").show();
}
}
player.process_conditional_display(section);
},
show_navigation: function(){
this._super();
/*var navHtml = UI_Elements.get_button_html({
id: "next_button2",
extra_class: "toolbar_button prev_next_buttons",
label: "Next",
fn: 'player.show_section("next")'
});
*/
//$("[data-type=chapter]").append(navHtml);
//$("#next_button2").button();
},
show_variables: function () {
//look through all the p nodes
var section = this.get_current_section_jq();
var regex = new RegExp("{(.+?)}", "gmi");
$(section).find("p, label, option, table").each(function (index, element) {
var text = $(element).html();
text = text.replace(regex, function (a, b) {
return eval("player." + b);
});
$(element).html(text);
});
},
process_conditional_display: function (section_to_show) {
var h = section_to_show;
player.get_current_section_jq().find("[data-block_type=conditional_display]").each(function (index, element) {
var md = new Metadata({ jq: $(element).children("[data-type=box_inner]").children("[data-type=metadata]") });
var condition = md["display_conditional"];
// alert("condition: " + condition);
if (typeof condition != 'undefined') {
condition = condition.replace(/model/g, "player.model");
condition = condition.replace(/&/g, "\&");
var div = document.createElement('div');
div.innerHTML = condition;
condition = div.firstChild.nodeValue;
if (eval(condition)) {
//if this displayed box has questions, make sure any next_section_button boxes are hidden
if ($(element).children().children("[data-type=question]").length > 0) {
player.get_current_section_jq().find(".next_section_button").hide();
}
$(element).show();
//now run the model updates in the block
// player.initialize_explain(element);
safe_log("condition met");
}
}
});
},
processNextStepConditionals: function (s) {
for (var i = 0; i < s.md["next_step_conditional"].length; ++i) {
var c = s.md.next_step_conditional[i];
if (c.search(/\{(.*)\}\s*\{(.*)\}/) > -1) {
// extract condition, section to show if it's met
c = new Object();
c.condition = RegExp.$1;
c.section_to_show = RegExp.$2;
c.message = $.trim(RegExp.$3);
c.condition = this.processCondition(c.condition);
s.md.next_step_conditional[i] = c;
} else {
safe_log("bad conditional step: " + c);
s.md.next_step_conditional[i] = { condition: "false" };
}
}
},
processModelUpdateConditionals: function (s) {
for (var i = 0; i < s.md["model_update_conditional"].length; ++i) {
var c = s.md.model_update_conditional[i];
if (c.search(/\{(.*)\}\s*(.*)/) > -1) {
// extract condition, section to show if it's met, and optional message
c = new Object();
c.condition = RegExp.$1;
c.updateStatement = RegExp.$2;
c.updateStatement = this.processCondition(c.updateStatement);
c.condition = this.processCondition(c.condition);
s.md.model_update_conditional[i] = c;
} else {
safe_log("bad conditional step: " + c);
s.md.model_update_conditional[i] = { condition: "false" };
}
}
},
processCondition: function (condition) {
// < > in condition
condition = condition.replace(//g, ">");
var div = document.createElement('div');
div.innerHTML = condition;
var condition = div.firstChild.nodeValue;
// substitute for queries in condition...
// query is correct or incorrect
condition = condition.replace(/qq(\d+)\s*==\s*true/g, "qq.queries[$1-1].isCorrect()");
condition = condition.replace(/qq(\d+)\s*==\s*false/g, "!qq.queries[$1-1].isCorrect()");
//check for a certain MC answer
condition = condition.replace(/qqMC(\d+)/g, "qq.queries[$1-1].user_answer_index");
// otherwise assume it's something about query.user_answer
condition = condition.replace(/qq(\d+)/g, "qq.queries[$1-1].user_answer");
// note that everything is going to be a string compare unless the condition includes "*1",
// i.e. qq1*1 < 4
//for update statements, get string value of a MC or DD
condition = condition.replace(/qqMCValue(\d+)/g, "qq.queries[$1-1].choices[qq.queries[$1-1].user_answer_index]");
// now conditions on the entire question -- just allow correct and incorrect
condition = condition.replace(/qq\s*==\s*true/g, "qq.is_correct()");
condition = condition.replace(/qq\s*==\s*false/g, "!qq.is_correct()");
return condition;
},
setModel: function (key, value, loadOnInit) {
if (key.match(/^userAvatar\./)) {
var newkey = key.substring(11, key.length);
player.model.userAvatar[newkey] = value;
} else
if (key.match(/^partnerAvatar\./)) {
var newkey = key.substring(14, key.length);
player.model.partnerAvatar[newkey] = value;
} else
if (key.match(/^avatar\./)) {
var newkey = key.substring(7, key.length);
player.model.avatar[newkey] = value;
} else {
player.model[key] = value;
}
},
initialize: function () {
this._super();
this.activity = new Activity_ays();
}
});
Question = Question.extend({
extract_metadata: function () {
},
extract_metadata: function () {
if (this.jq == null) {
return;
}
this.md.add_from_jq(this.jq.children("[data-type=metadata]"));
player.processNextStepConditionals(this);
player.processModelUpdateConditionals(this);
},
checkModelUpdateConditionals: function (question_index) {
var q_string = "player.activity.questions[" + question_index + "]";
for (var i = 0; i < player.activity.questions[question_index].md.model_update_conditional.length; ++i) {
var c = player.activity.questions[question_index].md.model_update_conditional[i];
var condition = c.condition.replace(/qq/g, q_string);
condition = condition.replace(/model/g, "player.model");
var updateStatement = c.updateStatement.replace(/setModel/g, "player.setModel");
updateStatement = updateStatement.replace(/model/g, "player.model");
updateStatement = updateStatement.replace(/qq/g, q_string);
updateStatement = unescape(updateStatement);
condition = unescape(condition);
condition = condition.replace(/&/g, '&');
if (condition == "else" || eval(condition) == true) {
// if section_to_show is "done", we're done!
safe_log("triggering model update from question");
eval(updateStatement);
}
}
return;
}
});
DD_Query = DD_Query.extend({
user_has_answered: function () {
var x = $('#query_answer_' + this.query_index).val();
if ($('#query_answer_' + this.query_index).val() != -1) {
return true;
} else {
return false;
}
}
});
MC_Query = MC_Query.extend({
user_has_answered: function () {
if (typeof $('input:radio[name=query_answer_' + this.query_index + ']:checked').val() != "undefined") {
return true;
} else {
return false;
}
},
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 += "
";
}
// get a possible feedback string; this fn will take account of mode
html += this.correct_incorrect_feedback(mode, is_correct);
html += "";
return html;
},
correct_incorrect_feedback: function (mode, is_correct) {
var html = "";
// get correct answer as presented to user
for (var i = 0; i < this.choices.length; ++i) {
if (this.choice_order[i] == this.correct_answer_index) {
break;
}
}
// if the question explicitly defines feedback for the user's answer, use it as the feedback
if (this.user_answer_index != null && this.choices_fb[this.user_answer_index] != null) {
html += this.choices_fb[this.user_answer_index];
}
// the correct answer will be highlighted in green, so there's no reason to say anything more.
// now, if we got any feedback, enclose it in a div
if (html != "") {
html = "";
}
return html;
}
});
Essay_Query = Essay_Query.extend({
user_has_answered: function () {
if ($.trim($("#query_answer_" + this.query_index).val() != "")) {
return true;
} else {
return false;
}
}
});
FB_Query = FB_Query.extend({
user_has_answered: function () {
var x = jQuery.trim($("#query_answer_" + this.query_index).val());
if (jQuery.trim($("#query_answer_" + this.query_index).val()) != "") {
return true;
} else {
return false;
}
}
});
player = new Player_ays();