Why Companies Should Require Vendors to Use SCORM Driver

Simply stated:

Companies should require vendors to develop elearning courses with SCORM Driver.

First, let me provide you a little bit of background information. Working at a large company, we use a wide variety of vendors who also have a variety of development methods for creating custom content courses in Adobe Flash. Previously, if we had a course that needed a minor update, we would need to contact the vendor and have them update it simply because it was cheaper for them to update their course than to take the time and hidden costs for one of us to update the course. In one instance, a vendor irritated us so much that we went to another vendor for them to update the course around SCORM and Java Run-time Environment due to compatibility errors with our Enterprise LMS.

Becoming irritated with this process, I began wondering if there was a way to bring some governance around this to expedite training, reduce the learning curve, enable minor edits on our part, and enable SCORM updating (from SCORM 1.2 to SCORM 2004 eventually to Tin Can API) without being charged here and there for these updates.

So I immediately went back to Scorm.com, which I basically live. Then I determined to dig into SCORM Driver a bit more. This enabled me to create a justification and argument that would require all of our vendors to use SCORM Driver.

What is SCORM Driver?

Scorm.com notes:

Our SCORM Driver dresses your content up to meet the high standards of both SCORM and AICC. As a developer or content author, you can still create learning materials with the subject matter you need, using the technologies you prefer. The Driver quickly outfits that content in the latest SCORM 2004 fashions or any past fashion such as SCORM 1.1, SCORM 1.2, or AICC. It can even be extended to support proprietary standards.

Simply, SCORM Driver provides a mechanism that separates a course and its files from SCORM compliance files.

So what benefits are there to using SCORM Driver?

  1. Single set of JavaScript function calls that support multiple standards. This is incredibly intelligent, and for us developers out there, this is awesome! No more trying to understand someone else’s uncommented code. SCORM Driver makes the proper method of communication based on the standard for you using meaningful function names like SetBookmark() or GetStudentName(). More examples here.
  2. Collaborative Codebase. If you find something that needs to be updated, the developer is responsive and will update the codebase. So far though…nothing has needed to be added to date.
  3. Debugging Tools/Logs. For complex courses using bluetooth technologies and cross-domain, etc., debugging is essential. Scorm.com makes this easy with SCORM Driver.
  4. License. SCORM Driver license enables companies to use it (if they are not selling their online courses) for free for non-commercial use defined as “Commercial use is defined as the distribution of shareable content objects (SCOs) that use the SCORM Driver in exchange for compensation.”
  5. Compatible. AICC, SCORM 1.2, SCORM 2004 2nd-4th Editions, Tin Can API
  6. Vendors. Using a standard like SCORM Driver leaves you open to use multiple vendors and even switching vendors without having to worry about this again. This will enable companies to focus more on content development rather than the “darker side of things,” and forces Vendors to produce better instructionally, sound learning objects. For vendors, using this standard allows you to have a solid codebase to work from improving inefficiencies, providing you with documentation to give to clients, and shortening the learning curve to bring on future developers. Simply, it’s a win-win for both the vendor and the company.

Note: Click links for more information on the SCORM Driver Integration Process, SCORM Driver QuickStart Guide, and the SCORM Driver Documentation (previously known as Extended Content API, RSECA).

How to Get the Student’s Name and More in Flash AS2 from the LMS in a SCORM2004 Articulate Published Course

In my previous post, I talked about How to Get Slides Viewed in a SCORM2004 Published Course in Articulate and How to Get Last Slide Viewed in a SCORM2004 Published Course in Articulate. Besides this information, there is other information that you can get.

As was previously mentioned, we called SCORM2004_GetDataChunk (which calls cmi.suspend_data) to get the slides already viewed and to get the last slide viewed (which, by the way, auto-update every slide).

import flash.external.ExternalInterface;
var getData:Object;
getData= ExternalInterface.call("parent.SCORM2004_GetDataChunk");

If we replace “SCORM2004_GetDataChunk”, we can call other functions (see below). While I haven’t tested all of them, some of them may be of use to you. Not only can get GET these figures, most of them, we can also set. For coding, simply see the SCORM2004Functions.js file in the LMS folder.

  • SCORM2004_GetStudentName() which calls cmi.learner_name.
  • SCORM2004_GetStudentID() which calls cmi.learner_id.
  • SCORM2004_GetBookmark() which calls cmi.location.
  • SCORM2004_GetAudioPlayPreference() which calls cmi.learner_preference.audio_level.
  • SCORM2004_GetAudioVolumePreference() which calls cmi.learner_preference.audio_level.
  • SCORM2004_GetLanguagePreference() which calls cmi.learner_preference.language
  • SCORM2004_GetSpeedPreference() which calls cmi.learner_preference.delivery_speed
  • SCORM2004_GetTextPreference() which calls cmi.learner_preference.audio_captioning
  • SCORM2004_GetPreviouslyAccumulatedTime() which calls cmi.total_time
  • SCORM2004_GetMaxTimeAllowed() which calls cmi.max_time_allowed
  • SCORM2004_DisplayMessageOnTimeout() which calls cmi.time_limit_action
  • SCORM2004_GetPassingScore() which calls cmi.scaled_passing_score
  • SCORM2004_GetScore() which calls cmi.score.raw
  • SCORM2004_GetEntryMode() which calls cmi.entry
  • SCORM2004_GetLessonMode() which calls cmi.mode
  • SCORM2004_GetTakingForCredit()  which calls cmi.credit
  • SCORM2004_GetStatus() which calls cmi.success_status

