Thursday, 7 April 2016

Bootstrap Plugins in XPages Part V - jQuery and JavaScript AMD (Asynchronous Module Definition) Fixes

Many Bootstrap Plugins have moved during the past period to a new version. Examples include among others are Select2 and the Bootstrap Date-Time Picker. Problem with some of the newer version is the AMD Loader. AMD (Asynchronous Module Definition) in Dojo causes issues with jQuery plugins and other JavaScript libraries, in that it prevents them from loading correctly. In this blog post I will show two solutions to solve the AMD Loader problem in XPages.

Bootstrap Plugins in XPages
Part I : Bootstrap-select - A jQuery plugin that utilizes Bootstrap's dropdown.js
Part II : Bootstrap FileStyle - Customization of input file for Bootstrap
Part III : Dialog Boxes using Bootbox
Part IV : Awesome Bootstrap Checkbox
Part V : jQuery and JavaScript AMD (Asynchronous Module Definition) Fixes

1. Edit the JavaScript Code
This solution, by Mark Roden, consists of five simple steps. I have used this solution at the Bootstrap-select plugin in part one of this series. In this example I use the bootstrap-select.js file. This solution will always work!

A. Go to the WebContent Folder in the Package Explorer
B. Select the JavaScript file
C. Select Open With - Client/Server JS Editor


D. Remove in the second line 'define.amd' and replace it with 'false'


E. Save the JavaScript file

2. Hack to use jQuery AMD widgets and Dojo together
This great script by Ferry Kranenburg solves the AMD problem definitively.
Note about the script: The first script tag will temporary disable the Dojo AMD loader by removing "define.amd". After this script tag you should add all jQuery widgets that cause issues.
Last step is to add the a script tag to restore de Dojo AMD loader.

OpenNTF XSnippet: Hack to use jQuery AMD widgets and Dojo together
See GitHub Gist for the sample code.

In the example below I added the select2.js file to the Script Libraries in the XPage Application.
In this case you don't have to alter the JavaScript file!


On the XPages (or Custom Control) just ad the Hack.

<xp:this.resources>
<!-- temporary redefine define.amd object  (Dojo AMD loader) -->
<xp:script clientSide="true" type="text/javascript">
<xp:this.contents><![CDATA[${javascript:"if (typeof define === 'function' && define.amd) {if(define.amd.vendor =='dojotoolkit.org'){define._amd = define.amd;delete define.amd;}}";}]]></xp:this.contents>
</xp:script>

<!-- load jquery AMD enabled widgets -->
<xp:script src="/select2.js" clientSide="true"></xp:script>

<!-- restore define.amd object (Dojo AMD loader) -->
<xp:script clientSide="true">
 <xp:this.contents><![CDATA[${javascript:"if (typeof define === 'function' && define._amd) {define.amd = define._amd; delete define._amd;}"}]]></xp:this.contents>
</xp:script>
</xp:this.resources>

In the Google Chrome Developer Tools we can see the Hack in action.


This work great but only if the option 'Use runtime optimized JavaScript and CSS resources' is disabled in the XSP Properties, the Performance Properties. (Xsp Properties - Tab Persistence)
The final result in XPages.


Great solutions for a frequently occurring problem with the newer Bootstrap Plugins.

2 comments:

  1. A modified version of the approach described in 2. is described here: http://stackoverflow.com/questions/34269886/amd-loader-disable-enable-in-theme. It involves moving the AMD disable/ enable code to JavaScript files and works just fine with the 'Use runtime optimized JavaScript and CSS resources' option.

    ReplyDelete
  2. Thanks for the mention Mark. You can also use
    xp:parameter name="xsp.resources.aggregate" value="false"
    on the specific XPages (or Custom Control) were the Hack is needed when 'Use runtime optimized JavaScript and CSS resources' is enabled for the entire XPages Application. Just add it in the head of the XPage (or Custom Control) and it also works just fine.

    ReplyDelete