META-INF.resources.bower_components.angular-bootstrap-datetimepicker.src.js.datetimepicker.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jwebmp-bootstrap-date-time-picker Show documentation
Show all versions of jwebmp-bootstrap-date-time-picker Show documentation
The JWebSwing implementation for Bootstrap Date Time Picker
/* globals define, jQuery, module, require, angular, moment */
/* jslint vars:true */
/**
* @license angular-bootstrap-datetimepicker
* Copyright 2016 Knight Rider Consulting, Inc. http://www.knightrider.com
* License: MIT
*
* @author Dale "Ducky" Lotts
* @since 2013-Jul-8
*/
;(function (root, factory) {
'use strict'
/* istanbul ignore if */
if (typeof module !== 'undefined' && module.exports) {
var ng = typeof angular === 'undefined' ? require('angular') : angular
var mt = typeof moment === 'undefined' ? require('moment') : moment
factory(ng, mt)
module.exports = 'ui.bootstrap.datetimepicker'
/* istanbul ignore next */
} else if (typeof define === 'function' && /* istanbul ignore next */ define.amd) {
define(['angular', 'moment'], factory)
} else {
factory(root.angular, root.moment)
}
}(this, function (angular, moment) {
'use strict'
angular.module('ui.bootstrap.datetimepicker', [])
.service('dateTimePickerConfig', DateTimePickerConfigProvider)
.service('dateTimePickerValidator', DateTimePickerValidatorService)
.directive('datetimepicker', DatetimepickerDirective)
DatetimepickerDirective.$inject = ['dateTimePickerConfig', 'dateTimePickerValidator']
function DatetimepickerDirective (defaultConfig, configurationValidator) {
var directiveDefinition = {
bindToController: false,
controller: DirectiveController,
controllerAs: 'dateTimePickerController',
replace: true,
require: 'ngModel',
restrict: 'E',
scope: {
beforeRender: '&',
onSetTime: '&'
},
templateUrl: 'templates/datetimepicker.html'
}
DirectiveController.$inject = ['$scope', '$element', '$attrs']
function DirectiveController ($scope, $element, $attrs) {
// Configuration
var ngModelController = $element.controller('ngModel')
var configuration = createConfiguration()
$scope.screenReader = configuration.screenReader
// Behavior
$scope.changeView = changeView
ngModelController.$render = $render
if (configuration.configureOn) {
$scope.$on(configuration.configureOn, function () {
configuration = createConfiguration()
$scope.screenReader = configuration.screenReader
ngModelController.$render()
})
}
if (configuration.renderOn) {
$scope.$on(configuration.renderOn, ngModelController.$render)
}
// Implementation
var viewToModelFactory = {
year: yearModelFactory,
month: monthModelFactory,
day: dayModelFactory,
hour: hourModelFactory,
minute: minuteModelFactory,
setTime: setTime
}
function changeView (viewName, dateObject, event) {
if (event) {
event.stopPropagation()
event.preventDefault()
}
if (viewName && (dateObject.utcDateValue > -Infinity) && dateObject.selectable && viewToModelFactory[viewName]) {
var result = viewToModelFactory[viewName](dateObject.utcDateValue)
var weekDates = []
if (result.weeks) {
for (var i = 0; i < result.weeks.length; i += 1) {
var week = result.weeks[i]
for (var j = 0; j < week.dates.length; j += 1) {
var weekDate = week.dates[j]
weekDates.push(weekDate)
}
}
}
$scope.beforeRender({
$view: result.currentView,
$dates: result.dates || weekDates,
$leftDate: result.leftDate,
$upDate: result.previousViewDate,
$rightDate: result.rightDate
})
$scope.data = result
}
}
function yearModelFactory (milliseconds) {
var selectedDate = moment.utc(milliseconds).startOf('year')
// View starts one year before the decade starts and ends one year after the decade ends
// i.e. passing in a date of 1/1/2013 will give a range of 2009 to 2020
// Truncate the last digit from the current year and subtract 1 to get the start of the decade
var startDecade = (parseInt(selectedDate.year() / 10, 10) * 10)
var startDate = moment.utc(startOfDecade(milliseconds)).subtract(1, 'year').startOf('year')
var yearFormat = 'YYYY'
var activeFormat = formatValue(ngModelController.$modelValue, yearFormat)
var currentFormat = moment().format(yearFormat)
var result = {
'currentView': 'year',
'nextView': configuration.minView === 'year' ? 'setTime' : 'month',
'previousViewDate': new DateObject({
utcDateValue: null,
display: startDecade + '-' + (startDecade + 9)
}),
'leftDate': new DateObject({utcDateValue: moment.utc(startDate).subtract(9, 'year').valueOf()}),
'rightDate': new DateObject({utcDateValue: moment.utc(startDate).add(11, 'year').valueOf()}),
'dates': []
}
for (var i = 0; i < 12; i += 1) {
var yearMoment = moment.utc(startDate).add(i, 'years')
var dateValue = {
'active': yearMoment.format(yearFormat) === activeFormat,
'current': yearMoment.format(yearFormat) === currentFormat,
'display': yearMoment.format(yearFormat),
'future': yearMoment.year() > startDecade + 9,
'past': yearMoment.year() < startDecade,
'utcDateValue': yearMoment.valueOf()
}
result.dates.push(new DateObject(dateValue))
}
return result
}
function monthModelFactory (milliseconds) {
var startDate = moment.utc(milliseconds).startOf('year')
var previousViewDate = startOfDecade(milliseconds)
var monthFormat = 'YYYY-MMM'
var activeFormat = formatValue(ngModelController.$modelValue, monthFormat)
var currentFormat = moment().format(monthFormat)
var result = {
'previousView': 'year',
'currentView': 'month',
'nextView': configuration.minView === 'month' ? 'setTime' : 'day',
'previousViewDate': new DateObject({
utcDateValue: previousViewDate.valueOf(),
display: startDate.format('YYYY')
}),
'leftDate': new DateObject({utcDateValue: moment.utc(startDate).subtract(1, 'year').valueOf()}),
'rightDate': new DateObject({utcDateValue: moment.utc(startDate).add(1, 'year').valueOf()}),
'dates': []
}
for (var i = 0; i < 12; i += 1) {
var monthMoment = moment.utc(startDate).add(i, 'months')
var dateValue = {
'active': monthMoment.format(monthFormat) === activeFormat,
'current': monthMoment.format(monthFormat) === currentFormat,
'display': monthMoment.format('MMM'),
'utcDateValue': monthMoment.valueOf()
}
result.dates.push(new DateObject(dateValue))
}
return result
}
function dayModelFactory (milliseconds) {
var selectedDate = moment.utc(milliseconds)
var startOfMonth = moment.utc(selectedDate).startOf('month')
var previousViewDate = moment.utc(selectedDate).startOf('year')
var endOfMonth = moment.utc(selectedDate).endOf('month')
var startDate = moment.utc(startOfMonth).subtract(Math.abs(startOfMonth.weekday()), 'days')
var dayFormat = 'YYYY-MMM-DD'
var activeFormat = formatValue(ngModelController.$modelValue, dayFormat)
var currentFormat = moment().format(dayFormat)
var result = {
'previousView': 'month',
'currentView': 'day',
'nextView': configuration.minView === 'day' ? 'setTime' : 'hour',
'previousViewDate': new DateObject({
utcDateValue: previousViewDate.valueOf(),
display: startOfMonth.format('YYYY-MMM')
}),
'leftDate': new DateObject({utcDateValue: moment.utc(startOfMonth).subtract(1, 'months').valueOf()}),
'rightDate': new DateObject({utcDateValue: moment.utc(startOfMonth).add(1, 'months').valueOf()}),
'dayNames': [],
'weeks': []
}
for (var dayNumber = 0; dayNumber < 7; dayNumber += 1) {
result.dayNames.push(moment.utc().weekday(dayNumber).format('dd'))
}
for (var i = 0; i < 6; i += 1) {
var week = {dates: []}
for (var j = 0; j < 7; j += 1) {
var dayMoment = moment.utc(startDate).add((i * 7) + j, 'days')
var dateValue = {
'active': dayMoment.format(dayFormat) === activeFormat,
'current': dayMoment.format(dayFormat) === currentFormat,
'display': dayMoment.format('D'),
'future': dayMoment.isAfter(endOfMonth),
'past': dayMoment.isBefore(startOfMonth),
'utcDateValue': dayMoment.valueOf()
}
week.dates.push(new DateObject(dateValue))
}
result.weeks.push(week)
}
return result
}
function hourModelFactory (milliseconds) {
var selectedDate = moment.utc(milliseconds).startOf('day')
var previousViewDate = moment.utc(selectedDate).startOf('month')
var hourFormat = 'YYYY-MM-DD H'
var activeFormat = formatValue(ngModelController.$modelValue, hourFormat)
var currentFormat = moment().format(hourFormat)
var result = {
'previousView': 'day',
'currentView': 'hour',
'nextView': configuration.minView === 'hour' ? 'setTime' : 'minute',
'previousViewDate': new DateObject({
utcDateValue: previousViewDate.valueOf(),
display: selectedDate.format('ll')
}),
'leftDate': new DateObject({utcDateValue: moment.utc(selectedDate).subtract(1, 'days').valueOf()}),
'rightDate': new DateObject({utcDateValue: moment.utc(selectedDate).add(1, 'days').valueOf()}),
'dates': []
}
for (var i = 0; i < 24; i += 1) {
var hourMoment = moment.utc(selectedDate).add(i, 'hours')
var dateValue = {
'active': hourMoment.format(hourFormat) === activeFormat,
'current': hourMoment.format(hourFormat) === currentFormat,
'display': hourMoment.format('LT'),
'utcDateValue': hourMoment.valueOf()
}
result.dates.push(new DateObject(dateValue))
}
return result
}
function minuteModelFactory (milliseconds) {
var selectedDate = moment.utc(milliseconds).startOf('hour')
var previousViewDate = moment.utc(selectedDate).startOf('day')
var minuteFormat = 'YYYY-MM-DD H:mm'
var activeFormat = formatValue(ngModelController.$modelValue, minuteFormat)
var currentFormat = moment().format(minuteFormat)
var result = {
'previousView': 'hour',
'currentView': 'minute',
'nextView': 'setTime',
'previousViewDate': new DateObject({
utcDateValue: previousViewDate.valueOf(),
display: selectedDate.format('lll')
}),
'leftDate': new DateObject({utcDateValue: moment.utc(selectedDate).subtract(1, 'hours').valueOf()}),
'rightDate': new DateObject({utcDateValue: moment.utc(selectedDate).add(1, 'hours').valueOf()}),
'dates': []
}
var limit = 60 / configuration.minuteStep
for (var i = 0; i < limit; i += 1) {
var hourMoment = moment.utc(selectedDate).add(i * configuration.minuteStep, 'minute')
var dateValue = {
'active': hourMoment.format(minuteFormat) === activeFormat,
'current': hourMoment.format(minuteFormat) === currentFormat,
'display': hourMoment.format('LT'),
'utcDateValue': hourMoment.valueOf()
}
result.dates.push(new DateObject(dateValue))
}
return result
}
function setTime (milliseconds) {
var tempDate = new Date(milliseconds)
var newDate = new Date(tempDate.getUTCFullYear(), tempDate.getUTCMonth(), tempDate.getUTCDate(), tempDate.getUTCHours(), tempDate.getUTCMinutes(), tempDate.getUTCSeconds(), tempDate.getUTCMilliseconds())
switch (configuration.modelType) {
case 'Date':
// No additional work needed
break
case 'moment':
newDate = moment([tempDate.getUTCFullYear(), tempDate.getUTCMonth(), tempDate.getUTCDate(), tempDate.getUTCHours(), tempDate.getUTCMinutes(), tempDate.getUTCSeconds(), tempDate.getUTCMilliseconds()])
break
case 'milliseconds':
newDate = milliseconds
break
default: // It is assumed that the modelType is a formatting string.
newDate = moment([tempDate.getUTCFullYear(), tempDate.getUTCMonth(), tempDate.getUTCDate(), tempDate.getUTCHours(), tempDate.getUTCMinutes(), tempDate.getUTCSeconds(), tempDate.getUTCMilliseconds()]).format(configuration.modelType)
}
var oldDate = ngModelController.$modelValue
ngModelController.$setViewValue(newDate)
if (configuration.dropdownSelector) {
jQuery(configuration.dropdownSelector).dropdown('toggle')
}
$scope.onSetTime({newDate: newDate, oldDate: oldDate})
return viewToModelFactory[configuration.startView](milliseconds)
}
function $render () {
$scope.changeView(configuration.startView, new DateObject({utcDateValue: getUTCTime(ngModelController.$viewValue)}))
}
function startOfDecade (milliseconds) {
var startYear = (parseInt(moment.utc(milliseconds).year() / 10, 10) * 10)
return moment.utc(milliseconds).year(startYear).startOf('year')
}
function formatValue (timeValue, formatString) {
if (timeValue) {
return getMoment(timeValue).format(formatString)
} else {
return ''
}
}
/**
* Converts a time value into a moment.
*
* This function is now necessary because moment logs a warning when parsing a string without a format.
* @param modelValue
* a time value in any of the supported formats (Date, moment, milliseconds, and string)
* @returns {moment}
* representing the specified time value.
*/
function getMoment (modelValue) {
return moment(modelValue, angular.isString(modelValue) ? configuration.parseFormat : undefined)
}
/**
* Converts a time value to UCT/GMT time.
* @param modelValue
* a time value in any of the supported formats (Date, moment, milliseconds, and string)
* @returns {number}
* number of milliseconds since 1/1/1970
*/
function getUTCTime (modelValue) {
var tempDate = new Date()
if (modelValue) {
var tempMoment = getMoment(modelValue)
if (tempMoment.isValid()) {
tempDate = tempMoment.toDate()
} else {
throw new Error('Invalid date: ' + modelValue)
}
}
return tempDate.getTime() - (tempDate.getTimezoneOffset() * 60000)
}
function createConfiguration () {
var directiveConfig = {}
if ($attrs.datetimepickerConfig) {
directiveConfig = $scope.$parent.$eval($attrs.datetimepickerConfig)
}
var configuration = angular.extend({}, defaultConfig, directiveConfig)
configurationValidator.validate(configuration)
return configuration
}
}
function DateObject () {
var tempDate = new Date(arguments[0].utcDateValue)
var localOffset = tempDate.getTimezoneOffset() * 60000
this.utcDateValue = tempDate.getTime()
this.selectable = true
this.localDateValue = function localDateValue () {
return this.utcDateValue + localOffset
}
var validProperties = ['active', 'current', 'display', 'future', 'past', 'selectable', 'utcDateValue']
var constructorObject = arguments[0]
Object.keys(constructorObject).filter(function (key) {
return validProperties.indexOf(key) >= 0
}).forEach(function (key) {
this[key] = constructorObject[key]
}, this)
}
return directiveDefinition
}
function DateTimePickerConfigProvider () {
var defaultConfiguration = {
configureOn: null,
dropdownSelector: null,
minuteStep: 5,
minView: 'minute',
modelType: 'Date',
parseFormat: 'YYYY-MM-DDTHH:mm:ss.SSSZZ',
renderOn: null,
startView: 'day'
}
var defaultLocalization = {
'bg': {previous: 'предишна', next: 'следваща'},
'ca': {previous: 'anterior', next: 'següent'},
'da': {previous: 'forrige', next: 'næste'},
'de': {previous: 'vorige', next: 'weiter'},
'en-au': {previous: 'previous', next: 'next'},
'en-gb': {previous: 'previous', next: 'next'},
'en': {previous: 'previous', next: 'next'},
'es-us': {previous: 'atrás', next: 'siguiente'},
'es': {previous: 'atrás', next: 'siguiente'},
'fi': {previous: 'edellinen', next: 'seuraava'},
'fr': {previous: 'précédent', next: 'suivant'},
'hu': {previous: 'előző', next: 'következő'},
'it': {previous: 'precedente', next: 'successivo'},
'ja': {previous: '前へ', next: '次へ'},
'ml': {previous: 'മുൻപുള്ളത്', next: 'അടുത്തത്'},
'nl': {previous: 'vorige', next: 'volgende'},
'pl': {previous: 'poprzednia', next: 'następna'},
'pt-br': {previous: 'anteriores', next: 'próximos'},
'pt': {previous: 'anterior', next: 'próximo'},
'ro': {previous: 'anterior', next: 'următor'},
'ru': {previous: 'предыдущая', next: 'следующая'},
'sk': {previous: 'predošlá', next: 'ďalšia'},
'sv': {previous: 'föregående', next: 'nästa'},
'tr': {previous: 'önceki', next: 'sonraki'},
'uk': {previous: 'назад', next: 'далі'},
'zh-cn': {previous: '上一页', next: '下一页'},
'zh-tw': {previous: '上一頁', next: '下一頁'}
}
var screenReader = defaultLocalization[moment.locale().toLowerCase()]
return angular.extend({}, defaultConfiguration, {screenReader: screenReader})
}
DateTimePickerValidatorService.$inject = ['$log']
function DateTimePickerValidatorService ($log) {
return {
validate: validator
}
function validator (configuration) {
var validOptions = [
'configureOn',
'dropdownSelector',
'minuteStep',
'minView',
'modelType',
'parseFormat',
'renderOn',
'startView',
'screenReader'
]
var invalidOptions = Object.keys(configuration).filter(function (key) {
return (validOptions.indexOf(key) < 0)
})
if (invalidOptions.length) {
throw new Error('Invalid options: ' + invalidOptions.join(', '))
}
// Order of the elements in the validViews array is significant.
var validViews = ['minute', 'hour', 'day', 'month', 'year']
if (validViews.indexOf(configuration.startView) < 0) {
throw new Error('invalid startView value: ' + configuration.startView)
}
if (validViews.indexOf(configuration.minView) < 0) {
throw new Error('invalid minView value: ' + configuration.minView)
}
if (validViews.indexOf(configuration.minView) > validViews.indexOf(configuration.startView)) {
throw new Error('startView must be greater than minView')
}
if (!angular.isNumber(configuration.minuteStep)) {
throw new Error('minuteStep must be numeric')
}
if (configuration.minuteStep <= 0 || configuration.minuteStep >= 60) {
throw new Error('minuteStep must be greater than zero and less than 60')
}
if (configuration.configureOn !== null && !angular.isString(configuration.configureOn)) {
throw new Error('configureOn must be a string')
}
if (configuration.configureOn !== null && configuration.configureOn.length < 1) {
throw new Error('configureOn must not be an empty string')
}
if (configuration.renderOn !== null && !angular.isString(configuration.renderOn)) {
throw new Error('renderOn must be a string')
}
if (configuration.renderOn !== null && configuration.renderOn.length < 1) {
throw new Error('renderOn must not be an empty string')
}
if (configuration.modelType !== null && !angular.isString(configuration.modelType)) {
throw new Error('modelType must be a string')
}
if (configuration.modelType !== null && configuration.modelType.length < 1) {
throw new Error('modelType must not be an empty string')
}
if (configuration.modelType !== 'Date' && configuration.modelType !== 'moment' && configuration.modelType !== 'milliseconds') {
// modelType contains string format, overriding parseFormat with modelType
configuration.parseFormat = configuration.modelType
}
if (configuration.dropdownSelector !== null && !angular.isString(configuration.dropdownSelector)) {
throw new Error('dropdownSelector must be a string')
}
/* istanbul ignore next */
if (configuration.dropdownSelector !== null && ((typeof jQuery === 'undefined') || (typeof jQuery().dropdown !== 'function'))) {
$log.error('Please DO NOT specify the dropdownSelector option unless you are using jQuery AND Bootstrap.js. ' +
'Please include jQuery AND Bootstrap.js, or write code to close the dropdown in the on-set-time callback. \n\n' +
'The dropdownSelector configuration option is being removed because it will not function properly.')
delete configuration.dropdownSelector
}
}
}
})); // eslint-disable-line semi