DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
11 Monitoring and Observability Tools for 2023
Learn more
  1. DZone
  2. Coding
  3. JavaScript
  4. Clean Up Your JavaScript with ztemplates and jQuery

Clean Up Your JavaScript with ztemplates and jQuery

Gerd Ziegler user avatar by
Gerd Ziegler
·
Jan. 04, 12 · Interview
Like (0)
Save
Tweet
Share
2.66K Views

Join the DZone community and get the full member experience.

Join For Free

When writing webapps that make heavy use of javascript it gets hard to keep track of the javascript used, especially when the webapp loads content dynamically like in AJAX applications. The problem is that every container page has to be aware of the javascript needed by all the dynamcally loaded component markup.

The problems are:

  • Which javascript must be loaded
  • How to prevent duplicate variable assignments 
  • dependencies between javascript libraries

In such cases a framework for dynamic javascript loading comes handy, because it relieves the container from the need to know what script is needed in the component. The component declares the needed script and is called after the script is available.

This article describes how to write dynamic javascript enabled webapps with the ztemplates java webframework. Beginning with version 2.3.0 ztemplates includes a small javascript library named zscript that makes dynamic JavaScript loading easy. zscript is fully integrated into ztemplates.

See Dynamic Javascript Loading with zscript and jquery published on dzone for a short introduction to zscript.

The library uses jquery, so make sure to include your preferred version.

To use add the following lines to your html head section: 

  <head>
    <script type="text/javascript" src="jquery-x.x.x.js"></script>
    <script type="text/javascript" src="${contextPath}/ztemplates/zscript.js"></script>
    <script type="text/javascript" src="${contextPath}/ztemplates/zscript-definitions.js"></script>
  </head> 


Now for each reusable piece of javascript functionality you want to make available to your webapp add a annotated class and a template containing the javascript. The annotation ensures that ztemplates can find the javascript. ztemplates makes the script available to the zscript library and adds it to zscript-definitions.js

Define a java class and annotate it with @ZScriptDefinition. Provide a name to the annotation. The name must match the name of the variable defined in the javascript snippet. The class-name does not matter, but You may find it useful to name your script classes ZScript_name so you can easily find them.

For example to define a javascript variable (keeping a service object) named 'user' create a java class.

 

@ZRenderer(ZVelocityRenderer.class)
//this defines a javascript object called 'user'
@ZScriptDefinition("user")
public class ZScript_user
{
}

and a javascript template in ZScript_user.vm at the same location as the class:

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

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

This code calls a method and assigns the return value to a variable called user. This happens only if the variable has not already been created. The return value is a collection of functions that are available for calling. The other functions are private.


To use the javascript from your html page write this to your javascript tag:

<script>
zscript.requires(['user'], function(){
   user.setLoggedIn(true);
   if(user.isLoggedIn()){
     alert('logged in!');
   }
});

zscript.requires(['mylib'], function(){
   mylib.doSomething();
});

</script>

This states that the javascript library 'user' is required in the callback body, so pass the name as first parameter to the requires method. The second parameter is a callback that will be called as soon as the 'user' library is available (which could also be immediately if the library has already been loaded).

If the code contains more than one call to zscript.requires() the order in which the callbacks are called is preserved. In the example the callback for 'user' is always called before the callback for 'mylib'.


You may define other javascripts like this:

 

zscript.define('mylib', '/js/mylib.js'); //map the name 'mylib' to the url

ztemplates will ensure the javascript is loaded whenever you use it in a zscript.requires(['mylib'], function(){}) call.

Be aware of the cross-domain restrictions placed upon the locations of your scripts, so best load them from the same server as your html.

Because there is no defined order in which the scripts are loaded at runtime the libraries should not contain logic that references other dynamically loaded libraries:

var user = function() {
    var loggedIn;

    //Declare all the libraries used by this library here, will be executed before requires callbacks
    zscript.requiresInScript(['dialog', 'mylib' ]);
  
    //wrong, mylib may not be loaded
    mylib.doSomething();

    function isLoggedIn() {
                //OK, because dependency has been declared above and call is in function                 mylib.doSomething();
        return loggedIn;
    }
    
    function setLoggedIn(loggedInParam) {
                //OK, as dependency has been declared above.
                dialog.show('Something');
        loggedIn = loggedInParam;
    }    
    
    return {
        isLoggedIn: function () {
            return isLoggedIn();
        },
        setLoggedIn: function (loggedIn) {
            return setLoggedIn(loggedIn);
        }
    };
}();


Note the if(typeof user=='undefined') condition that ensures that the variable is created only once.

Using this pattern you get a clean separation between java, javascript and html and don't have to worry about script tags in your html header markup or duplicate instantiations of variables. All needed javascript is loaded on demand, or if you don't want that you can instruct ztemplates to collect all javascript in zscript-definitions.js

Weblinks:

  • http://www.ztemplates.org the annotation based java webframework.  
  • Dynamic Javascript Loading with zscript and jquery published on dzone for a short introduction to zscript.
JavaScript library JQuery

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • What Is Continuous Testing?
  • A Deep Dive Into AIOps and MLOps
  • An End-to-End Guide to Vue.js Testing
  • Accelerating Enterprise Software Delivery Through Automated Release Processes in Scaled Agile Framework (SAFe)

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: