Captivate SCORM 2004 Output, setting up template
<!DOCTYPE HTML> | |
<!-- saved from url=(0014)about:internet --> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<title>@MOVIETITLE</title> | |
<script> | |
// set document.domain property here, if it works for your environment/SCORM implementation | |
// document.domain=""; | |
var CONFIG = { | |
TITLE: "@MOVIETITLE", | |
FILEPATH: "@MOVIENAME", | |
BGCOLOR: "@SKINCOLOR", | |
FPVERSION: "@FlashPlayerVersion", | |
WIDTH: "@MOVIEWIDTH", | |
HEIGHT: "@MOVIEHEIGHT", | |
WMODE: "@WMODEVALUE", | |
TARGET: "CaptivateContent", | |
NOSCORM: "Sorry, but the course is not available at this time (SCORM API not found). Please try again. If you continue to encounter problems, please contact the course administrator." | |
}, | |
flashvars = {}, | |
params = { bgcolor: CONFIG.BGCOLOR, menu: "false", wmode: CONFIG.WMODE }, | |
attributes = { id: "Captivate", name: "Captivate" }; | |
</script> | |
<script src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script> | |
<script src="standard.js"></script> | |
<script src="SCORM_support/scorm_support.js"></script> | |
<style> | |
* { margin: 0; padding: 0; } /* remove all padding and margins on page */ | |
body { text-align: center; background: @SKINCOLOR } | |
</style> | |
</head> | |
<body> | |
<div id="CaptivateContent"> | |
<noscript> | |
This course requires JavaScript to be enabled in your browser. Please enable JavaScript, then relaunch the course. | |
</noscript> | |
</div> | |
</body> | |
</html> |
var SCORM_API = null, | |
unloaded = false, | |
isInitialized = false, | |
isTerminated = false, | |
courseStatus, | |
value_store = [], | |
lastCommand, | |
setValueWasSuccessful = true, | |
CaptivateSWF; //Cache the reference to the SWF to avoid future lookups | |
/* | |
cmiCache(property, value) | |
Caches CMI value to help prevent sending duplicate data to LMS | |
Parameters: property (CMI property name), value (CMI value, normally a string) | |
Returns: property value if cached version found, false if not cached. | |
*/ | |
var cmiCache = function(property, value){ | |
//Ensure we have a valid property to work with | |
if(typeof property === "undefined"){ return false; } | |
//Replace all periods in CMI property names so we don't run into JS errors | |
property = property.replace(/\./g,'_'); | |
//If cached value exists, return it | |
if(typeof value_store[property] !== "undefined"){ | |
return value_store[property]; | |
} | |
//Otherwise add to cache | |
if(typeof value !== "undefined"){ | |
value_store[property] = value; | |
} | |
return false; | |
}; | |
/* | |
findAPI(window) | |
Adapted from pipwerks SCORM wrapper | |
https://github.com/pipwerks/scorm-api-wrapper | |
Looks for an object named API in parent and opener windows | |
Parameters: window (the browser window object). | |
Returns: Object if API is found, null if no API found | |
*/ | |
var findAPI = function(win){ | |
var API, | |
findAttempts = 0, | |
findAttemptLimit = 500; | |
while (!win.API_1484_11 && win.parent && win.parent != win && findAttempts <= findAttemptLimit){ | |
findAttempts++; | |
win = win.parent; | |
} | |
API = win.API_1484_11 || null; | |
/* | |
if(!API){ | |
alert("Error finding API. \nFind attempts: " +findAttempts +". \nFind attempt limit: " +findAttemptLimit); | |
} | |
*/ | |
return API; | |
}; | |
/* | |
getAPI() | |
Adapted from pipwerks SCORM wrapper | |
https://github.com/pipwerks/scorm-api-wrapper | |
Looks for an object named API_1484_11, first in the current window's frame | |
hierarchy and then, if necessary, in the current window's opener window | |
hierarchy (if there is an opener window). | |
Parameters: None. | |
Returns: Object if API found, null if no API found | |
*/ | |
var getAPI = function(){ | |
var API = null, | |
win = window; | |
//Look in parent windows first | |
if(win.parent && win.parent != win){ | |
API = findAPI(win.parent); | |
} | |
//Look in opener windows next | |
if(!API && win.top.opener){ | |
API = findAPI(win.top.opener); | |
} | |
//Plateau LMS needs special hand-holding | |
if(!API && win.top.opener && win.top.opener.document) { | |
API = findAPI(win.top.opener.document); | |
} | |
//if(!API){ alert("getAPI failed: Can't find the API!"); } | |
return API; | |
}; | |
var Captivate_DoExternalInterface = function (command, parameter, value, variable) { | |
console.log("Captivate_DoExternalInterface: " +command +", " +parameter +", " +value); | |
var strErr = "true", | |
intercept = false; | |
//Ensure SCORM API was initialized | |
if(!isInitialized){ return; } | |
if(command === "Initialize"){ | |
//We already initialized, just nod politely | |
//and tell the SWF everything is okay! | |
} else if(command === "SetValue"){ | |
if(parameter === "completion_status"){ courseStatus = value; } | |
//Check to see if value is already cached | |
var cached_value = cmiCache(parameter, value); | |
//Only send value to LMS if it hasn't already been sent; | |
//If value is cached and matches what is about to be sent | |
//to the LMS, prevent value from being sent a second time. | |
if(!cached_value || cached_value !== value){ | |
console.log(parameter +"(" +value +") is not cached. Sending to LMS."); | |
strErr = SCORM_API.SetValue(parameter, value); | |
setValueWasSuccessful = (strErr === "true"); | |
} else { | |
console.log(parameter +"(" +value +") has already been sent. Preventing redundant LMS communication."); | |
//Fakin' it for Captivate's sake. | |
setValueWasSuccessful = true; | |
} | |
} else if(command === "Terminate"){ | |
strErr = SCORM_API.Terminate(""); | |
isTerminated = (strErr === "true"); | |
} else if(command === "Commit"){ | |
strErr = SCORM_API.Commit(""); | |
} else if(command === "GetLastError"){ | |
if(lastCommand === "SetValue" && setValueWasSuccessful){ | |
strErr = ""; | |
console.log("Last Get/Set was successful. Preventing pointless GetLastError invocation."); | |
} else { | |
strErr = SCORM_API.GetLastError(); | |
} | |
} else if(value && value.length > 0){ | |
strErr = SCORM_API[command](parameter); | |
} | |
CaptivateSWF.SetScormVariable(variable, strErr); | |
lastCommand = command; | |
return strErr; | |
}; | |
var initializeSCORM = function (){ | |
isInitialized = SCORM_API.Initialize(""); | |
if(isInitialized){ | |
console.log("SCORM initialized. Ready to go!"); | |
courseStatus = SCORM_API.GetValue("cmi.completion_status"); | |
if(courseStatus === "not attempted"){ | |
SCORM_API.SetValue("cmi.completion_status", "incomplete"); | |
} | |
} | |
}; | |
//Used by SWFObject | |
var callbackFn = function (e){ | |
//e.ref is the <object> aka SWF file. No need for getElementById | |
if(e.success && e.ref){ | |
CaptivateSWF = e.ref; | |
CaptivateSWF.tabIndex = -1; //Set tabIndex to enable focus on non-form elements | |
CaptivateSWF.focus(); | |
//Initialze the SCORM API, don't wait for the SWF to do it. | |
initializeSCORM(); | |
} | |
}; | |
var unloadHandler = function (){ | |
if(!unloaded && isInitialized && !isTerminated){ | |
var exit_status = (courseStatus === "incomplete") ? "suspend" : "normal"; | |
SCORM_API.SetValue("cmi.exit", exit_status); //Set exit to whatever is needed | |
SCORM_API.Commit(""); //Ensure that LMS saves all data | |
isTerminated = (SCORM_API.Terminate("") === "true"); //close the SCORM API connection properly | |
unloaded = true; //Ensure we don't invoke unloadHandler more than once. | |
} | |
}; | |
window.onbeforeunload = unloadHandler; | |
window.onunload = unloadHandler; | |
//Initialize SCORM API | |
SCORM_API = getAPI(); | |
//Only embed SWF if SCORM API is found | |
if(SCORM_API){ | |
swfobject.embedSWF(CONFIG.FILEPATH + "?SCORM_API=1.0&SCORM_TYPE=0", CONFIG.TARGET, CONFIG.WIDTH, CONFIG.HEIGHT, CONFIG.FPVERSION, false, flashvars, params, attributes, callbackFn); | |
} else { | |
//Provide a useful error message for the learner. Will only show up if SCORM API is not found! | |
swfobject.addDomLoadEvent(function(){ | |
document.getElementById(CONFIG.TARGET).innerHTML = CONFIG.NOSCORM; | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment