Link to home
Start Free TrialLog in
Avatar of rghnaish
rghnaish

asked on

APIWrapper.js is not bookmarking progress to SCORM for users on IE6

We have a flash learning programme that communicates with the SCORM LMS using a standard javascript interface (APIWrapper.js).

For all the users on IE7 or IE8, plus Firefox and Safari, the bookmarking works fine. They do part of the programme, this is recorded on the LMS via this interface, then they logout. When log back in they go back to where they got to in the programme. But for IE6 users, they just go back to the beginning everytime. Very annoying.

I have tested it and if you go through the course using IE8, logout and then log back in using IE6, it can read the bookmarking and find the right place in the course. But for some reason the APIwrapper.js is not working with IE6 and it will not *send* any bookmarking information to the LMS.

Anyone got any clues what it going on here? I am hoping it is a quick fix since all the other browsers work fine.

My programmer is back online at the weekend; I am just trying to get some clues to help him get started. Hence I may have not written like a programmer, apologies.

Avatar of Antonio Estrada
Antonio Estrada
Flag of Mexico image

Well, without having code to look up it's a bit tough to know what could be breaking it.

Could be a script error that's being ignored in IE7 and above but that destroys IE6 (a yellow icon should be seen on the status bar if that's the case).

An "alert" based debugging to know where the script is dying and why it isn't working specifically on IE6.

If everything fails though, I do have a bunch of SCORM wrappers that work fine under IE6... I'm posting the code here:

<code>

Good luck,

-V
var findAPITries = 0; 
var startTime = new Date().getTime();
var endTime = new Date().getTime();
var sessionTime = "";
var LMSInitialized = false;
var API = null;

function findAPI(win) {
	while ((win.API == null) && (win.parent != null) && (win.parent != win)) { 
		findAPITries++; 
		if (findAPITries > 7) {
			alert("Error in finding API -- too deeply nested."); 
			return null;
		}  
		win = win.parent;
	} 
	return win.API;
} 

function callLMSInitialize() { 
	if ((window.parent) && (window.parent != window)) { 
		API = findAPI(window.parent);
	} 
	if ((API == null) && (window.opener != null)) { 
		API = findAPI(window.opener);
	} 
	if (API == null) { 
		alert("No API adapter found");
	} else { 
		API.LMSInitialize("");
		LMSInitialized = true;
	} 
}
function getBookmark() {
	var retVal;
	if(LMSInitialized) {
		retVal = API.LMSGetValue("cmi.core.lesson_location");
		if(retVal == "") {
			retVal = 0;
		}
	} else {
		retVal = 0;
	}
	return(parseInt(retVal));
}
function setBookmark(pag) {
	if(LMSInitialized) {
		API.LMSSetValue("cmi.core.lesson_location",""+pag);
	}
}

Open in new window

Avatar of rghnaish
rghnaish

ASKER

hi Vulturous
I was hoping you would pick this up since I have seen your replies on similar topics...you must be the world expert on this.
I have found a file called api.php, would that be it? I have put the code below. As you can see we have tried a workaround for IE6, but it didn't work.