How to Get Last Slide Viewed in Flash AS2 in a SCORM2004 Published Course in Articulate

In my previous post, I talked about How to Get Slides Viewed in a SCORM2004 Published Course in Articulate. This tutorial talks about how to get the last slide viewed.

import flash.external.ExternalInterface;
var getData:Object;
var lastVewData:String;
var lastVewData2:Array;
var arrVisited:Array;
var sVisited:String;
getData= ExternalInterface.call("parent.SCORM2004_GetDataChunk");
var getData2 :String;
getData2 = String(getData); // outputs string: "viewed=1,2|lastviewedslide=2|0#2##,3,11,1,1,1#0##-1"
lastVewData = getScore2.split("=")[2];
lastVewData2 = lastVewData.split("|",1); // reduces string into an array (lastVewData2[0]) of "2"

So, now I have the last slide viewed for a course published to SCORM2004 in Articulate.

How to Get Slides Viewed in Flash AS2 in a SCORM2004 Published Course in Articulate

So for one of my courses, I could not use the Restricted view because the course branched and I also wanted to allow some controlled branching at any time in case the user selected the wrong branch. Because of this later request, the Restricted Mode in Player Properties was problematic. So, I manually locked each slide using a global variable. However, it only worked if the person completed the course in one sitting. So if they were to break it into two sittings, I needed to retrieve the cmi.suspend_data from the LMS that contained the slides viewed. So with some help at the Articulate forums, I was able to figure it out.

import flash.external.ExternalInterface;
var getData:Object;
var susData:String;
var vewData:Array;
var arrVisited:Array;
var sVisited:String;
getData= ExternalInterface.call("parent.SCORM2004_GetDataChunk");
var getData2 :String;
getData2 = String(getData); // outputs string: "viewed=1,2|lastviewedslide=2|0#2##,3,11,1,1,1#0##-1"
susData = getScore2.split("=")[1];
vewData = susData.split("|",1);
arrVisited = vewData[0].split(","); // reduces string into an array of "1,2"

So, now I have an array (arrVisited) of all the slides viewed for a course published to SCORM2004 in Articulate.

Using XML for Flash ActionScript 2 in Articulate, Part 1

Part 1: Understanding XML in Flash

It’s great to build flash objects/assets that can be used, but the problem with most is that they are not reusable. Yes, the code can easily be copied and pasted again and again; however, the use of XML is extremely easy to use/edit and reduces QA time once the look and feel have been created. However, understanding how ActionScript 2 and XML work is not so easy.

We must first understand the basic XML document and its various names/sections. So let’s create and look at a basic XML file.

<?xml version="1.0" encoding="UTF-8" ?>
<data>
	<slide id="1">
		<Filename></Filename>
		<Title><![CDATA[My Title]]></Title>
		<Notes><![CDATA[Nulla vel tempus nibh? Cras congue, nunc quis tincidunt tincidunt; mauris ipsum posuere libero, sit amet bibendum dui nunc et orci? Morbi in tortor turpis, nec auctor eros. Donec volutpat enim nec purus porttitor ullamcorper. Aenean vehicula enim sit amet leo hendrerit consequat nec eget velit! Phasellus mattis vulputate consequat. Morbi suscipit egestas tellus sit amet cursus! Vivamus commodo dui quis augue pellentesque dapibus. Curabitur vel eleifend diam. Praesent et eros purus, et auctor nibh. Ut dapibus egestas orci. Nam sit amet odio nisl.]]></Notes>
		<navlocked>false</navlocked>
	</slide>
</data>

So what you have here is a basic XML document. It has the following elements:

  • XML declaration (<?xml version=”1.0″ encoding=”UTF-8″ ?>)
  • Root Node (<data>)
  • Child Nodes (<Filename>,<Title>,<Notes>,<navlocked>)
  • Attributes (id=”1″)
  • Sibling Nodes (<Filename>’s siblings: <Title>,<Notes>,<navlocked>)
  • Node Values (eg., the node value of the child node <navlocked> is false)

Root Node
The root node is <data>. If we were to eliminate DATA as the root node, then <slide> would become the root node. One neat thing that flash can do is pull the name of the various nodes. To pull the root node name, simply refer to it as myXML.firstChild.nodeName.

Child Nodes
Probably the most important thing to understand about XML documents is the notion of Child Nodes. All XML files must have a root node followed by child nodes. For Flash, it is also important to know that the first child node is called firstChild and the last child node is called lastChild (and note the camel spelling [myTest, myXML], which is when the second word is capitalized when combined with the first word). In flash, child nodes will be called as followsmyXML.childNodes[0] (note that 0 refers to the first one like an array) or myXML.lastChild or myXML.firstChild. Flash also has a way to simply check to see if child nodes exist, e.g., myXML.firstChild.hasChildNodes(). So trace(myXML.firstChild.hasChildNodes()); will output true.

