var Activity_ays = Activity_manuscript.extend({
// brb: Fixes bug for questions with more than 30 queries. Previously,
// only the first 30 queries would be restored.
brb_get_query_number: function(question, query_index) {
var n = this.get_question_number(question);
// if the question has more than one query, add a sub-index
if (question.queries.length > 1) {
if (query_index < 31) {
n += String.fromCharCode(97 + query_index); // 97 is "a"
}
else {
n += "%" + (97 + query_index).toString(16).toUpperCase();
}
}
return n;
},
// brb: storing both original grade and learner response in questionData
ARGA_set_query_response: function(q, query_number, query_weight) {
// return if ARGA isn't running
if (!player.ARGA_running) return;
safe_log("ARGA_set_query_response");
// set arga response
// note that we send the original grade in questionData so we can get it back when the user returns
var new_question_data = q.getOriginalGrade() + "::" + this.encode_for_ARGA(q.getUserAnswerForARGA());
safe_log(new_question_data);
Set_ARGA_Question_Response({
questionNum:'' + query_number,
questionType:q.getQueryTypeForARGA(),
questionText:this.encode_for_ARGA(q.getQueryTextForARGA()),
correctAnswer:this.encode_for_ARGA(q.getCorrectAnswerForARGA()),
learnerResponse:"N/A",
questionGrade:q.getGradeForARGA(),
questionWeight:query_weight,
questionData:new_question_data
});
},
// This function goes through all questions (from all sections)
// and restores answers from previous sessions that are retrieved via ARGA.
// The function needs to be kept "in synch" with submit_question, so that everything
// done in submit_question gets done here.
restore_saved_answers: function() {
// skip page queries (questions[0])
for (var i = 1; i < this.questions.length; ++i) {
var question = this.questions[i];
// prepare for question_report_text questions
var query_responses;
if (question.md_set("question_report_text")) {
query_responses = "" + Get_ARGA_QuestionData(this.get_question_number(question))
query_responses = query_responses.split(this.query_responses_separator);
}
var restored_all_answers = true;
var all_answers_correct = true;
for (var j = 0; j < question.queries.length; ++j) {
var query = question.queries[j];
var saved_answer, saved_grade;
// get saved answer and grade out of the questionData for question_report_text questions
if (question.md_set("question_report_text")) {
if (query_responses[j] != null) {
var arr = query_responses[j].split(this.query_responses_grade_separator);
saved_answer = arr[0];
saved_grade = arr[1];
} else {
saved_grade = saved_answer = "";
}
// or out of learnerResponse / questionData for single-query questions
} else {
// brb: use new get_query_number so we don't run into
// the over 30 query bug
var ARGA_question_number = this.brb_get_query_number(question, j);
saved_answer = Get_ARGA_LearnerResponse(ARGA_question_number);
// we stored the original grade in questionData
saved_grade = Get_ARGA_QuestionData(ARGA_question_number)
// if saved_grade is of the form
//
// grade::learnerResponse
//
// split this into an array
if (/::/.test(saved_grade)) {
var q_data = saved_grade.split("::");
saved_grade = q_data[0];
saved_answer = q_data[1];
}
}
// if we found a grade...
if (saved_grade !== "" && saved_grade >= 0) {
// restore the answer
query.restoreAnswerFromARGA(saved_answer);
query.setGrade(saved_grade);
// then re-render the query in review mode
query.jq.html(query.getHTML("review"));
if (query.isCorrect() == false) {
all_answers_correct = false;
}
} else {
restored_all_answers = false;
}
}
if (restored_all_answers) {
// update the submit div for the question
this.update_question_action_div(i);
// Show appropriate feedback. If the question responses were submitted,
// the student must have finished the question, so we don't have to worry
// about hints.
this.show_question_feedback(question, all_answers_correct, false);
// if the item is in a sequence, show the next question
this.show_next_question(question);
// NEED TO CHECK TO MAKE SURE THIS IS WORKING PROPERLY
// If the question is in a sequence and the sequence is complete, call show_closing_material
var qs = question.question_sequence;
if (qs != null && qs.sequence_complete == "partial") {
this.show_closing_material(qs.index);
}
// update section status
player.update_section_status();
}
}
// brb
if (player.ACTIVITY_COMPLETED) {
$("[data-type='question']").each(function() {
var q_idx = $(this).attr("data-question_index");
player.activity.questions[q_idx].checkModelUpdateConditionals(q_idx);
});
player.show_variables();
}
},
show_grade_saved_message: function() {
// if the user has answered all queries AND the user hasn't been told this already,
// tell them now
if (player.activity.answered_all_queries && !player.user_has_received_completion_alert) {
//set_scroll_for_modal();
//setTimeout('Standard_Dialog.alert("You have completed the scale, and your score is available on the next screen.");', 20);
Standard_Dialog.alert("You have completed the scale, and your score is available on the next screen.");
setTimeout("set_scroll_for_modal();", 400);
player.user_has_received_completion_alert = true;
}
},
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 queries = player.activity.questions[question_index].queries;
var allQueriesAnswered = true;
for ( var i = 0; i < queries.length; i++ ) {
if ( !queries[i].user_has_answered() ){
allQueriesAnswered = false;
}
}
if (!allQueriesAnswered) {
Standard_Dialog.open("
Please answer all of the questions before submitting.
",{
from: this,
modal: true,
buttons: [{
text: "OK",
click: function () {
Standard_Dialog.close();
}
}]
});
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);
//check if we need to show the next button
player.get_current_section_jq().find(".next_section_button").show();
// show text after submitting
var curSection = player.get_current_section();
var lastSectionIndex = player.sections.length - 1;
var submitMessageDiv = document.createElement('div');
submitMessageDiv.setAttribute('class','submit_message');
if( curSection.index != lastSectionIndex ) {
Standard_Dialog.open("
You have completed the scale, and your score is available on the next screen.
", {
from: player.sections[player.section_currently_showing].jq.find('.next_button'),
modal: true,
buttons: [{
text: "OK",
click: function () {
Standard_Dialog.close();
}
}]
});
}
//STG set focus on continue button, 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();
// calculate score
player.activity.calculate_score(curSection, question_index);
player.FIRST_TIME_THROUGH = true;
$(".next_button").show();
return false;
},
calculate_score: function(curSection, question_index) {
//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");
}
}]
});
var feedback = document.querySelector(".question_feedback_part");
if( feedback ) {
feedback.setAttribute("tabindex", "0");
var feedbackAriaLabel = feedback.textContent;
feedback.setAttribute("aria-label", feedbackAriaLabel);
}
},
is_instructor: function() {
return ( player.ARGA_running && Get_ARGA_Data('user_rights') == '3_instructor' || player.instructor );
}
});
var completeVideo = false;
var Player_ays = Player_manuscript.extend({
ACTIVITY_COMPLETED: false,
DUE_DATE_HAS_PASSED: false,
FIRST_TIME_THROUGH: false,
model: {},
tab_selected: function (event, ui){
safe_log("tab_selected");
// we don't actually use event;
// it's just there because it's part of the standard jquery ui fn prototype
$('[data-type=chapter]').attr('tabindex', '-1');
$('[data-type=chapter]').attr('aria-label', '');
var current_section = null;
if (player.section_currently_showing !== null) {
current_section = window.player.sections[player.section_currently_showing];
}
var section_to_show = ui.index;
// If user has to view sections in sequence and hasn't gotten up to this one, don't allow it
// brb: if activity has been completed then we don't need to test
// for this
if ( section_to_show > player.last_available_section && !player.ACTIVITY_COMPLETED) {
// Let pass through
if ( player.activity.is_instructor() || player.md.sequenced_sections !== "true" ) {
Standard_Dialog.open("Please note: Students need to read and complete each section of the activity before moving on to the next section. " +
"Instructors, however, can skip around between sections as they choose.");
}
else {
Standard_Dialog.open(player.md.section_sequence_message);
return false;
}
}
var videoSection = player.get_current_section_jq().find("[data-block_type=video-container]").length > 0;
// brb: if activity has been completed then we don't need to test
// for this
if ( videoSection && !completeVideo && !player.ACTIVITY_COMPLETED) {
if ( player.activity.is_instructor() || player.md.sequenced_sections !== "true" ) {
Standard_Dialog.open("Please note: Students need to read and complete each section of the activity before moving on to the next section. " +
"Instructors, however, can skip around between sections as they choose.");
}
else {
Standard_Dialog.open("You will be able to move to the next screen after you have watched the video!");
return false;
}
}
player.section_currently_showing = section_to_show;
// process iframes for the section, unless all were preloaded
if (player.md.preload_all_iframes != "true") {
player.figures.process_iframes(player.get_current_section().jq); // iframes
}
player.hide_section(current_section);
player.show_section_animate(section_to_show);
player.update_section_status();
player.update_navigation();
if( videoSection ) {
var figureId = $( '#digfir_section_0 [data-type="figure"]' ).data( 'figure-id' );
var videoPlayer = brightcove.api.getExperience( figureId );
var playerModule = videoPlayer.getModule( brightcove.api.modules.APIModules.VIDEO_PLAYER );
playerModule.pause();
}
window.scrollTo(0, 0);
resize_iframe();
},
hide_section: function (section) {
'use strict';
if (section && section.md.section_type && window.mheAYS[section.md.section_type]) {
if (window.mheAYS[section.md.section_type].hide) {
window.mheAYS[section.md.section_type].hide(section);
}
}
},
show_navigation: function () {
// this._super(); return;
var title = "
Check Your Health
";
var html = "
"
// + "
" + title + "
" + this.md.activity_type_title + "
"
+ "
" + title + "
" + this.md.activity_type_title + "
"
+ "
"
;
for (var i = 0; i < this.sections.length; ++i) {
var s = this.sections[i];
html += "
"
;
// also insert a "next" button at the bottom of each section, unless it's the last one
if (i < this.sections.length - 1) {
s.jq.append("
");
}
}
html += "
";
var self = this;
$("[data-type=chapter]").prepend(html).tabs({
select: self.tab_selected,
fx: {opacity: 'toggle', duration: 100}
});
var LEFT_ARROW_KEY = 37;
var RIGHT_ARROW_KEY = 39;
var CustomTabs = function( $jq ) {
this.$jq = $jq;
this.$li = $jq.find('li a');
this.index = 0;
// Disable all tabindex attr on $jq
this._disableAll();
this.$jq.attr('role', 'tablist');
this.$li.attr('role', 'tab');
// Attach listeners
var cTabs = this;
this.$li.click( function(){
if ( cTabs.stopEvents ) {
return false;
}
cTabs._disableAll();
// Get index of node was clicked by
var index = cTabs.$li.index( this );
cTabs.setMenuActive( index, true );
});
this.$li.keydown( function( event ){
var key = event.keyCode;
var l = cTabs.$li.length;
var newIndex = cTabs.index;
var changes = false;
if ( key === LEFT_ARROW_KEY && cTabs.index >= 1 ) {
--newIndex;
changes = true;
}
if ( key === RIGHT_ARROW_KEY && cTabs.index < l - 1 ) {
++newIndex;
changes = true;
}
if ( changes ) {
cTabs.setMenuActive( newIndex );
}
});
$(".next_button").click( function() {
var newIndex = cTabs.index;
++newIndex;
cTabs.setMenuActive( newIndex );
});
// Set first menu as active element
this.setMenuActive( 0 );
};
CustomTabs.prototype.setMenuActive = function( index, fake ) {
var cTabs = this;
this.stopEvents = true;
this.prevIndex = this.index;
this.index = index;
this.$li[this.prevIndex].setAttribute('tabindex', '-1');
this.$li[this.index].setAttribute('tabindex', '0');
this.$li[this.prevIndex].setAttribute('aria-selected', 'false');
this.$li[this.index].setAttribute('aria-selected', 'true');
if ( !fake ) {
this.$li[this.index].click();
}
if ( this.index <= player.last_available_section ) {
this.$li[this.index].focus();
} else {
Standard_Dialog.onceCallback = function(){
cTabs.setMenuActive( cTabs.prevIndex, true );
}
}
this.stopEvents = false;
};
CustomTabs.prototype._disableAll = function(){
$.each( this.$li, function( index, node ) {
node.setAttribute('tabindex', '-1');
node.setAttribute('aria-selected', 'false');
} );
};
//var $tabs = $("li.ui-state-default a");
var $tabs = $("#activity_top ul");
new CustomTabs( $tabs );
player.tab_jq = $("[data-type=chapter]");
},
show_section: function (section_to_show) {
safe_log("show_section");
if (section_to_show == "previous") {
section_to_show = this.section_currently_showing - 1;
} else if (section_to_show == "next") {
section_to_show = this.section_currently_showing + 1;
}
if (section_to_show == null || isNaN(section_to_show) || section_to_show < 0 || section_to_show >= this.sections.length) {
return;
}
// callling jquery ui's tabs() here will call tab_selected below,
// which will take care of calling update_section_status and updating
// the navigation (in this case, showing the right tab).
player.tab_jq.tabs("select", section_to_show);
// but for some reason tab_selected isn't running properly when we first start,
// so make sure player.section_currently_showing got updated
if (player.section_currently_showing != section_to_show) {
player.section_currently_showing = section_to_show;
// and call update_section_status in this case too
player.update_section_status();
}
// process iframes for the section, unless all were preloaded
if (player.md.preload_all_iframes != "true") {
this.figures.process_iframes(this.get_current_section().jq); // iframes
}
var videoSection = player.get_current_section_jq().find("[data-block_type=video-container]");
var videoPlayer, playerModule;
if( videoSection.length > 0 && !completeVideo ) {
var figureId = $( '#digfir_section_0 [data-type="figure"]' ).data( 'figure-id' );
var ready = false;
var timerId = setInterval( function() {
var refreshIntervalId = setInterval( function() {
if( brightcove.api.getExperience(figureId) ) {
videoPlayer = brightcove.api.getExperience(figureId);
ready = true;
clearInterval(refreshIntervalId);
}
}, 1000);
if( ready ) {
playerModule = videoPlayer.getModule( brightcove.api.modules.APIModules.VIDEO_PLAYER );
playerModule.addEventListener( brightcove.api.events.MediaEvent.COMPLETE, function() {
completeVideo = true;
$(".next_button").show();
$(".next_button").focus();
} );
clearInterval(timerId);
}
}, 1000 );
}
if( !videoSection ) {
var figureId = $( '#digfir_section_0 [data-type="figure"]' ).data( 'figure-id' );
videoPlayer = brightcove.api.getExperience( figureId );
playerModule = videoPlayer.getModule( brightcove.api.modules.APIModules.VIDEO_PLAYER );
playerModule.pause();
}
var ddSelect = player.sections[section_to_show].jq.find('.query_dd_select');
var isTable = player.sections[section_to_show].jq.find('table');
if( ddSelect.length > 0) {
$('.query_dd_select').each( function() {
var $p, pID, pText;
if ( isTable.length > 0 ) {
$p = $(this).parent().parent().prev('td').find('p')
} else {
$p = $(this).parent().parent().find('p');
}
pID = $p.attr('id');
pText = $p.text();
//$(this).attr('aria-describedby', pID);
$(this).attr('aria-label', pText);
} );
}
resize_iframe();
},
/* brb: We are overriding this method in order to keep the activity from
updating ARGA if the activity has been completed so that it doesn't
overwrite a manual grade change in the grade book (see JIRA LP-127) */
super_update_section_status: function() {
if (this.section_currently_showing != null && this.last_available_section <= this.section_currently_showing) {
var s = this.get_current_section();
s.all_questions_answered = true;
// if the current section has any questions, see if they've all been answered
var qs_to_check = [];
s.jq.find("[data-type=question]").each(function(index, element) {
var q_index = $(element).attr("data-question_index");
var question = player.activity.questions[q_index];
s.all_questions_answered = s.all_questions_answered && question.is_complete();
if (question.question_sequence != null) {
for (var i = 0; i < qs_to_check.length; ++i) {
if (qs_to_check[i] == question.question_sequence) break;
}
if (i == qs_to_check.length) {
qs_to_check.push(question.question_sequence);
}
}
});
// now check question sequences to make sure they're done too
s.all_question_sequences_completed = true;
for (var i = 0; i < qs_to_check.length; ++i) {
s.all_question_sequences_completed = s.all_question_sequences_completed && (qs_to_check[i].sequence_complete == "complete");
}
if (s.all_questions_answered && s.all_question_sequences_completed) {
this.last_available_section = this.section_currently_showing + 1;
}
}
this.fill_in_previous_query_responses();
// if ARGA is initialized and we need to restore the user to his last position when he returns,
if (this.ARGA_running && player.md.restore_last_viewed_section == "true") {
// if we're viewing a page other than the one currently saved as LVS (last-viewed section)
var lvs = Get_ARGA_Data("LVSX");
if (this.section_currently_showing != null && this.section_currently_showing != lvs) {
// store LVS/LAS to register the last-viewed/last-available page,
// and save ARGA so it gets registered
Set_ARGA_Data("LVSX", this.section_currently_showing);
Set_ARGA_Data("LASX", this.last_available_section);
/* brb: If the activity has not been completed then save LVSX, but if
it has been completed then do not save LVSX because that will also
send the grade to the PX grade book again, overwriting any manual
grade changes the instructor may have made. */
/* brb: also don't want to do this if the due date has passed */
if (!this.ACTIVITY_COMPLETED && !this.DUE_DATE_HAS_PASSED) {
this.activity.ARGA_submit_data(false);
}
}
}
},
update_section_status: function () {
//this._super();
this.super_update_section_status();
player.show_variables();
//handle the next button;
var section = this.get_current_section_jq();
var curSection = player.get_current_section();
// brb: the above are null when we re-enter the activity
if (section === null) {
section = $("#digfir_ebook_0");
curSection = this.sections[0];
this.section_currently_showing = 0;
}
if ( section.find("[data-type=question]").length > 0 ) {
$(section).find(".next_button").hide();
} else if( section.find(".next_screen_button").length == 0 ) {
//make sure its not the last section
$(section).find(".next_button").show();
}
if( curSection.all_questions_answered
&& section.find(".next_screen_button").length == 0) {
$(section).find(".next_button").show();
}
if( section.find("[data-type=question]").length > 0 ) {
var messageNode = document.querySelector(".submit_message_text");
var parent = document.querySelector("#question_action_div_1");
if(messageNode) {
parent.removeChild(messageNode);
}
}
if ( section.find("[data-block_type=video-container]").length > 0 && !completeVideo ) {
$(".next_button").hide();
}
player.process_conditional_display(section);
resize_iframe();
},
show_section_animate: function (section_to_show) {
'use strict';
safe_log("show_section_animate");
// Hide currently showing section
if (this.section_currently_showing !== null) {
this.sections[this.section_currently_showing].jq.hide();
}
this.section_currently_showing = section_to_show;
var section = this.sections[section_to_show];
section.jq.show();
if (section_to_show === 0 && !this.show_in_first_time) {
this.show_in_first_time = true;
$('[data-type=chapter]').focus();
}
else {
section.jq.focus();
}
$('.slide_title').html(section.title);
// Update slide number
$('#slide_number').html('slide ' + ( section_to_show + 1 ) + ' of ' + this.sections.length);
// If this is the first/last section, disabled the previous/next button
if (this.section_currently_showing === 0) {
$('.prev_button').attr('disabled', 'disabled');
}
else {
$('.prev_button').attr('disabled', '');
}
if (section.md.section_type && window.mheAYS[section.md.section_type]) {
if (window.mheAYS[section.md.section_type].show) {
window.mheAYS[section.md.section_type].show(section);
}
}
resize_iframe();
safe_log("section_currently_showing = " + this.section_currently_showing);
safe_log("last section = " + (this.sections.length - 1));
safe_log("FIRST_TIME_THROUGH = " + player.FIRST_TIME_THROUGH);
if (this.section_currently_showing == (this.sections.length - 1) &&
player.FIRST_TIME_THROUGH) {
player.FIRST_TIME_THROUGH = false;
Standard_Dialog.open("You have completed this activity.");
}
},
show_variables: function () {
safe_log("show_variables");
//look through all the p nodes
var section = this.get_current_section_jq();
var regex = new RegExp("{(.+?)}", "gmi");
// old parsed tags is [p, label, option, table]
$(section).find("p, label").each(function (index, element) {
var oldText = $(element).html();
var newText = oldText.replace(regex, function (a, b) {
return eval("player." + b );
});
if ( oldText.localeCompare(newText) !== 0 ) {
var attr = element.getAttribute("aria-label");
if ( attr ) {
attr = attr.replace(regex, function (a, b) {
return eval("player." + b);
});
element.setAttribute("aria-label", attr);
}
$(element).html(newText);
}
});
},
process_conditional_display: function (section_to_show) {
safe_log("process_conditional_display");
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);
}
}
});
setTimeout(resize_iframe, 500);
},
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 = {};
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) {
//console.log(key, value );
if((value - Math.floor(value))!== 0) {
value=value.toFixed(1);
}
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;
}
},
initialize2: function() {
this._super();
safe_log("initialize2");
/*
$("body").click(function() {
safe_log("caught click");
var scroll_to = $(document.body).height() / 2;
$('#fne-content', window.parent.document).animate({ scrollTop: scroll_to }, "fast");
});
*/
if (player.ARGA_running) {
try {
var dejs_arr = ARGA_API.dejs_data;
for (var i=0; iPlease note: The due date for this assignment has now passed. You may review the materials in the activity but you will not be able to submit answers for a grade.");
}
});
// disable all questions
$('[data-type="question"]').each(function() {
var $this = $(this);
$this.find('input[type="radio"]').attr("disabled",true);
$this.find('textarea').attr("disabled",true);
$this.find('input').attr("disabled",true);
$this.find('select').attr("disabled",true);
});
alert("The due date for this assignment has now passed. You may review the materials in the activity but you will not be able to submit answers for a grade.");
}
},
initialize: function () {
this._super();
var main_title = $("[key=activity_type_title]").html();
document.head.querySelector( 'title' ).innerHTML = main_title;
this.activity = new Activity_ays();
this.figures = new AYS_Figures();
if( window.location.search ){
var p = window.location.search.substr( 1 ).split( "=", 2 );
var b = {};
if( p.length === 1 ){
b[p[0]] = "";
} else {
p[1] = p[1].toLowerCase();
b[p[0]] = decodeURIComponent( p[1].replace( /\+/g, " " ) );
}
this.instructor = ( b["role"] === "instructor" );
}
// Manuscript
//var $manuscript = $('#manuscript');
//$manuscript.attr('role', 'application');
// Chapter
var $chapter = $('[data-type=chapter]');
this.silentElement = $('');
$chapter.append(this.silentElement);
// Section
$('[data-type="section"]').attr('tabindex', '0');
$('[data-type="section"]').attr('aria-label', '');
$('[data-type="section"]').attr('role', 'main');
//$('[data-type="section"]').attr('role', 'tabpanel');
var videoSection = $('[data-type="section"]')[0];
var video = $('[data-block_type="video-container"]').find('[data-type="figure"]');
var videoText = videoSection.querySelector("p").innerText;
videoSection.setAttribute('tabindex', '-1');
video.attr("aria-label", videoText);
// Images
//$('[data-block_type="figure_text"]').attr('aria-hidden', 'true');
//$('img').attr('aria-hidden', 'true');
//$('img').attr('alt', '');
//$('img').before('1');
// Tables
$('[data-block_type="question-container"] table').attr('role', 'document');
// Video
var $video = $('[data-block_type="video-container"]').find('[data-type="figure"]');
$video.attr('role', 'application');
//var $question = $('[data-block_type="question-container"]');
//var $query = $question.find('[data-type="query"]');
//$query.attr('role', 'application');
//Source
$('[data-block_type="reference"]').attr('tabindex', '0');
$('li').each( function(i, value) {
$(value).html('• ' + $(value).html());
});
$('[data-onclick_trigger="true"]').attr('role', 'button');
$('[data-onclick_trigger="true"]').attr('tabindex', '0');
player.show_source_buttons();
$('ul').attr('role', 'list');
},
show_source_buttons: function() {
//Show source buttons
var referenceBlock = $('[data-block_type="references"]');
referenceBlock.each( function( i, v ) {
var sourceBtn = document.createElement("button");
sourceBtn.setAttribute("class", "source-btn");
if( $(v).find('p').length > 1 ) {
sourceBtn.innerHTML = "Sources";
} else {
sourceBtn.innerHTML = "Source";
}
var referenceButton = $(v).find('[data-block_type="references_button"]');
referenceButton.append(sourceBtn);
} );
$('.source-btn').click( function() {
var referenceList = $(this).parent().parent().find('[data-block_type="references_list"]');
var curSection = player.get_current_section_jq();
var nextButton = curSection.find('.next_button');
if ( referenceList.is(":visible") ) {
referenceList.hide();
nextButton.css('margin-top', '-38px');
} else {
referenceList.show();
referenceList.attr('tabindex','0');
referenceList.focus();
var top = -referenceList.css('height').match(/\d+/g) - 58;
nextButton.css('margin-top', top + 'px');
//setTimeout( function(){ this.focus(); }, 500 );
}
} );
$('[data-onclick_trigger="true"]').keydown( function( event ){
var key = event.keyCode;
if( key == 13 ){
var referenceList = $(this).parent().parent().find('[data-block_type="references_list"]');
var curSection = player.get_current_section_jq();
var nextButton = curSection.find('.next_button');
if ( referenceList.is(":visible") ) {
referenceList.hide();
nextButton.css('margin-top', '-38px');
} else {
referenceList.show();
referenceList.attr('tabindex','0');
referenceList.focus();
var top = -referenceList.css('height').match(/\d+/g) - 58;
nextButton.css('margin-top', top + 'px');
//setTimeout( function(){ this.focus(); }, 500 );
}
}
});
},
initialize_sections: function () {
var player = this; // define this so it's available inside the below function
var self = this;
$("[data-type='section']").each(function (index, element) {
var jq = $(element);
// establish the section in the sections array; store its jq
var s = player.sections[player.sections.length] = {};
s.jq = jq;
// set the section's index
s.index = index;
jq.attr("data-section-index", index).attr("id", "digfir_section_" + index);
// extract the section's title and number
s.number = jq.find("h2").find("[data-type=number]").html();
s.title = jq.find("h2").find("[data-type=title]").html();
// process page queries for the section
player.activity.process_page_queries_for_section(jq);
++player.section_count;
s.md = new window.Metadata({lowercase_keys: true});
s.md.add_from_jq(s.jq.children('[data-type=metadata]'));
if (s.md.section_type && window.mheAYS[s.md.section_type]) {
var initialize = window.mheAYS[s.md.section_type].initialize;
if (initialize) {
initialize(s);
}
}
});
$('[data-type="query"]').find('.query_mc_choice_radio').each(function () {
// var questionId = $(this).closest('.mc_query_group label:first').attr('id');
var text = $(this).closest('tr').find('td:first p');
// if(text.attr('id') !== questionId) {
// var textId = $(this).attr('id') + '_text';
// text.attr('id', textId);
// }
var textId = text.attr('id');
var labelId = $(this).closest('label').attr('id');
var labelString = textId + ' ' + labelId;
$(this).attr('aria-labelledby', labelString);
});
$('[data-type="query"]').find('.query_dd_select').each(function () {
var text = $(this).closest('tr').find('td:first p');
var label = text.text();
var textId = $(this).attr('id') + '_text';
text.attr('id', textId);
$(this).closest('table').attr('role', 'group');
$(this).attr('aria-labelledby', textId);
$(this).attr('aria-label', label);
});
}
});
Question = Question.extend({
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!
eval(updateStatement);
}
}
return null;
}
});
DD_Query = DD_Query.extend({
user_has_answered: function () {
var x = $('#query_answer_' + this.query_index).val();
return x != -1;
},
getHTML: function (mode) {
var html = this.query_text_html();
var ariaLabel = $(html).text();
if (this.userHasAnswered() || mode == 'review' || mode == 'review_correct_incorrect' || mode == 'preview') {
ariaLabel += ' You already answered this question.';
}
else {
ariaLabel += ' Answer the question and click Submit button.';
}
ariaLabel = ariaLabel.replace(/\"/g, '');
html = html.replace('>', 'aria-label="' + ariaLabel + '" tabindex="0"> ');
// 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 = this.query_text_html();
ariaLabel = $(html).text();
if (this.userHasAnswered() || mode == 'review' || mode == 'review_correct_incorrect' || mode == 'preview') {
ariaLabel += ' You already answered this question.';
}
else {
ariaLabel += ' Answer the question and click Submit button.';
}
ariaLabel = ariaLabel.replace(/\"/g, '');
html = html.replace('>', 'aria-label="' + ariaLabel + '" tabindex="0"> ');
html += '';
html += this.finish_inline_query(this.choices[this.correct_answer_index], mode);
// Close off the nobr tag for the item
html += '';
return html;
}
});
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();
var oldAriaString = html.match(/_{2,20}/g);
if( oldAriaString ) {
$(oldAriaString).each( function(i, value) {
var newAriaString = '' + value + 'blank';
html = html.replace(value, newAriaString);
} );
}
var ariaLabel = $(html).text();
ariaLabel = ariaLabel.replace(/_{2,20}/g, '');
if (this.userHasAnswered() || mode == 'review' || mode == 'review_correct_incorrect' || mode == 'preview') {
ariaLabel += ' You already answered this question.';
}
else {
ariaLabel += ' Answer the question and click Submit button.';
}
ariaLabel = ariaLabel.replace(/\"/g, '');
html = html.replace('>', 'aria-label="' + ariaLabel + '" tabindex="0"> ');
var legendText = this.jq.closest('td').prev('td').text();
// wrap answers in a p tag
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 = "
" + html + "
";
}
return html;
}
});
var AYS_Figures = Figures.extend({
process_media: function() {
// we're not currently using this (jwplayer is not being included)
$("[data-mmtype='mp3']").each(function(index, element) {
var jq = $(element);
var id = jq.attr("data-figure-id");
var mmsrc = jq.attr("data-mmsrc");
// http://www.longtailvideo.com/jw/upload/bunny.mp3
// http://www.youtube.com/embed/CsGYh8AacgY
var src = jq.attr("src");
var attr = jq.attr("data-attr");
if (attr == null) attr = "";
attr = attr.split(/\s*,\s*/);
var params = new Object();
params.width = jq.width();
params.height = jq.height() + 24; // 24 is for the controler at the bottom
params.file = mmsrc;
params.image = src;
params.controlbar = "bottom";
params.screencolor = "ffffff";
params["viral.allowmenu"] = "false";
params["viral.onpause"] = "false";
params["viral.oncomplete"] = "false";
// determine url of flashplayer based on whether we're published or not
if (UI_Elements.in_preview_mode()) {
params.flashplayer = "/js/preview/player.swf";
} else {
params.flashplayer = "js/player.swf";
}
//safe_log(params.flashplayer);
for (var i = 0; i < attr.length; ++i) {
var a = attr[i].split(/\s*=\s*/);
params[a[0]] = a[1];
}
jwplayer(id).setup(params);
});
//AF: this is less than ideal, but i had to make this a global variable so it can be accessed by the video players when they fire the templateloaded event.
// we should look into changing it.
videos.templateReady = function (figureObjectID) {
var KEY_CODES = {
SPACE: 32,
ENTER: 13
};
var vidplayer = brightcove.api.getExperience(figureObjectID);
var experienceModule = vidplayer.getModule(brightcove.api.modules.APIModules.EXPERIENCE);
var playerModule = vidplayer.getModule(brightcove.api.modules.APIModules.VIDEO_PLAYER);
var el = document.querySelector("[data-figure-id="+ figureObjectID +"]");
el.setAttribute( "tabindex", "0" );
el.addEventListener( "keydown", (function( isPlay ) {
return function( evt ) {
var keyCode = evt.keyCode || evt.which;
if( keyCode === KEY_CODES.SPACE || keyCode === KEY_CODES.ENTER ){
if( isPlay ){
playerModule.pause();
isPlay = false;
return;
}
playerModule.play();
isPlay = true;
}
}
})( false ));
var questionSequence = $("#" + figureObjectID).closest('[data-type="figure"]').nextAll('[data-block_type="question_sequence"], [data-block_type="question_sequence_one_at_a_time"]');
questionSequence.each(function (index, element) {
if ($(element).attr("data-block_type") == "figure") {
if ($(element).find(".BrightcoveExperience").size() > 0) { //we have found another video following the current one, so stop
return false;
}
}
var questionSequenceIndex = $(element).attr("question_sequence_index");
var questionSequenceMetaData = $(element).find('[data-type="box_inner"]').children('[data-type="metadata"]').find('[key="cuepoint"]').html();
$(element).hide();
if (questionSequenceMetaData != null) {
var cuePointsModule = vidplayer.getModule(brightcove.api.modules.APIModules.CUE_POINTS);
var CuePointType = brightcove.api.modules.CuePointsModule.CuePointType;
var cuePoints = [{ name: figureObjectID, metadata: questionSequenceIndex, time: questionSequenceMetaData, type: CuePointType.CODE }];
cuePointsModule.addCuePoints(videos[figureObjectID], cuePoints);
videos.question_sequence_to_video_map[questionSequenceIndex] = figureObjectID;
}
});
playerModule.addEventListener(brightcove.api.events.CuePointEvent.CUE, videos.cuePointEvent);
};
videos.cuePointEvent = function (e) {
//get the player - the name property of the cuePoint is set to the ID of the Brightcove experience
//so we can find the player here.
var vidplayer = brightcove.api.getExperience(e.cuePoint.name);
globalPlayer = brightcove.api.getExperience(e.cuePoint.name);
//safe_log("got vid player");
var playerModule = vidplayer.getModule(brightcove.api.modules.APIModules.VIDEO_PLAYER);
//safe_log("got module");
playerModule.pause(true);
//safe_log("paused");
player.show_question_sequence(e.cuePoint.metadata, false);
};
$("[data-mmtype='mov']").each(function(index, element) {
var jq = $(element);
var id = jq.attr("data-figure-id");
var mmsrc = jq.attr("data-mmsrc");
var src = jq.attr("src");
var attr = jq.attr("data-attr");
if (attr == null) attr = "";
attr = attr.split(/\s*,\s*/);
var params = new Object();
for (var i = 0; i < attr.length; ++i) {
var a = attr[i].split(/\s*=\s*/);
params[a[0]] = a[1];
// safe_log("added param " + a[0] + ": " + a[1]);
}
params.autoStart = jq.attr("data-autoplay");
var videoPlayerID = "";
var videoPlayerKey = "";
//if(params.showVideoControls == 'true'){
//AF: This is the video player with playback controls. We are only using this one for right now.
videoPlayerID = "1513003547001";
if(jq.attr("data-playerid")){
videoPlayerID = jq.attr("data-playerid");
}
videoPlayerKey = "AQ~~,AAABXVHBMdE~,bnY9CM55Z1MLPZuidy4KYEC_16wi-U8Q";
//}else{
// videoPlayerID = "1504927982001";
// videoPlayerKey = "AQ~~,AAABXVHBMdE~,bnY9CM55Z1PiqOYprq-NHmUPG2yKZ4U-";
//}
videos[id] = mmsrc;
var BCL = {};
BCL.markup = function (html, data) {
var m;
var i = 0;
var match = html.match(data instanceof Array ? /{{\d+}}/g : /{{\w+}}/g) || [];
while (m = match[i++]) {
html = html.replace(m, data[m.substr(2, m.length-4)]);
}
return html;
};
videos.templateLoad = function(e){
//AF: For now, we are not using captions.
var vidplayer = brightcove.api.getExperience(e);
var CuePointType = brightcove.api.modules.CuePointsModule.CuePointType;
var modExp = vidplayer.getModule(brightcove.api.modules.APIModules.EXPERIENCE);
modExp.addEventListener(brightcove.api.events.ExperienceEvent.TEMPLATE_READY, function (evt) { videos.templateReady(e); });
//captionsModule.loadDFXP(player.md.video_caption_url + videos[e] + ".xml", videos[e]);
//if needed, we can use these events to trigger code upon the success or error of loading captions.
//if there is an error, it fails silently and just doesn't show captions.
//captionsModule.addEventListener(brightcove.api.events.CaptionsEvent.DFXP_LOAD_SUCCESS, onDFXPLoadSuccess);
//captionsModule.addEventListener(brightcove.api.events.CaptionsEvent.DFXP_LOAD_ERROR, onDFXPLoadError);
};
BCL.playerData = { "playerID" : videoPlayerID,
"playerKey" : videoPlayerKey,
"width" : jq.width(),
"height" : jq.height(),
"videoID" : mmsrc,
"autoStart" : params.autoStart};
BCL.playerTemplate = "";
console.log( BCL.playerTemplate );
var playerHTML = "";
playerHTML = BCL.markup(BCL.playerTemplate, BCL.playerData); //replaces placeholders with values
jq.replaceWith(playerHTML);
brightcove.createExperiences();
});
}
});
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;
}
},
getHTML: function(mode) {
var html = "";
// start with the query text, if there is any
html += this.query_text_html();
// determine how big the response blank should be, unless one was specified
var blank_size = this.md.blank_size;
if (blank_size == "" || blank_size == null || isNaN(blank_size * 1)) {
var s = "" + this.correct_answer;
blank_size = (s.length + 2);
}
// if student hasn't answered or we're in preview mode, use an empty string for the input value
var val, disabled;
var fb_string = "";
if (!this.userHasAnswered() || mode == 'preview') {
val = "";
disabled = "";
// otherwise we have an answer, so fill it in
} else {
// make sure we convert double quotes to " for placement in 'value="xxx"' attributes
val = this.user_answer.replace(/\"/g, """);
// also disable the input in this case, if we're not in review_correct_incorrect mode
// or if the user got it right
if (mode != "review_correct_incorrect" || this.isCorrect()) {
disabled = "disabled";
}
}
html += ''
+ ''
;
html += this.finish_inline_query(this.correct_answer, mode);
html += '';
$('.query_fb_input').keypress(function(e) {
if ( !( e.charCode >= 65 && e.charCode <= 90 || e.charCode >= 97 && e.charCode <= 122 )
&& e.charCode ){
return false;
}
});
return html;
}
});
CB_Query = CB_Query.extend({
user_has_answered: function () {
return (jQuery.trim($("#query_answer_" + this.query_index).val()) != "");
},
getHTML: function(mode) {
var html = "";
// CB's never have query text
// 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 checkbox
var disabled = "";
if (mode == 'preview' || (mode != 'review_correct_incorrect' && this.user_answer_index != null) || this.isCorrect()) {
disabled = "disabled";
}
// if user has answered with choice 0, it should be checked, unless we're in preview mode
var checked = "";
if (this.user_answer_index === 0 && mode != 'preview') {
checked = "checked"
}
html += '';
html += this.finish_inline_query(this.choices[this.correct_answer_index], mode);
$('.query_cb').each(function () {
var label = $(this).parent().parent().next('td');
$(this).attr('aria-label', label.text());
});
return html;
}
});
var preventTab = function (dialog, e) {
e = e || window.event;
e.stopPropagation();
if (e.keyCode === 9) { // Tab key
e.preventDefault();
if (e.shiftKey) { // Shift + Tab key
dialog.focus();
}
}
};
var preventShiftTab = function (e) {
e = e || window.event;
if (e.shiftKey && e.keyCode === 9) { // Shift + Tab key
e.preventDefault();
}
};
window.Standard_Dialog.open = function (html, options) {
if (options == null) {
options = {};
}
if (options.width == "auto") {
options.width = null;
}
else if (options.width == null) {
options.width = 400;
}
if (options.modal == null) {
options.modal = true;
}
if (options.resizable == null) {
options.resizable = false;
}
if (options.buttons == "none") {
options.buttons = null;
}
else if (options.buttons == "OK" || options.buttons == null) {
options.buttons = [{text: "OK", click: Standard_Dialog.close}];
}
options.closeOnEscape = false;
options.dialogClass = "noclose";
options.draggable = false;
$("#standard_dialog_div").dialog("close");
$("#standard_dialog_div").remove();
html = "
" + html + "
";
$('body').append(html);
var $dialog = $('#standard_dialog_div');
$dialog.dialog(options);
var dialog = $dialog.parent();
dialog.attr('aria-label', $dialog.text());
dialog.attr('role', 'dialog');
dialog.attr('aria-labelledby', 'standard_dialog_div');
dialog.focus();
var $lastBtn = $('.ui-dialog-buttonset button:last-child');
$lastBtn.attr('aria-label', 'Ok');
$lastBtn.click( function(){
if ( window.Standard_Dialog.onceCallback ) {
if ( options.from && options.from !== $(".next_button") ) {
window.Standard_Dialog.onceCallback = null;
} else {
var f = window.Standard_Dialog.onceCallback;
window.Standard_Dialog.onceCallback = null;
f();
}
}
if ( options.from && options.from != "next" ) {
options.from.focus();
}
});
$lastBtn.bind('keydown', preventTab.bind(this, dialog));
dialog.bind('keydown', preventShiftTab);
};
window.Standard_Dialog.close = function () {
'use strict';
$("#standard_dialog_div").remove();
};
player = new Player_ays();
function resize_iframe() {
safe_log("resize_iframe");
$('body').click();
var iFrame = $('#document-body-iframe', parent.document.body);
var body_height = $(document.body).height();
safe_log(body_height);
iFrame.height(body_height + 30);
$('body').click();
}
function set_scroll_for_modal() {
// get position of ui-dialog
safe_log("set_scroll_for_modal");
var i = 1;
var pos;
while (i < 3000) {
pos = $("div.ui-dialog").position();
if (pos !== null) {
break;
}
i++;
}
if (pos === null) {
return;
}
var scroll_to = pos.top - 150;
safe_log("scrolling to " + scroll_to);
$('#fne-content', window.parent.document).animate({ scrollTop: scroll_to }, "fast");
}