The status bar is not showing anything at the time this code should be being sent.
thanks
Richard
<?php

    require_once("../../config.php");
    require_once('locallib.php');

    $id = optional_param('id', '', PARAM_INT);       // Course Module ID, or
    $a = optional_param('a', '', PARAM_INT);         // scorm ID
    $scoid = required_param('scoid', PARAM_INT);     // sco ID
    $mode = optional_param('mode', '', PARAM_ALPHA); // navigation mode
    $attempt = required_param('attempt', PARAM_INT); // new attempt

    //IE 6 Bug workaround
    if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 6') !== false && ini_get('zlib.output_compression') == 'On') {
        ini_set('zlib.output_compression', 'Off');
    }

    if (!empty($id)) {
        if (! $cm = get_coursemodule_from_id('scorm', $id)) {
            error("Course Module ID was incorrect");
        }
        if (! $course = get_record("course", "id", $cm->course)) {
            error("Course is misconfigured");
        }
        if (! $scorm = get_record("scorm", "id", $cm->instance)) {
            error("Course module is incorrect");
        }
    } else if (!empty($a)) {
        if (! $scorm = get_record("scorm", "id", $a)) {
            error("Course module is incorrect");
        }
        if (! $course = get_record("course", "id", $scorm->course)) {
            error("Course is misconfigured");
        }
        if (! $cm = get_coursemodule_from_instance("scorm", $scorm->id, $course->id)) {
            error("Course Module ID was incorrect");
        }
    } else {
        error('A required parameter is missing');
    }

    require_login($course->id, false, $cm);

    if ($usertrack = scorm_get_tracks($scoid,$USER->id,$attempt)) {
        if ((isset($usertrack->{'cmi.exit'}) && ($usertrack->{'cmi.exit'} != 'time-out')) || ($scorm->version != "SCORM_1.3")) {
            foreach ($usertrack as $key => $value) {
                $userdata->$key = addslashes_js($value);
            }
        } else {
            $userdata->status = '';
            $userdata->score_raw = '';
        }
    } else {
        $userdata->status = '';
        $userdata->score_raw = '';
    }
    $userdata->student_id = addslashes_js($USER->username);
    $userdata->student_name = addslashes_js($USER->lastname .', '. $USER->firstname);
    $userdata->mode = 'normal';
    if (isset($mode)) {
        $userdata->mode = $mode;
    }
    if ($userdata->mode == 'normal') {
        $userdata->credit = 'credit';
    } else {
        $userdata->credit = 'no-credit';
    }
    if ($scodatas = scorm_get_sco($scoid, SCO_DATA)) {
        foreach ($scodatas as $key => $value) {
            $userdata->$key = addslashes_js($value);
        }
    } else {
        error('Sco not found');
    }
    if (!$sco = scorm_get_sco($scoid)) {
        error('Sco not found');
    }
    $scorm->version = strtolower(clean_param($scorm->version, PARAM_SAFEDIR));   // Just to be safe
    if (file_exists($CFG->dirroot.'/mod/scorm/datamodels/'.$scorm->version.'.js.php')) {
        include_once($CFG->dirroot.'/mod/scorm/datamodels/'.$scorm->version.'.js.php');
    } else {
        include_once($CFG->dirroot.'/mod/scorm/datamodels/scorm_12.js.php');
    }

?>

var errorCode = "0";
function underscore(str) {
    str = String(str).replace(/.N/g,".");
    return str.replace(/\./g,"__");
}

Open in new window

Hah, I wish I were :)

Anyway, in your original post you mention a file called APIWrapper.js. As I understand it, that file is part of the SCORM package you created and the error would appear on every LMS.

That api.php file seems to be part of a LMS that is performing the tracking of the SCORM packages. It shouldn't be an issue there since that file is given to the client after being processed in the server (php = hypertext preprocessor).

Unless the api.php file generates a JavaScript file, it wouldn't be the cause for the issue...

And now the issue is that I'm confused, not sure if the error happens in an LMS you built, or in a SCORM package and the communication breaks in every LMS.

-V
Another thing, if that api.php file does generate a JavaScript file, can you post the result of it?

As in... the actual JavaScript that is delivered to the client (that way I can run some tests and see why it's breaking on IE6).

-V
hi Vulturous
I am on GMT hence the delay in replying.
I can't find this APIwrapper.js file in all the files on the website. I will have to ask my developer.

The LMS itself is an off-the-shelf Moodle LMS and so should work fine and not have issues.

I have run MS script debugger while in IE6 and I can see no javascrip code being generated as the e-leanring course passes 'bookmarking points' where the course is meant to tell the LMS that they have got to this point. So this means the javascript is not working?
cheers
Richard
ASKER CERTIFIED SOLUTION
Avatar of Antonio Estrada
Antonio Estrada
Flag of Mexico image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
thanks, I think we are on to a solution now....which I'd like to share with the community...

It seems that the function that calls the javascript scorm functions doesn’t work in IE6 if you call more than one function at a time. So it can save and retrieve the data but when you ask it to do more than one thing at a time it fails in IE6. Since when we save data we call a function to save it then immediately after call another function to commit the data the whole thing was failing in IE6. So we’ve changed the function that calls the javascript scorm functions.
It seems that IE6 cannot multi-task!

thanks very much for your help, Vulturous, I will give you the points for all your help.
thanks, I think we are on to a solution now....which I'd like to share with the community...

It seems that the function that calls the javascript scorm functions doesn’t work in IE6 if you call more than one function at a time. So it can save and retrieve the data but when you ask it to do more than one thing at a time it fails in IE6. Since when we save data we call a function to save it then immediately after call another function to commit the data the whole thing was failing in IE6. So we’ve changed the function that calls the javascript scorm functions.
It seems that IE6 cannot multi-task!

thanks very much for your help, Vulturous.
Very interesting... as far as I know, JavaScript doesn't multi-task at all, it starts a thread and does it in a linear fashion unless you're using "eval".

But hey... maybe IE6 does something odd (that browser could very well be the devil) and prevents the execution of one of the functions.

I'm glad you got it sorted and thanks a lot for the points!

-V