This project has moved and is read-only. For the latest updates, please go here.

Navigation is denied after lesson completion


To see this bug download the SCORM 2004 package:
mini SCORM 2004 - English language from this site.

When you finish one lesson or a test click on the red Quit button.

After that you can navigate to anoter lesson or test but then next navigation to another lesson or test is denied.

It seems to me that the whole concept of waiting till a content is loaded is implemented wrong.

Check the comment in the FramesetMgr.js file about the FM_ReadyStateReceived() function:
...FM_ReadyStateReceived; // decrements the number of times to wait for the content frame

But in fact this function is not called when the content frame is loaded, but when the page Hidden.aspx in the frameHidden is loaded.

When a SCO is changed you set the this.m_waitForContentCount to 2.

Then two posts are made to the LMS through the Hidden.aspx.

The first post is initiated in the FM_Terminate() function:
The second post is initiated in the FM_ContentIsCleared() function:
  • DoPost: commands: TC;
  • DoPost: commandData: 4@C
  • DoPost: dataModelValues: null
After each post when the form is loaded the this.m_waitForContentCount is decreased which means after two posts it is 0 and the navigation is allowed.

Then the uses finishes the study of a SCO and we call the API.Terminate(""); function which calls the FM_Terminate() function which posts:
Therefore when the SCO is changed after previous SCO completion the FM_Terminate() function is not called for the second time and the form is posted only in the FM_ContentIsCleared() function:
  • DoPost: commands: TC;
  • DoPost: commandData: 3@C
  • DoPost: dataModelValues: null
This will keep the this.m_waitForContentCount at value 1 which will deny the further navigation to another SCO.

My solution is:

Do not count the posts that have to be finished in the Hidden.aspx page. Deny the navigation only if a post is in progress:
function FM_ReadyForNavigation()
    this.DebugLog("ReadyForNavigation: Begin. m_waitForContentCount = " + this.m_waitForContentCount); 
    //var isReady = (this.m_waitForContentCount <= 0);
    var isReady = !this.m_postInProgress;
    this.DebugLog("ReadyForNavigation: End. isReady = " + isReady); 
    return isReady;