JavaScript scripting in the browser

At some point, your plugin’s user interface will need to use JavaScript in the browser.

The client side JavaScript is placed in the static directory of your plugin to make it available over HTTP. The full pathname of the file will be different in every application, and vary over time as it’s upgraded. There is no access control on static files, so they can be downloaded by anyone who knows the URL.

To include a <script> tag with the correct pathname, use the std:plugin:resources() template function. For example, if the client side JavaScript file is named userinterface.js, you would include

    std:plugin:resources("userinterface.js")

at the top of your template. This will include the script in the page sent to the browser. It can be placed in any template, and if multiple templates including it are rendered in one request, only one <script> tag will be sent to the browser.

This works whether you’re responding to an HTTP request, or generating some HTML to add user interface to the main application’s pages, such as an Element.

JavaScript Libraries

The standard jQuery and underscore.js JavaScript libraries are included in every page, and so are available by default.

The libraries are updated frequently, so you should assume that updates to the latest version will happen within weeks of their release.

Be careful if you include additional browser JavaScript libraries. If multiple plugins include different versions of the same library on the same page, there may be conflicts.

jQuery global

You must use the jQuery library through the jQuery global, not $. To access it using the $() syntax, use the recommended coding style below.

Coding style

The following coding style is recommended to encapsulate your client side scripting, and avoid clashing with the core Haplo scripting and other plugins.

    (function($) {
        
        // Define a variable, accessible to this script only
        var exampleData = {};
        
        // Define a function, accessible to this script only
        var exampleFunction = function(arg) {
            // ... do something here
            exampleData[arg] = true;
            // ...
        };
        
        // Use jQuery to set an event handler
        $("#example").click(function() {
            // ...
            exampleFunction("ABC");
            // ...
        });
        
    })(jQuery);

An anonymous function is used to encapsulate all the code, and rename jQuery to $ for the encapsulated code only. Because of the encapsulation, you need to use a slightly different syntax for defining functions than you might otherwise use.

Note that underscore.js is available through the _ global without any renaming required.

Syntax checking & minimisation

While you are developing your plugin, the Plugin Tool will check the syntax of the browser JavaScript each time you save the file. While plugins will be accepted with some warnings for browser JavaScript, it’s recommended that you follow the suggestions above.

Browser JavaScript must not have any “'variable' is not defined” warnings, as these indicate issues which may cause scripting to clash. Well tested library code with these warnings may be accepted — get in touch for advice.

In deployment, your browser JavaScript will be minimised to reduce the amount of data sent to the browser. This will remove comments and whitespace, and rename variables to reduce file size. The recommended style is particularly suitable for minimisation, as the encapsulation allows the minimiser to rename all variables.