Forum Discussion
How to add jQuery or anyother external Javascript Library to Storyline
As this question pops up every now and then...i created a post i can link too.
A few options to add jQuery to Storyline ( 3, 360... any version ) manually.
You can add these lines to the html that runs your story...
<!--Added jQuery -->
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
<!--END addition -->
Depending on your usage that can be the index.html and/or index_lms.html in the Articulate folder on your computer in either or both the classic and unified folder.
If you choose this approach best to copy the lines of code from online jQuery repository..as you need the proper hash/sha code to ensure its ok. Do this at https://code.jquery.com/
This for sure is the easiest option, ensuring all projects you publish will have jQuery included. Whenever Articulate updates Storyline you have to redo this as the files will be replaced.
Another Approach
Second option is adding jQuery as a Webobject to a specific project.
Basically you add JQuery as a WebObject on a separate slide. Then you load the scripts needed on the first frame. The folder you load needs to have a index.html and all the external scripts you want to load.
As you see in the image below i have all scripts i use in separate folders. And a empty index file to make it loadable as WebObject.
The biggest drawback of using WebObjects is, that when you change anything in your folders, you need to delete the WebObject in Storyline and add it new...as Storyline copies the Webfolder structure internally...and changes wont work unless you actually remove and add it again. So its good practice to only add reusable libraries there.
On the first frame of my course i then load jQuery.
With this script...
var loadedCount = 0;
var amountOfLibs = 1;
var player = GetPlayer();
function loadJSfile(filename, filetype){
if (filetype=="js"){ //if filename is a external JavaScript file
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", filename);
fileref.onload = function() {
loadedCount++;
console.log(loadedCount+" JS / "+filename+' loaded.');
if(loadedCount >= amountOfLibs){
player.SetVar("javascriptsLoaded", true);
}
};
}
else if (filetype=="css"){ //if filename is an external CSS file
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename);
fileref.onload = function() {
loadedCount++;
console.log(loadedCount+" CSS / "+filename+' loaded.');
if(loadedCount >= amountOfLibs){
player.SetVar("javascriptsLoaded", true);
}
};
}
if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref)
}
/*
When we change anything in the scriptFolder this needs to change
*/
var scriptFolder ="story_content/WebObjects/69PeU1oP5RP/";
/*
And lastly we call the functions we want to run
*/
loadJSfile(scriptFolder+"JQUERY/jquery-1.10.2.min.js", "js");
Notice i have a variable amountOfLibs set to 1, thus only loading jQuery. I often use more thirdparty libraries and thus change that to the amount of libraries wanted.
Do watch the line where i set the variable scriptFolder. You need to ensure on first publish this is correct.
I always have a variable called 'javascriptsLoaded' in my files. I set that to true when my libraries are loaded and from then on i can use anything in them.
So adding a trigger to watch that variable to change...
And then calling this:
$(".top-ui-bg").css("background-color", "#FFFFFF00");
$(".area-primary").css("background-color", "#FFFFFF00");
$(".cs-slide-container").css("background-color", "#FFFFFF00");
if (jQuery) {
// jQuery is loaded
console.log("Yeah! JQuery available");
player.SetVar("jQueryAvailable",True);
} else {
// jQuery is not loaded
console.log("Oh my it doesn't Work");
}
The if then check is not really needed, as i know jQuery is loaded at that point, but better be sure.
One thing that is missing in this method. On a resume you skip the first page and jump to another slide in the course and thus miss all initializations. You could add it to the Slide Master, but i dislike that, because that means you have it on every page. One of the reasons i did a feature request for a custom resume page. So you can ensure the proper needed extra libraries are loaded on the custom resume page.
Added a working sample.
- MartinGregsonCommunity Member
Hi there,
This is just what I'm looking for. But, I am struggling to figure out what you mean with some of your points.
What do you mean by "On the first frame"?
How can this be used for "anyother external Javascript Library"?
Many thanks
- MartinGregsonCommunity Member
Where is this HTML file located?
Hi Martin,
I'm happy to chime in! If I'm correct, Math refers to the index.html file found in the \Program Files (x86)\Articulate\360\Storyline\player\unified folder, as shown in Math's screenshot.
Let me know if that helps!
- MartinSinclair-Community Member
Hello!
Revisiting this as I have successfully used it in the past.
Trying again this morning and notice that the latest index.html file now looks different from Math's original screenshot.
Anyone able to help with where to insert the lines listed above? - eloiselerisson-Community Member
Thanks a lot Math! My clients don't have internet connection and that solves it all!
- YanValdes-aea53Community Member
Hi Math, this is Jhonatan!
Is there a way to use Buzz library exporting directly into Review 360?
I saw your comment on this post, but i'm having a hard time tuning in. - AndyCorbin-b10bCommunity Member
Hi Math and everyone else up there.
I'm attempting to place a live webcam that has a button to capture a snapshot of the learner. I've tried using your second option above to access this nifty JavaScript module from Benson Ruan but am having trouble activating it within Storyline. So far, I've managed to activate the JS file as a Webobject as you've described but I'm not having much fun getting it to run.
I did originally try tinkering with this code from Paul Kizilos in this now closed discussion from a few years back but had no luck.
Many thanks in advance for any pointers for how this can be done.
- MathNotermans-9Community Member
Do share an example. Makes it way much easier to troubleshoot.
- Bob_MongioviCommunity Member
What issues would I run into if I were to just copy the content of the external JavaScript file, and just add it to an Execute JavaScript trigger that starts on timeline start? This way no need to call it in or import. And no need to update the story.html file every time you publish.
- MathNotermans-9Community Member
Scope is the big difference. Placing it on a trigger localizes the function to just that trigger. Nowhere else it will be available. Using it as described makes your function(s) globally available everywhere in Storyline.