Jul 292013
 

OpenText Content Server ships with an outdated version of jQuery (v1.3.2; released February 2009). The library is loaded in the “commonheader.html” file, which means it appears in almost every page in Content Server. Any WebReport or module that uses the standard header will have this version of jQuery forced onto the page. While this might suffice for simple operations in a WebReport or module, it can be limiting when a newer version of jQuery is required.

Unfortunately, you can’t just reference a newer version of jQuery in your page. This will cause all menus to break since they rely on the version supplied with Content Server. Fortunately, jQuery provides a way to have multiple instances of jQuery in a page. It can be confusing if you’re not familiar with variable scoping in Javascript, so here’s a recipe and an explanation of how it works.

<script src="/img/yourmodule/jquery-1.10.2.min.js"></script>
<!-- Load your jQuery plugins here -->

<script>
    // This could also go in an externally referenced .js file
    $(document).ready(function($) {
        // your code here
        // all variables should be locally defined
        // jQuery accessed via the $ alias
    });
</script>

<script>$.noConflict(true);</script>

Let’s break it down.

The first line adds the newer version of jQuery to the page and sets the jQuery and $ global variables (i.e., window.jQuery and window.$) to the v1.10.2 instance.

The second line is where jQuery plugins can be loaded (e.g., jQuery-ui). Plugins must not reference the global jQuery or $ variables since these variables will be later set back to the original version (i.e., v1.3.2). Fortunately, most third party jQuery plugins are written to access the global instance of jQuery that was valid when the plugin was imported (as opposed to the global instance that is valid when the plugin is executed). See the section “Protecting the $ Alias and Adding Scope” on How to Create a Basic Plugin for details.

Lines 7-9 is where you add your custom code and do any jQuery bindings to your DOM elements. This code is wrapped in an anonymous function that gets executed by $(document).ready() once the DOM has finished loading. It’s important that variable scope be restricted to the anonymous function. This will ensure your variables and functions don’t clobber any of the many globals that Content Server defines. It also ensures that no other variable or function can clobber your code. It’s just good practice. For example:

$(document).ready(function($) {
    // bad - this would break function menus by clobbering window.renderMenu(), which 
    // Content Server uses to render function menus
    renderMenu = "abc";

    // good - limit the scope to this anonymous function using 
    // the "var" keyword
    var renderMenu = "abc";
});

The last line $.noConflict(true); sets the global jQuery and $ variables back to the original version (v1.3.2). This is required since other Javascript libraries in Content Server reference $ and expect it to be v1.3.2 with its associated plugins. You’ll get Javascript errors and broken menus otherwise.

It’s important your anonymous function accept a $ parameter, which becomes the alias you use to access your jQuery instance. Omitting this parameter would mean any reference to $ would reference the global instance, which has meanwhile been set back to v1.3.2. This might be easier to explain with examples:

Wrong:

$(document).ready(function() {
   // Without the $ parameter any reference to $ will access the global instance,
   // which has been set back to v1.3.2 via the $.noConflict() call.  e.g.,
   alert( $.fn.jquery ); // displays the version "1.3.2"
   alert( jQuery.fn.jquery ); // displays "1.3.2"
});

Right:

$(document).ready(function($) {
   // With the $ parameter we are referencing the newer instance.  e.g.,
   alert( $.fn.jquery ); // displays the version "1.10.2"
   alert( jQuery.fn.jquery ); // displays "1.3.2"
});

This pattern isolates the Javascript from anything else going on in the page. It reduces the risk of conflicts and makes it much more likely to work after a Content Server version upgrade. I’ve been using it for years and it’s by far the best way I know of doing this.

  2 Responses to “OpenText Content Server & jQuery”

  1. May I add this comment from the web which could be helpful : forum.jquery.com :

    After reading the jQuery code, i think it is simpler than you think.

    First important thing: when you load your jQuery.x.x.js, it will overwrite the existing $ and jQuery vars... BUT it keeps a backup copy of them (in _$ and _jQuery).
    Calling noConflict(true) you restore the situation as it was before your js inclusion!

    noConflict() gives you the running instance (the last loaded), so you can work with you version in this way

    Resuming:
    - original page loads his "jquery.versionX.js"
    - $ and jQuery belong to versionX
    - you call your "jquery.versionY.js"
    - now $ and jQuery belong to versionY, plus _$ and _jQuery that belongs to versionX
    - var my_jQuery = jQuery.noConflict(true);
    - now $ and jQuery belong to versionX, _$ and _jQuery are probably null, and my_jQuery is versionY

    Have a nice day ;)

  2. Hi Jean-Philippe: This approach also works but has limitations. Keep in mind that any plugins that are specific to your instance must be referenced before you call jQuery.noConflict(true);. What I don’t like about the approach is that you must reference my_jQuery in your code, which reduces reusability. In some instances (due to the modularity of Content Server pages) I may load multiple instances of jQuery with different plugins. This means each instance would need a unique name (e.g., my_jQuery1, my_jQuery2, etc.), which isn’t practical. The approach I outline keeps the code block self-contained without adding any new variables to the global scope. Thanks for your comment!

 Leave a Reply

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)