Attributes
In addition, any node can have attributes. In our example above, has an attribute id="1". id is an attribute and must be followed by an equal sign (=) with the value in quotation marks (“”). In flash and using this example, attributes are called myXML.firstChild.childNodes[0].attributes.id. So firstChild calls , then I direct it to its first child node via childNodes[0] (which again is the first one in the array), then to its attribute, specifically id.

Sibling Nodes
Our example also contains sibling nodes, which are nodes at the same level. Note that root nodes cannot have sibling nodes. Flash has the ability to move across siblings skipping over the children (or childNodes). So, myXML.firstChild.childNodes[0].childNodes[0].nextSibling will basically refer to myXML.firstChild.childNodes[0].childNodes[1]. If you were to trace() it would output: <!--[CDATA[My Title]]-->. There is also a previousSibling function that works the same way.

Node Values
Now, probably most important in regards to data obtained from the XML is the node value. The content within each node is called “node values”. So in our example, the node value of the node <navlocked> is false. In flash would be referred to as myXML.firstChild.childNodes[0].childNodes[3].firstChild.nodeValue.

While XMLs can be much more complicated than this, this is a great place to start. The essential flash elements that are used most often are firstChild, lastChild, childNodes[i] (i being a number), attributes, and nodeValue. Knowing how to navigate in an XML file will do wonders for your flash coding, especially as it relates to dealing with Articulate Studio ’09.

Additional Steps to Creating an Articulate Popup

Recently James Kingsley discussed creating an Articulate Popup using the the Powered by area of the Articulate Player. I just wanted to add in a few comments to help the newbie. First, read/watch this Articulate knowledge article and Screenr to know how to utilize and replace the Articulate Logo.

Second, to make the popup appear and disappear, you will need to add this code:

var helpOn=false;
function showHelp() {
  if (helpOn) {
    whereToLoad.popholder.box.tip_txt.text = "";
    whereToLoad.popholder.box.title_txt.text = "";
    whereToLoad.popholder._visible = false;
    helpOn = false;
  } 	else {
    whereToLoad.popholder.box.tip_txt.text = "Monkeys can stay underwater for 7 minutes!";
    whereToLoad.popholder.box.title_txt.text = "Did You Know?";
    whereToLoad.popholder._visible = true;
  helpOn = true;
  }
}

Or, you can add some more AS to myAlert.swf with a CLOSE button to also initiate this._visible = false;.

Now to set up myAlert.swf, create a AS2 fla file at the size 700×500. Create a box, whatever you’d like it to look like. Convert it to a symbol, movie clip. Name it whatever, but give it an instance name of box. Go inside the box and create two dynamic text fields giving them instance names of tip_txt and title_txt embedding whatever font you wish for it to use exporting it for ActionScript. Then in a new layer add the action that James discussed in his update:

this._visible = false;

Add a Closed Captions Button at the Top of Your Articulate Player

So for one of my courses, I wanted to create an alternative method of presenting closed captions for our elearning course instead of the preferred method that we currently use, which was started back when they were using Articulate 5 and before. So after placing all your closed captions in the notes section of the PowerPoint, simply publish. Then here is a zip file that contains 2 files (art_plugins.xml and cc.swf) that can go in the published PLAYER folder that will create a Closed Caption button at the top, where ATTACHMENTS and EXIT appear. If you are zipping to upload to a LMS, be sure to extract and put these files into the folder before zipping. Though, if you zipped, that’s still not a problem. Simply double-click on the zip file so that WinZip opens it. Double-click on the player folder and drag the files into the WinZip program. Click Add at the bottom, and then the X at the top right.

Closed Captions Button: How It Works
I have my presentation player template set to No Sidebar View, Display Mode = 2. To set this, in PowerPoint, click on the Articulate tab (in 2007/2010), then select Player Templates. Under Layout, select the view modes you want to allow. The default has them all selected. The Standard View must be selected/checked. Set whichever you’d like as your starting mode by selecting it so that it turns blue and then click Set as Starting View.

Closed Captions Button: AS2 Code
For those who like code, I simply took the Test_Tool.fla from the Articulate SDK.

tab="notes";
var displayMode = ArtAPI.GetDisplayMode(); //be sure that this is defined according to the Articulate SDK
var currentTab = _level44.mcSidePanel.mcOutlinePanel.g_strLastActiveId; //thanks to @onEnterFrame
if ((displayMode == 1) && (currentTab == tab)) {
	ArtAPI.SetDisplayMode(2); //be sure that this is defined according to the Articulate SDK
}
else {
	ArtAPI.SetDisplayMode(1);
	_level44.mcSidePanel.mcOutlinePanel.mcTabCtrl.SetSelectedTab(tab);
}

Thanks James for collaborating with me and giving me some code to build this easy Articulate closed captions button! If anyone ever needs someone to do some custom Articulate work for you whether template building or building a custom player, he can do it and more. Check him out at his website and elearningenhanced.com site.