Tuesday, 29 August 2017

Using Boostrap Date Range Picker in XPages


The Bootstrap Date Range Picker component creates a dropdown menu from which a user can select a range of dates. Features include limiting the selectable date range, localizable strings and date formats, a single date picker mode, optional time picker (for e.g. making appointments or reservations), and styles that match the default Bootstrap 3 theme. Originally built for reporting at Improvely, the Date Range Picker can be attached to any webpage element to pop up two calendars for selecting dates, times, or from predefined ranges like "Last 30 Days". Bootstrap Date Range Picker relies on Bootstrap, jQuery and Moment.js.
In order to use Bootstrap Date Range Picker, the JavaScript and CSS file(s) need to be included on the XPage / Custom Control. The latest version can be downloaded from GitHub: Bootstrap Date Range Picker.

Adding the JS and CSS files
The JavaScript and CSS files must be added to the WebContent Folder in the Package Explorer.
In this example a Folder daterangepicker has been added in the WebContent Folder.
Next the JavaScript and CSS files, moment.js, daterangepicker.js and daterangepicker.css must be included on the XPage or Custom Control. In this example I add the files to an XPage.

<script type="text/javascript" src="daterangepicker/moment.js"></script>
<script type="text/javascript" src="daterangepicker/daterangepicker.js"></script>
<link rel="stylesheet" href="daterangepicker/daterangepicker.css" />

AMD Loader Fix
For the Bootstrap Date Range Picker in XPages there is a need for an AMD Loader Fix. Reason: newer jQuery plugins try to use its AMD loader, but that doesn't play well with the Dojo implementation in XPages. In the example below I use two javascript libraries, disable_amd.js and enable_amd.js, a solution provided by Mark Leussink. You can add these scripts to in the Script Libraries of the XPages application.

disable_amd.js
if (typeof define === 'function' && define.amd) {if(define.amd.vendor =='dojotoolkit.org'){define._amd = define.amd;delete define.amd;}}

enable_amd.js
if (typeof define === 'function' && define._amd) {define.amd = define._amd; delete define._amd;}

The first one is loaded before the js files, the second one after the js files.

<script type="text/javascript" src="disable_amd.js" clientSide="true"></script>
<script type="text/javascript" src="daterangepicker/moment.js"></script>
<script type="text/javascript" src="daterangepicker/daterangepicker.js"></script>
<script type="text/javascript" src="enable_amd.js" clientSide="true"></script>

Note: There are other solutions for the AMD Fix. For more information about these solutions see my blog post Bootstrap Plugins in XPages Part VI - jQuery and JavaScript AMD (Asynchronous Module Definition) Fixes (2).

Adding the x$ jQuery selector for XPages
Furthermore I recommend to use the the great XSnippet by Mark Roden, x$ jQuery selector for XPages, to initialize the plugin. The XSnippet can be added to the Script Libraries. See also the blog post by Csaba Kiss, x$ selector problem with JQuery 3.
The script itself can be made up as follows. In this example I use a few standard options.

<xp:scriptBlock id="scriptBlock1">
<xp:this.value><![CDATA[
$(document).ready(
function() {
x$( "#{id:inputText1}" ).daterangepicker({
timePicker: true,
timePicker24Hour: true,
timePickerIncrement: 30,
locale: {
format: 'DD-MM-YYYY hh:mm',        
}
});    
})
]]></xp:this.value>
</xp:scriptBlock>

Final Result
The final result is a responsive Date Range Picker with some additional options in the initial setup.


Code Xpage
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xc="http://www.ibm.com/xsp/custom">
<xp:this.resources>
<xp:script src="/JQueryXSnippet.js" clientSide="true"></xp:script>
</xp:this.resources>
<script type="text/javascript" src="disable_amd.js" clientSide="true"></script>
<script type="text/javascript" src="daterangepicker/moment.js"></script>
<script type="text/javascript" src="daterangepicker/daterangepicker.js"></script>
<script type="text/javascript" src="enable_amd.js" clientSide="true"></script>
<link rel="stylesheet" href="daterangepicker/daterangepicker.css" />
<xp:scriptBlock id="scriptBlock1">
<xp:this.value><![CDATA[
$(document).ready(
function() {
x$( "#{id:inputText1}" ).daterangepicker({
timePicker: true,
timePicker24Hour: true,
timePickerIncrement: 30,
locale: {
format: 'DD-MM-YYYY hh:mm',        
}
});    
})
]]></xp:this.value>
</xp:scriptBlock>
<xp:scriptBlock id="scriptBlock2">
<xp:this.value><![CDATA[
$(document).ready(
function() {
x$( "#{id:inputText2}" ).daterangepicker({
singleDatePicker: true,
showDropdowns: true,  
locale: {
format: 'DD-MM-YYYY'
}
});    
})
]]></xp:this.value>
</xp:scriptBlock>
<xc:ccLayout>
<xp:this.facets>
<xp:panel xp:key="facetMiddle">
<div class="col-md-7">
<h3>DateRangePicker</h3>
<h5>
A JavaScript component for choosing date ranges. Designed to work with the Bootstrap CSS
framework. Date Range Picker relies on Bootstrap, jQuery and Moment.js.
</h5>
</div>
<div class="col-md-7">
<xp:inputText id="inputText1">
<xp:this.attrs>
<xp:attr name="name" value="daterange"></xp:attr>
<xp:attr name="value" value="01/01/2017 - 31/01/2017">
</xp:attr>
</xp:this.attrs>
</xp:inputText>
</div>
<xp:br></xp:br>
<xp:br></xp:br>
<div class="col-md-7">
<xp:inputText id="inputText2">
<xp:this.attrs>
<xp:attr name="name" value="daterange"></xp:attr>
<xp:attr name="value" value="01-08-2017">
</xp:attr>
</xp:this.attrs>
</xp:inputText>
</div>
<xp:br></xp:br>
</xp:panel>
</xp:this.facets>
</xc:ccLayout>
</xp:view>

More information: Bootstrap Date Range Picker documentation

No comments:

Post a Comment