2 way communication between content in an IFrame and Storyline

Dec 05, 2019

Hi there, I am new to Storyline and I have been having trouble changing/reading a variable that I created in storyline from an web object containing my content. Anyone have any suggestions? I just can't seem to find any documentation that its will work with Articulate Storyline 360. From what I have gathered online I have tried a few different methods I have noted below but none seem to work. 

iFrame Click Grabs Variable from Parent
Throws error access is denied. Code is in the web object or iframe and is triggered when button is pushed from within in there. Thanks in advance!

function doMyAlert2(){
var someJSVariable = parent.GetPlayer().GetVar(’numberBox’);
alert(’working number = ‘ + someJSVariable
}

iFrame Click Triggers function on Parent from iFrame
Throws error Unable to get property 'frameElement' of undefined or null reference. Code is in the web object or iframe and is triggered when button is pushed from within in there.

window.frame[0].frameElement.contentWindow.doMyAlert();

Added this code to the story_html.html
<script LANGUAGE="JavaScript1.2" SRC="story_content/myJavascript.js" TYPE="text/javascript"></script>

Parent (storyline)click Triggers function in webobject iFrame
Notes: this assumes only one webobject on slide. Currently throws a permission denied error

$('iframe')[0].contentWindow.c3_callFunction("setMyVar",[""+GetPlayer().SetVar("numberBox")+"6000"]);

Parent (storyline)click Triggers function in webobject iFrame
Note this caused code in project to not work. Currently commented out.

$(’iframe’)[0].contentWindow.doMyAlert();

Add this code to the story_html.html
<script LANGUAGE="JavaScript1.2" SRC="story_content/myJavascript.js" TYPE="text/javascript"></script>

9 Replies
Chris Clift

Hi Jürgen

Thanks for responding. Sorry, this answer may be a bit long winded, but I want to ensure that the issue is clearly understood.

Firstly, I should state that I am not a programmer, so can't code off my own back. Where I have succeeded in using JavaScript, it has been by 'magpie-ing' other people's code and then trying to make sense of it and then, if need be, modifying it to my needs.

The issue I have is that I cannot find a clear and easy to follow explanation of what I am trying to achieve and hence cannot find a solution to my issue which is as follows:

In brief, I want a student to complete an interactive emulation, built in SL3, that is embedded as a web object in to a main training package, also build in SL3 and, on completion of the interactive emulation, for the state of a 'Continue' button in the main training package to change state from Hidden to Normal (that bit being easy once I have the variables I need in Storyline). The issue is communication between the embedded web object emulation, which I will now refer to as 'Daughter' and the main training package, which I will refer to as 'Mother, how to achieve this communication between 'Daughter' and 'Mother' and how to ensure it isn't blocked by security protocols inside current browsers.

To elaborate further, the 'Mother' project I am currently working on is (a) quite large and complex and (b) has multiple different 'Daughter' interactive emulations to demonstrate the different operational modes of the equipment. Both the 'Mother' and embedded web object 'Daughter' projects are of different aspect ratio, so I can't just import the emulations into the 'Mother' project, as it would require each 'Daughter' emulation to be modified to fit the new aspect ratio. This would entail a lot of hours and make the 'Mother' project very large indeed, possibly to the point where I may have issues with the 4GB ram limit of the 32 bit SL3 software. It is a requirement that the student cannot continue with 'Mother' until they have successfully completed the 'Daughter' emulation. All parts work in isolation without issue. However, it is this requirement that the student is required to complete each 'Daughter', that is causing the issue.

I understand that there should be a way to code in JavaScript when a 'Daughter' has been completed and then, since it is a web object, to have a JavaScript 'listen' device within the 'Mother' project on the slide in which the 'Daughter' is embed, so that when the 'Daughter' has been completed, the 'Mother' would then be notified, causing the state of the 'Continue' button to change from Hidden to Normal. But despite a lot of research, I have been unable to find a set of instructions I can follow easily, without having to be an expert in JavaScript.

Sorry this has been so long winded, but I understand the resolution should be relatively easy, if you understand and can code efficiently in JavaScript which, unfortunately, I can't.
Hopefully, my explanation has made sense, but please feel free to ask for any additional information. Unfortunately, I can't share any part of the project as it is 'Client Sensitive' and is not for release in the public domain.

I appreciate any help that you may be able to give in this issue and thank you in advance.

Best regards

Chris Clift

Chris Clift

Hi Jürgen, good question (and an interesting read).

There are no external links outside of the direct links to the Daughters themselves, which would all be contained within the published WebObjects folder of the 'Mother', each Daughter having its own subfolder.

The Mother and Daughters will, as one published package, either be hosted on an LMS in SCORM format, where the user has access to the secure hosted network or, in some cases, where there is no direct access to the secure network, the training, in HTML (published for Web) would be hosted locally on a desktop/laptop, so in both cases, unless I am mistaken, they would, under the "Same-origin policy" have come from a single origin.

Jürgen Schoenemeyer

very interesting method to combine several storyline courses

here is a small example how it could work

mother:

  • create a variable for every daughter ("subCourse1" with default value false)
  • set trigger on "variable changes" to do something (here show a layer)

daughter:

here little javascript script for the daugther (here on button click)

var player = parent.GetPlayer();

console.log( "Player", player );

player.SetVar( "subCourse1", true );
  • Daughter: then publish to web and rename "story.html" to "index.html"
  • Mother: import the web object
  • if you publish, you can see the result (a complete copy of the daugther)

VERY IMPORTANT: If you change anything with the daughter, you have to delete the webobject (-> Mother) and reimport it - there is NO automatic update

  • Mother: publish to review360

result:

https://360.articulate.com/review/content/22ca6822-b7d9-4753-8646-64c2230d736b/review

-> daughter: click the button -> sends to "result"
-> mother: receives the "result" -> overlay

and here the link to scorm cloud

https://app.cloud.scorm.com/sc/InvitationConfirmEmail?publicInvitationId=07cc4219-ce67-44f5-bca5-bd9b8929891b

hint:

use the browser console (-> F12) if there are problems with the javascript

in the last line you can see the result of

console.log( "Player", player ); 

if there errors - e.g. wrong "variable name: subCourse2" you get a message

 

Chris Clift

Big shout out to Jürgen Schoenemeyer, you are officially a HERO.

The solution you provided works like a charm. I will test it on the fill model to see if any issues occur but am not expecting any.

All just in time for the Easter Break, which I can now have without worrying how to solve this issue. 

Thanks again.

Chris

🙂