scorm

Get Scorm test result from inside an iframe (same domain)


My company is getting a scorm test from another company. (scorm schemaversion 1.2)

We are embedded the test in an iframe like this:

<html>
</head>
<iframe src="exam/scormcontent/index.html" name="course">
</iframe>
</html>

This is the test folder structure:

enter image description here

I am new this scorm solution. What we are trying to do is to get the final result of the scorm test (student passed/failed) in the parent html page.

The html page and the scorm are planned to be hosted on the same domain.

P.S: The entire project involves a react app, where at some stage, the user is supposed to do the scorm test, and he will only be allowed to continue if he passed the test. I am not sure if our plan to use iframe is what we should do. I would love to learn if there is a better option.


Solution

  • I have found a way to do it based on this:

    https://github.com/hershkoy/react_scrom

    The idea is to inject javascript code into the iframe (requires that the iframe and the parent are on the same domain).

    The injected javascript code is listening to the button click events, and send a postMessage event to the parent when detects that the course is completed.

       <div id="result"></div>
        <input id="btn" type="button" value="Go to course" name="btnOpenPopup" onClick="OpenNewWindow()" />  
        <iframe style="display:none;" id="myiframe" src="http://localhost/training/content" name="course" frameborder="0" style="overflow:hidden;height:100%;width:100%" height="100%" width="100%"></iframe>
    
        <script type="text/javascript">  
    
            const iframe = document.getElementById('myiframe');
            const iframeWin = iframe.contentWindow || iframe;
            const iframeDoc = iframe.contentDocument || iframeWin.document;    
    
            function OpenNewWindow()  {  
                iframe.style.display="block";
                document.getElementById('result').innerHTML = "";
                document.getElementById('btn').style.display="none";
             }  
    
            function injectThis() {
                //alert("hi!");
                document.addEventListener('click', (event) => {
                   console.log("click!");
    
                   let chk_condition = event && 
                      event.target && 
                      event.target.href && 
                      event.target.href.includes("exam_completed");
    
                   if (chk_condition) {
                      event.preventDefault();
                      event.stopPropagation();
                      window.parent.postMessage({type: 'course:completed'}, '*');
                      //window.close();
                   };
                }); 
             };
    
             window.addEventListener('message', event => {
                // IMPORTANT: check the origin of the data! 
                if ( true /*event.origin.startsWith('http://localhost:3002')*/) {
                    // The data was sent from your site.
                    // Data sent with postMessage is stored in event.data:
                    console.log(event.data);
                    if (event.data.type=="course:completed"){
                        iframe.style.display="none";
                        document.getElementById('result').innerHTML = "TEST PASSED!";
                    };
    
                } else {
                    // The data was NOT sent from your site! 
                    // Be careful! Do not use it. This else branch is
                    // here just for clarity, you usually shouldn't need it.
                    return;
                }
            });
    
    
            var script = iframeDoc.createElement("script");
    
            script.append('window.onload = ' + injectThis.toString() + ';');
            iframeDoc.documentElement.appendChild(script);
                     
        </script>