Gerd has posted 5 posts at DZone. View Full User Profile

Dynamic Javascript Loading with zscript and jquery

07.08.2011
| 1792 views |
  • submit to reddit
Since its latest version (2.3.0) the java webframework ztemplates http://www.ztemplates.org comes with a small javascript framework called zscript. This article introduces zscript. It will be followed by another article that describes the integration in ztemplates.

Introducing zscript

zscript is a javascript loading framework aimed at loading scripts dynamically. The advantage of using such a framework is that you don’t have to declare all scripts in the html header but can rely on the framework to load them for you. Thus you don’t have to keep track of which scripts are used on which page.

The usage pattern is as follows:

  1. Define a logical name for your script. Map the name to a url pointing to the script. Do this in a script that is included in all of your pages. Use the API method ‘define’ for this.
  2. In your pages, if you need functionality contained in some script, write a callback method that wraps the usage and tell zscript to call the callback only after all required scripts have been loaded. Use the API method ‘requires ’ for this.

That’s all.

An example

Define scripts:

zscript.define(‘script1’, ‘/js/comp1.js’);

zscript.define(‘script2’, ‘/js/comp2.js’);

zscript.define(‘script3’, ‘/js/comp3.js’);

Now whenever you need the scripts:

zscript.requires([‘script1’, ‘script2’], function(){

script1.method();

script2.do();

});

zscript.requires([‘script3’], function(){

script3.method();

});

zscript API

After including zscript.js to your page you get an object called zscript that has the following public interface consisting of 3 functions:

function define(script, url)

Defines a logical name for a script and maps it to a url from which the script will be loaded if required.

Parameter script is the logical name of your script. You will reference the script under this name in your code.

Parameter url is the url from which the script can be loaded.

function setLoaded(script)

If a script has already been loaded by other mechanisms you can tell zscript to not load it again by calling this function.

Parameter script is the logical name of the script that has already been loaded. You have to define the script first by calling define so zscript knows the logical name.

function requires(scripts, callback)

Specifies that the function callback needs the scripts from the array scripts to be loaded.

Parameter scripts is an array of logical script names. The names must have been defined before using the 'define' api call.

Parameter callback is a callback function with no arguments that contains your code. The callback will be called after all required scripts have been loaded or immediately if all scripts are already loaded.

The callbacks are called in the order in which they have been added to zscript by the requires function.

Use zscript on your page

zscript is based on jquery. To use zscript add the following lines to your head section and don’t forget to adjust the contextPath and jquery version:

 <head>
<script type="text/javascript" src=" your_contextPath/jquery-x.x.x.js"></script>
<script type="text/javascript" src="your_contextPath/zscript.js"></script>
</head>

Please be aware of the browsers cross site javascript restrictions, so this will work only for scripts from the same domain.

Writing a zscript component

 If you write a new javascript component for zscript here's the recommended pattern:

if(typeof user=== 'undefined') { 
var user = function() {
//private area
var loggedIn;

//because helper uses otherComponent, declare the dependency here.
zscript.requires('otherComponent');

function isLoggedIn() {
return loggedIn;
}

function setLoggedIn(loggedInParam) {
loggedIn = loggedInParam;
helper();
}

//helper, not visible from the outside
function helper() {
otherComponent.doSomething();
...
}

//public area containes public methods that can be used from outside
return {
isLoggedIn: function () {
return isLoggedIn();
},
setLoggedIn: function (loggedIn) {
setLoggedIn(loggedIn);
}
};
}();
}

This creates a javascript object called user if it has not already been created. The returned object has 2 methods, isLoggedIn and setLoggedIn.

The object is a javascript closure, in this case a function that is called and that returns a object. The returned object contains the public methods of your javascript component. In the function body you can define other functions that are not visible from the outside, like helper in the example above.

You should only declare methods in your component, because there is no guarantee when the component is loaded, also the order in which the components are loaded is not defined (random).

Dependencies between javascript components 

If you have dependenencies between your scripts, that means a script that needs another one you should call zscript.requires() with all needed scripts in the function body. In the example above, the function helper calls otherComponent and so otherComponent must be available for user to work. So you should place zscript.requires(['otherComponent']) in the function body of the user component. This is the only thing you are allowed to do here, as there is no guarantee in which order the components are loaded or if the dom tree is available or not.

Download

zscript is Apache 2.0 licensed and can be found at http://www.ztemplates.org/zscript or bundled with ztemplates.

See a followup article on the ztemplates integration.

 

Published at DZone with permission of its author, Gerd Ziegler.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)