blob: 1e43d1b395bc2c11f4e90c5979f750a34b484bbf [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Listener, Phase} from "./tobago-listener";
import {Tobago4Utils} from "./tobago-utils";
class DateTime {
static init(elements) {
elements = elements.jQuery ? elements : jQuery(elements); // fixme jQuery -> ES5
Tobago4Utils.selectWithJQuery(elements, ".tobago-date")
.not("[disabled]")
.not("[readonly]")
.each(function () {
var $date = jQuery(this);
var analyzed = DateTime.analyzePattern($date.data("tobago-pattern"));
var options = {
format: analyzed,
showTodayButton: $date.data("tobago-today-button") === "data-tobago-today-button",
icons: {
time: 'fa fa-clock-o',
date: 'fa fa-calendar',
up: 'fa fa-chevron-up',
down: 'fa fa-chevron-down',
previous: 'fa fa-chevron-left',
next: 'fa fa-chevron-right',
today: 'fa fa-calendar-check-o',
clear: 'fa fa-trash',
close: 'fa fa-times'
},
keyBinds: {
enter: function () {
$date.trigger(jQuery.Event("keypress", {
which: 13,
target: $date[0]
}));
}
},
widgetParent: '.tobago-page-menuStore'
};
var i18n = $date.data("tobago-date-time-i18n");
if (i18n) {
var monthNames = i18n.monthNames;
if (monthNames) {
moment.localeData()._months = monthNames;
}
var monthNamesShort = i18n.monthNamesShort;
if (monthNamesShort) {
moment.localeData()._monthsShort = monthNamesShort;
}
var dayNames = i18n.dayNames;
if (dayNames) {
moment.localeData()._weekdays = dayNames;
}
var dayNamesShort = i18n.dayNamesShort;
if (dayNamesShort) {
moment.localeData()._weekdaysShort = dayNamesShort;
}
var dayNamesMin = i18n.dayNamesMin;
if (dayNamesMin) {
moment.localeData()._weekdaysMin = dayNamesMin;
}
var firstDay = i18n.firstDay;
if (firstDay) {
moment.localeData()._week.dow = firstDay;
}
}
$date.parent().datetimepicker(options);
// we need to add the change listener here, because
// in line 1307 of bootstrap-datetimepicker.js
// the 'stopImmediatePropagation()' stops the change-event
// execution of line 686 in tobago.js
$date.parent().on('dp.change', function (event) {
var commands = jQuery(this).find("input").data("tobago-commands");
if (commands && commands.change) {
if (commands.change.execute || commands.change.render) {
jsf.ajax.request(
jQuery(this).find("input").attr("name"),
event,
{
"javax.faces.behavior.event": "change",
execute: commands.change.execute,
render: commands.change.render
});
} else if (commands.change.action) {
Tobago4.submitAction(this.firstElementChild, commands.change.action, commands.change);
}
}
});
// set position
$date.parent().on('dp.show', function () {
var datepicker = jQuery('.bootstrap-datetimepicker-widget');
var $div = jQuery(this);
var top, left;
if (datepicker.hasClass('bottom')) {
top = $div.offset().top + $div.outerHeight();
left = $div.offset().left;
datepicker.css({
'top': top + 'px',
'bottom': 'auto',
'left': left + 'px'
});
} else if (datepicker.hasClass('top')) {
top = $div.offset().top - datepicker.outerHeight();
left = $div.offset().left;
datepicker.css({
'top': top + 'px',
'bottom': 'auto',
'left': left + 'px'
});
}
DateTime.addPastClass($date);
});
// set css class in update - like changing the month
$date.parent().on('dp.update', function () {
DateTime.addPastClass($date);
});
// fix for bootstrap-datetimepicker v4.17.45
$date.parent().on('dp.show', function () {
jQuery(".bootstrap-datetimepicker-widget .collapse.in").addClass("show");
jQuery(".bootstrap-datetimepicker-widget .picker-switch a").click(function () {
// the click is executed before togglePicker() function
var $datetimepicker = jQuery(".bootstrap-datetimepicker-widget");
$datetimepicker.find(".collapse.in").removeClass("in");
$datetimepicker.find(".collapse.show").addClass("in");
});
});
});
}
static addPastClass($date) {
var today = $date.data("tobago-today");
if (today.length === 10) {
var todayArray = today.split("-");
if (todayArray.length === 3) {
var year = todayArray[0];
var month = todayArray[1];
var day = todayArray[2];
var todayTimestamp = new Date(month + "/" + day + "/" + year).getTime();
jQuery(".bootstrap-datetimepicker-widget .datepicker-days td.day[data-day]").each(function () {
var day = jQuery(this);
var currentTimestamp = new Date(day.attr('data-day')).getTime();
if (currentTimestamp < todayTimestamp) {
day.addClass('past');
}
});
}
}
}
/*
Get the pattern from the "Java world" (http://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html)
and convert it to 'moment.js'.
Attention: Not every pattern char is supported.
*/
static analyzePattern = function (pattern) {
if (!pattern || pattern.length > 100) {
console.warn("Pattern not supported: " + pattern);
pattern = "";
}
var analyzedPattern = "";
var nextSegment = "";
var escMode = false;
for (var i = 0; i < pattern.length; i++) {
var currentChar = pattern.charAt(i);
if (currentChar == "'" && escMode == false) {
escMode = true;
analyzedPattern += DateTime.analyzePatternPart(nextSegment);
nextSegment = "";
} else if (currentChar == "'" && pattern.charAt(i + 1) == "'") {
if (escMode) {
nextSegment += "\\";
}
nextSegment += "'";
i++;
} else if (currentChar == "'" && escMode == true) {
escMode = false;
analyzedPattern += nextSegment;
nextSegment = "";
} else {
if (escMode) {
nextSegment += "\\";
}
nextSegment += currentChar;
}
}
if (nextSegment != "") {
if (escMode) {
analyzedPattern += nextSegment;
} else {
analyzedPattern += DateTime.analyzePatternPart(nextSegment);
}
}
return analyzedPattern;
};
static analyzePatternPart = function (pattern) {
if (pattern.search("G") > -1 || pattern.search("W") > -1 || pattern.search("F") > -1
|| pattern.search("K") > -1 || pattern.search("z") > -1 || pattern.search("X") > -1) {
console.warn("Pattern chars 'G', 'W', 'F', 'K', 'z' and 'X' are not supported: " + pattern);
pattern = "";
}
if (pattern.search("y") > -1) {
pattern = pattern.replace(/y/g, "Y");
}
if (pattern.search("Y") > -1) {
pattern = pattern.replace(/\bY\b/g, "YYYY");
pattern = pattern.replace(/\bYYY\b/g, "YY");
pattern = pattern.replace(/YYYYYY+/g, "YYYYY");
}
if (pattern.search("MMMMM") > -1) {
pattern = pattern.replace(/MMMMM+/g, "MMMM");
}
if (pattern.search("w") > -1) {
pattern = pattern.replace(/\bw\b/g, "W");
pattern = pattern.replace(/www+/g, "WW");
}
if (pattern.search("D") > -1) {
pattern = pattern.replace(/DDD+/g, "DDDD");
pattern = pattern.replace(/\bD{1,2}\b/g, "DDD");
}
if (pattern.search("d") > -1) {
pattern = pattern.replace(/dd+/g, "DD");
pattern = pattern.replace(/\bd\b/g, "D");
}
if (pattern.search("E") > -1) {
pattern = pattern.replace(/\bE{1,3}\b/g, "dd");
pattern = pattern.replace(/EEEE+/g, "dddd");
}
if (pattern.search("u") > -1) {
pattern = pattern.replace(/u+/g, "E");
}
if (pattern.search("a") > -1) {
pattern = pattern.replace(/a+/g, "A");
}
if (pattern.search("HHH") > -1) {
pattern = pattern.replace(/HHH+/g, "HH");
}
if (pattern.search("kkk") > -1) {
pattern = pattern.replace(/kkk+/g, "kk");
}
if (pattern.search("hhh") > -1) {
pattern = pattern.replace(/hhh+/g, "hh");
}
if (pattern.search("mmm") > -1) {
pattern = pattern.replace(/mmm+/g, "mm");
}
if (pattern.search("sss") > -1) {
pattern = pattern.replace(/sss+/g, "ss");
}
if (pattern.search("SSSS") > -1) {
pattern = pattern.replace(/SSSS+/g, "SSS");
}
if (pattern.search("Z") > -1) {
pattern = pattern.replace(/\bZ\b/g, "ZZ");
pattern = pattern.replace(/ZZZ+/g, "ZZ");
}
return pattern;
};
}
Listener.register(DateTime.init, Phase.DOCUMENT_READY);
Listener.register(DateTime.init, Phase.AFTER_UPDATE);