Skip to content

Adding custom JavaScript

marksreeves edited this page Jan 27, 2016 · 9 revisions

It is possible to add application-specific JavaScript to a WComponents application. Before doing so though one ought consider carefully whether:

  1. the functionality one is trying to implement is already available in the theme; and
  2. if not then should it be added to the theme?

Adding a cacheable JavaScript file

The most efficient way to add CSS is usually using a cacheable script file.

Using WApplication

This is new and not yet in a released version of WComponents (release 1.0.2). If you build from source you will have this method available to you.

WApplication has these methods which may be used to add a script element to the page head element:

  • addJsUrl(String url); and
  • addJsFile(String fileName).

Each of these methods has the same net effect: a HTML script element will be added to the head with the src set to the url or file resource. The script element is placed after the inclusion of WComponents scripts and requirejs configuration and inclusion therefore you should be able to rely on the presence of requirejs and if you build your script as an AMD module you will be able to use WComponents modules.

// Get the WApplication from the current object'
WApplication app = WebUtilities.getAncestorOfClass(WApplication.class, this);

// Then use this WApplication to add JS from a resource.
app.addCssFile("/path/to/resource/my_javascript_file.js");
// Adding from a URL is similar. Use '//'' to avoid defining the protocol.
app.addCssUrl("//example.com/path/to/static_js_file.js");

Using Headers

This method will be deprecated in favour of that outlined above but is available in WComponents 1.0.2 and before. In this case the HTML script element is placed in the body in the position in which it is added to the component tree.

A JavaScript file can be added to an application using com.github.bordertech.wcomponents.Headers.addUniqueHeadLine(String type, String aLine) or com.github.bordertech.wcomponents.Headers.addUniqueHeadLine(String aLine).

One possible method of doing this could be by using WContent and an internal resource :

private final WContent js = new WContent();

// ...

// Add a cache key to css so that it can be cached. This cache key
// can then be changed if there is a need to update the JavaScript.
css.setCacheKey("my.custom.js" + version);

// The resource must be added to the output tree event though it is
// not included in the XML output.
add(js);

// ...

// At some point the css resource must be set up. This could be the
// first time the object to which css was 'added' is painted in
// preparePaintComponent
@Override
protected void preparePaintComponent(final Request request) {
    super.preparePaintComponent(request);

    // ...

    if (!isInitialised()) {

        // ...

       css.setContentAccess(new InternalResource(
                "/path/to/resource/my_custom_script.js",
                "my_custom_script.js"));
        setInitialised(true);
    }

    // ...

    // Finally use addUniqueHeadLine To attach the script
    UIContext uic = UIContextHolder.getCurrent();
    uic.getHeaders().addUniqueHeadLine(
        "<script type='text/javascript' " +
        "src='" + WebUtilities.encode(js.getUrl()) + "'></script>");
}

Adding inline script using WText

WText may be used to output any HTML element(s) including a script element. You must turn off output escaping (doing this is considered harmful) and you are completely responsible for ensuring your HTML snippet is XML compliant. This includes knowing what to escape or enclosing your script in a CDATA block.

// Let us assume we have a JavaScript snippet we want to include and it is in
// a String MY_SCRIPT which should include the script element opening and
// closing tags and a CDATA wrapper if required.
WText jsText = new WText(MY_SCRIPT);
jsText.setEncodeText(false);
add(jsText);

The script element will be echoed to the output stream (HTML) in the position in which it is added to the component tree.

Using templates

WComponents has supported the use of velocity templates for some time and a new templating component is to be launched very soon. Custom JavaScript may be included in a view by adding it to such a template.

Related topics

Clone this wiki locally