I'm having a problem with the bootstrap dateTimePicker control in my xpage application and I suspect this is to do with the way xPages generates a control id.
The following code works fine without an id on the inputText element.
<script type="text/javascript" src="/fPath/jquery-min.js"></script>
<script type="text/javascript" src="/fPath/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/RfPath/bootstrap-datetimepicker-3.0.0/js/moment.min.js"></script>
<script type="text/javascript" src="/fPath/bootstrap-datetimepicker-3.0.0/js/bootstrap-datetimepicker.min.js"></script>
<div class='input-group date' data-datetimepicker="true">
<xp:inputText styleClass="form-control timePicker">
<xp:this.converter>
<xp:convertDateTime type="time" timeStyle="short" />
</xp:this.converter>
</xp:inputText>
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
</div>
As soon as I add an id back in I receive the following error when clicking away/out of the control:
Error: Syntax error, unrecognized expression: unsupported pseudo: _id1
the id is required to map the data back to the document but I am not actually using it to attach the datetimepicker - I am using a class for this:
$('.timePicker').each(function(i,el){SHARED.timePickerOpen(el)})
SHARED = {
timePickerOpen: function(el){
$(el).datetimepicker({
pickDate: false,
pickTime: true,
useCurrent: true,
minuteStepping:5
});
}
}
UPDATE #1:
Sounds like there's a bit of misunderstanding going on so I'll try to explain further...
The problem appears to be the datetimepicker using the field id. Even though I obtain the field through the class name (Not the id) the datetimepicker code seems to want to use an id if one is found in the field. The datetimepicker binds to the field without any problems. When you attempt to select a time the model box displays and allows you to select a time, the error occurs when you try to click away from the field to close the model time control.
Interesting plugin. I created a sample page to see if I can get it to integrate with an XPage and if I get the same error. After doing what I describe below I got it to run without the issues you reported.
As described in the docs, I've added the plugin and moment.js to a database, and used the sample code here to build a simple demo page. In the database I am using the Bootstrap4XPages plugin (March release), so Bootstrap 3.1.1 is already loaded.
<?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="momentjs-2.7.0/moment.min.js"
clientSide="true">
</xp:script>
<xp:script
src="eonasdan-datetimepicker/js/bootstrap-datetimepicker.min.js"
clientSide="true">
</xp:script>
<xp:styleSheet
href="eonasdan-datetimepicker/css/bootstrap-datetimepicker.min.css"></xp:styleSheet>
</xp:this.resources>
<xp:div
xp:key="facetMiddle">
<p>
This page uses 
<a
href="https://github.com/Eonasdan/bootstrap-datetimepicker">Eonasdan's Bootstrap DateTimePicker</a>
.
</p>
<div
class="col-sm-6">
<div
class="form-group">
<div
class='input-group date'
id='datetimepicker1'>
<xp:inputText
id="inputText1"
styleClass="form-control">
<xp:this.converter>
<xp:convertDateTime
type="both"
timeStyle="short" />
</xp:this.converter>
</xp:inputText>
<span
class="input-group-addon">
<span
class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</xp:div>
<xp:scriptBlock
id="scriptBlock1">
<xp:this.value><![CDATA[$(function () {
$('#datetimepicker1').datetimepicker();
});]]></xp:this.value>
</xp:scriptBlock>
</xp:view>
Opening the XPage for the first time gave me a familiar error in Chrome's console:
Uncaught TypeError: undefined is not a function
I've seen that one before: newer jQuery plugins try to use its AMD loader, but that doesn't play well with the Dojo implementation in XPages. There are 2 workarounds that I know of:
bootstrap-datetimepicker.js
you need to find the lines that determine if it can use the AMD loader. They can mostly be found at the beginning or end of a JavaScript file.Here's the code you're looking for in bootstrap-datetimepicker.js:
; (function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD is used - Register as an anonymous module.
define(['jquery', 'moment'], factory);
} else {
// AMD is not used - Attempt to fetch dependencies from scope.
if (!jQuery) {
throw 'bootstrap-datetimepicker requires jQuery to be loaded first';
} else if (!moment) {
throw 'bootstrap-datetimepicker requires moment.js to be loaded first';
} else {
factory(jQuery, moment);
}
}
}
We then disable (or remove; your choice) the AMD part:
; (function (factory) {
//if (typeof define === 'function' && define.amd) {
// AMD is used - Register as an anonymous module.
// define(['jquery', 'moment'], factory);
//} else {
// AMD is not used - Attempt to fetch dependencies from scope.
if (!jQuery) {
throw 'bootstrap-datetimepicker requires jQuery to be loaded first';
} else if (!moment) {
throw 'bootstrap-datetimepicker requires moment.js to be loaded first';
} else {
factory(jQuery, moment);
}
//}
}
A live demo can be found here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With