datetimepicker.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. /* globals define, jQuery, module, require, angular, moment */
  2. /* jslint vars:true */
  3. /**
  4. * @license angular-bootstrap-datetimepicker
  5. * Copyright 2016 Knight Rider Consulting, Inc. http://www.knightrider.com
  6. * License: MIT
  7. *
  8. * @author Dale "Ducky" Lotts
  9. * @since 2013-Jul-8
  10. */
  11. ;(function (root, factory) {
  12. 'use strict'
  13. /* istanbul ignore if */
  14. if (typeof module !== 'undefined' && module.exports) {
  15. var ng = typeof angular === 'undefined' ? require('angular') : angular
  16. var mt = typeof moment === 'undefined' ? require('moment') : moment
  17. factory(ng, mt)
  18. module.exports = 'ui.bootstrap.datetimepicker'
  19. /* istanbul ignore next */
  20. } else if (typeof define === 'function' && /* istanbul ignore next */ define.amd) {
  21. define(['angular', 'moment'], factory)
  22. } else {
  23. factory(root.angular, root.moment)
  24. }
  25. }(this, function (angular, moment) {
  26. 'use strict'
  27. angular.module('ui.bootstrap.datetimepicker', [])
  28. .service('dateTimePickerConfig', DateTimePickerConfigProvider)
  29. .service('dateTimePickerValidator', DateTimePickerValidatorService)
  30. .directive('datetimepicker', DatetimepickerDirective)
  31. DatetimepickerDirective.$inject = ['dateTimePickerConfig', 'dateTimePickerValidator']
  32. function DatetimepickerDirective (defaultConfig, configurationValidator) {
  33. var directiveDefinition = {
  34. bindToController: false,
  35. controller: DirectiveController,
  36. controllerAs: 'dateTimePickerController',
  37. replace: true,
  38. require: 'ngModel',
  39. restrict: 'E',
  40. scope: {
  41. beforeRender: '&',
  42. onSetTime: '&'
  43. },
  44. templateUrl: 'templates/datetimepicker.html'
  45. }
  46. DirectiveController.$inject = ['$scope', '$element', '$attrs']
  47. function DirectiveController ($scope, $element, $attrs) {
  48. // Configuration
  49. var ngModelController = $element.controller('ngModel')
  50. var configuration = createConfiguration()
  51. $scope.screenReader = configuration.screenReader
  52. // Behavior
  53. $scope.changeView = changeView
  54. ngModelController.$render = $render
  55. if (configuration.configureOn) {
  56. $scope.$on(configuration.configureOn, function () {
  57. configuration = createConfiguration()
  58. $scope.screenReader = configuration.screenReader
  59. ngModelController.$render()
  60. })
  61. }
  62. if (configuration.renderOn) {
  63. $scope.$on(configuration.renderOn, ngModelController.$render)
  64. }
  65. // Implementation
  66. var viewToModelFactory = {
  67. year: yearModelFactory,
  68. month: monthModelFactory,
  69. day: dayModelFactory,
  70. hour: hourModelFactory,
  71. minute: minuteModelFactory,
  72. setTime: setTime
  73. }
  74. function changeView (viewName, dateObject, event) {
  75. if (event) {
  76. event.stopPropagation()
  77. event.preventDefault()
  78. }
  79. if (viewName && (dateObject.utcDateValue > -Infinity) && dateObject.selectable && viewToModelFactory[viewName]) {
  80. var result = viewToModelFactory[viewName](dateObject.utcDateValue)
  81. var weekDates = []
  82. if (result.weeks) {
  83. for (var i = 0; i < result.weeks.length; i += 1) {
  84. var week = result.weeks[i]
  85. for (var j = 0; j < week.dates.length; j += 1) {
  86. var weekDate = week.dates[j]
  87. weekDates.push(weekDate)
  88. }
  89. }
  90. }
  91. $scope.beforeRender({
  92. $view: result.currentView,
  93. $dates: result.dates || weekDates,
  94. $leftDate: result.leftDate,
  95. $upDate: result.previousViewDate,
  96. $rightDate: result.rightDate
  97. })
  98. $scope.data = result
  99. }
  100. }
  101. function yearModelFactory (milliseconds) {
  102. var selectedDate = moment.utc(milliseconds).startOf('year')
  103. // View starts one year before the decade starts and ends one year after the decade ends
  104. // i.e. passing in a date of 1/1/2013 will give a range of 2009 to 2020
  105. // Truncate the last digit from the current year and subtract 1 to get the start of the decade
  106. var startDecade = (parseInt(selectedDate.year() / 10, 10) * 10)
  107. var startDate = moment.utc(startOfDecade(milliseconds)).subtract(1, 'year').startOf('year')
  108. var yearFormat = 'YYYY'
  109. var activeFormat = formatValue(ngModelController.$modelValue, yearFormat)
  110. var currentFormat = moment().format(yearFormat)
  111. var result = {
  112. 'currentView': 'year',
  113. 'nextView': configuration.minView === 'year' ? 'setTime' : 'month',
  114. 'previousViewDate': new DateObject({
  115. utcDateValue: null,
  116. display: startDecade + '-' + (startDecade + 9)
  117. }),
  118. 'leftDate': new DateObject({utcDateValue: moment.utc(startDate).subtract(9, 'year').valueOf()}),
  119. 'rightDate': new DateObject({utcDateValue: moment.utc(startDate).add(11, 'year').valueOf()}),
  120. 'dates': []
  121. }
  122. for (var i = 0; i < 12; i += 1) {
  123. var yearMoment = moment.utc(startDate).add(i, 'years')
  124. var dateValue = {
  125. 'active': yearMoment.format(yearFormat) === activeFormat,
  126. 'current': yearMoment.format(yearFormat) === currentFormat,
  127. 'display': yearMoment.format(yearFormat),
  128. 'future': yearMoment.year() > startDecade + 9,
  129. 'past': yearMoment.year() < startDecade,
  130. 'utcDateValue': yearMoment.valueOf()
  131. }
  132. result.dates.push(new DateObject(dateValue))
  133. }
  134. return result
  135. }
  136. function monthModelFactory (milliseconds) {
  137. var startDate = moment.utc(milliseconds).startOf('year')
  138. var previousViewDate = startOfDecade(milliseconds)
  139. var monthFormat = 'YYYY-MMM'
  140. var activeFormat = formatValue(ngModelController.$modelValue, monthFormat)
  141. var currentFormat = moment().format(monthFormat)
  142. var result = {
  143. 'previousView': 'year',
  144. 'currentView': 'month',
  145. 'nextView': configuration.minView === 'month' ? 'setTime' : 'day',
  146. 'previousViewDate': new DateObject({
  147. utcDateValue: previousViewDate.valueOf(),
  148. display: startDate.format('YYYY')
  149. }),
  150. 'leftDate': new DateObject({utcDateValue: moment.utc(startDate).subtract(1, 'year').valueOf()}),
  151. 'rightDate': new DateObject({utcDateValue: moment.utc(startDate).add(1, 'year').valueOf()}),
  152. 'dates': []
  153. }
  154. for (var i = 0; i < 12; i += 1) {
  155. var monthMoment = moment.utc(startDate).add(i, 'months')
  156. var dateValue = {
  157. 'active': monthMoment.format(monthFormat) === activeFormat,
  158. 'current': monthMoment.format(monthFormat) === currentFormat,
  159. 'display': monthMoment.format('MMM'),
  160. 'utcDateValue': monthMoment.valueOf()
  161. }
  162. result.dates.push(new DateObject(dateValue))
  163. }
  164. return result
  165. }
  166. function dayModelFactory (milliseconds) {
  167. var selectedDate = moment.utc(milliseconds)
  168. var startOfMonth = moment.utc(selectedDate).startOf('month')
  169. var previousViewDate = moment.utc(selectedDate).startOf('year')
  170. var endOfMonth = moment.utc(selectedDate).endOf('month')
  171. var startDate = moment.utc(startOfMonth).subtract(Math.abs(startOfMonth.weekday()), 'days')
  172. var dayFormat = 'YYYY-MMM-DD'
  173. var activeFormat = formatValue(ngModelController.$modelValue, dayFormat)
  174. var currentFormat = moment().format(dayFormat)
  175. var result = {
  176. 'previousView': 'month',
  177. 'currentView': 'day',
  178. 'nextView': configuration.minView === 'day' ? 'setTime' : 'hour',
  179. 'previousViewDate': new DateObject({
  180. utcDateValue: previousViewDate.valueOf(),
  181. display: startOfMonth.format('YYYY-MMM')
  182. }),
  183. 'leftDate': new DateObject({utcDateValue: moment.utc(startOfMonth).subtract(1, 'months').valueOf()}),
  184. 'rightDate': new DateObject({utcDateValue: moment.utc(startOfMonth).add(1, 'months').valueOf()}),
  185. 'dayNames': [],
  186. 'weeks': []
  187. }
  188. for (var dayNumber = 0; dayNumber < 7; dayNumber += 1) {
  189. result.dayNames.push(moment.utc().weekday(dayNumber).format('dd'))
  190. }
  191. for (var i = 0; i < 6; i += 1) {
  192. var week = {dates: []}
  193. for (var j = 0; j < 7; j += 1) {
  194. var dayMoment = moment.utc(startDate).add((i * 7) + j, 'days')
  195. var dateValue = {
  196. 'active': dayMoment.format(dayFormat) === activeFormat,
  197. 'current': dayMoment.format(dayFormat) === currentFormat,
  198. 'display': dayMoment.format('D'),
  199. 'future': dayMoment.isAfter(endOfMonth),
  200. 'past': dayMoment.isBefore(startOfMonth),
  201. 'utcDateValue': dayMoment.valueOf()
  202. }
  203. week.dates.push(new DateObject(dateValue))
  204. }
  205. result.weeks.push(week)
  206. }
  207. return result
  208. }
  209. function hourModelFactory (milliseconds) {
  210. var selectedDate = moment.utc(milliseconds).startOf('day')
  211. var previousViewDate = moment.utc(selectedDate).startOf('month')
  212. var hourFormat = 'YYYY-MM-DD H'
  213. var activeFormat = formatValue(ngModelController.$modelValue, hourFormat)
  214. var currentFormat = moment().format(hourFormat)
  215. var result = {
  216. 'previousView': 'day',
  217. 'currentView': 'hour',
  218. 'nextView': configuration.minView === 'hour' ? 'setTime' : 'minute',
  219. 'previousViewDate': new DateObject({
  220. utcDateValue: previousViewDate.valueOf(),
  221. display: selectedDate.format('ll')
  222. }),
  223. 'leftDate': new DateObject({utcDateValue: moment.utc(selectedDate).subtract(1, 'days').valueOf()}),
  224. 'rightDate': new DateObject({utcDateValue: moment.utc(selectedDate).add(1, 'days').valueOf()}),
  225. 'dates': []
  226. }
  227. for (var i = 0; i < 24; i += 1) {
  228. var hourMoment = moment.utc(selectedDate).add(i, 'hours')
  229. var dateValue = {
  230. 'active': hourMoment.format(hourFormat) === activeFormat,
  231. 'current': hourMoment.format(hourFormat) === currentFormat,
  232. 'display': hourMoment.format('LT'),
  233. 'utcDateValue': hourMoment.valueOf()
  234. }
  235. result.dates.push(new DateObject(dateValue))
  236. }
  237. return result
  238. }
  239. function minuteModelFactory (milliseconds) {
  240. var selectedDate = moment.utc(milliseconds).startOf('hour')
  241. var previousViewDate = moment.utc(selectedDate).startOf('day')
  242. var minuteFormat = 'YYYY-MM-DD H:mm'
  243. var activeFormat = formatValue(ngModelController.$modelValue, minuteFormat)
  244. var currentFormat = moment().format(minuteFormat)
  245. var result = {
  246. 'previousView': 'hour',
  247. 'currentView': 'minute',
  248. 'nextView': 'setTime',
  249. 'previousViewDate': new DateObject({
  250. utcDateValue: previousViewDate.valueOf(),
  251. display: selectedDate.format('lll')
  252. }),
  253. 'leftDate': new DateObject({utcDateValue: moment.utc(selectedDate).subtract(1, 'hours').valueOf()}),
  254. 'rightDate': new DateObject({utcDateValue: moment.utc(selectedDate).add(1, 'hours').valueOf()}),
  255. 'dates': []
  256. }
  257. var limit = 60 / configuration.minuteStep
  258. for (var i = 0; i < limit; i += 1) {
  259. var hourMoment = moment.utc(selectedDate).add(i * configuration.minuteStep, 'minute')
  260. var dateValue = {
  261. 'active': hourMoment.format(minuteFormat) === activeFormat,
  262. 'current': hourMoment.format(minuteFormat) === currentFormat,
  263. 'display': hourMoment.format('LT'),
  264. 'utcDateValue': hourMoment.valueOf()
  265. }
  266. result.dates.push(new DateObject(dateValue))
  267. }
  268. return result
  269. }
  270. function setTime (milliseconds) {
  271. var tempDate = new Date(milliseconds)
  272. var newDate = new Date(tempDate.getUTCFullYear(), tempDate.getUTCMonth(), tempDate.getUTCDate(), tempDate.getUTCHours(), tempDate.getUTCMinutes(), tempDate.getUTCSeconds(), tempDate.getUTCMilliseconds())
  273. switch (configuration.modelType) {
  274. case 'Date':
  275. // No additional work needed
  276. break
  277. case 'moment':
  278. newDate = moment([tempDate.getUTCFullYear(), tempDate.getUTCMonth(), tempDate.getUTCDate(), tempDate.getUTCHours(), tempDate.getUTCMinutes(), tempDate.getUTCSeconds(), tempDate.getUTCMilliseconds()])
  279. break
  280. case 'milliseconds':
  281. newDate = milliseconds
  282. break
  283. default: // It is assumed that the modelType is a formatting string.
  284. newDate = moment([tempDate.getUTCFullYear(), tempDate.getUTCMonth(), tempDate.getUTCDate(), tempDate.getUTCHours(), tempDate.getUTCMinutes(), tempDate.getUTCSeconds(), tempDate.getUTCMilliseconds()]).format(configuration.modelType)
  285. }
  286. var oldDate = ngModelController.$modelValue
  287. ngModelController.$setViewValue(newDate)
  288. if (configuration.dropdownSelector) {
  289. jQuery(configuration.dropdownSelector).dropdown('toggle')
  290. }
  291. $scope.onSetTime({newDate: newDate, oldDate: oldDate})
  292. return viewToModelFactory[configuration.startView](milliseconds)
  293. }
  294. function $render () {
  295. $scope.changeView(configuration.startView, new DateObject({utcDateValue: getUTCTime(ngModelController.$viewValue)}))
  296. }
  297. function startOfDecade (milliseconds) {
  298. var startYear = (parseInt(moment.utc(milliseconds).year() / 10, 10) * 10)
  299. return moment.utc(milliseconds).year(startYear).startOf('year')
  300. }
  301. function formatValue (timeValue, formatString) {
  302. if (timeValue) {
  303. return getMoment(timeValue).format(formatString)
  304. } else {
  305. return ''
  306. }
  307. }
  308. /**
  309. * Converts a time value into a moment.
  310. *
  311. * This function is now necessary because moment logs a warning when parsing a string without a format.
  312. * @param modelValue
  313. * a time value in any of the supported formats (Date, moment, milliseconds, and string)
  314. * @returns {moment}
  315. * representing the specified time value.
  316. */
  317. function getMoment (modelValue) {
  318. return moment(modelValue, angular.isString(modelValue) ? configuration.parseFormat : undefined)
  319. }
  320. /**
  321. * Converts a time value to UCT/GMT time.
  322. * @param modelValue
  323. * a time value in any of the supported formats (Date, moment, milliseconds, and string)
  324. * @returns {number}
  325. * number of milliseconds since 1/1/1970
  326. */
  327. function getUTCTime (modelValue) {
  328. var tempDate = new Date()
  329. if (modelValue) {
  330. var tempMoment = getMoment(modelValue)
  331. if (tempMoment.isValid()) {
  332. tempDate = tempMoment.toDate()
  333. } else {
  334. throw new Error('Invalid date: ' + modelValue)
  335. }
  336. }
  337. return tempDate.getTime() - (tempDate.getTimezoneOffset() * 60000)
  338. }
  339. function createConfiguration () {
  340. var directiveConfig = {}
  341. if ($attrs.datetimepickerConfig) {
  342. directiveConfig = $scope.$parent.$eval($attrs.datetimepickerConfig)
  343. }
  344. var configuration = angular.extend({}, defaultConfig, directiveConfig)
  345. configurationValidator.validate(configuration)
  346. return configuration
  347. }
  348. }
  349. function DateObject () {
  350. var tempDate = new Date(arguments[0].utcDateValue)
  351. var localOffset = tempDate.getTimezoneOffset() * 60000
  352. this.utcDateValue = tempDate.getTime()
  353. this.selectable = true
  354. this.localDateValue = function localDateValue () {
  355. return this.utcDateValue + localOffset
  356. }
  357. var validProperties = ['active', 'current', 'display', 'future', 'past', 'selectable', 'utcDateValue']
  358. var constructorObject = arguments[0]
  359. Object.keys(constructorObject).filter(function (key) {
  360. return validProperties.indexOf(key) >= 0
  361. }).forEach(function (key) {
  362. this[key] = constructorObject[key]
  363. }, this)
  364. }
  365. return directiveDefinition
  366. }
  367. function DateTimePickerConfigProvider () {
  368. var defaultConfiguration = {
  369. configureOn: null,
  370. dropdownSelector: null,
  371. minuteStep: 5,
  372. minView: 'minute',
  373. modelType: 'Date',
  374. parseFormat: 'YYYY-MM-DDTHH:mm:ss.SSSZZ',
  375. renderOn: null,
  376. startView: 'day'
  377. }
  378. var defaultLocalization = {
  379. 'bg': {previous: 'предишна', next: 'следваща'},
  380. 'ca': {previous: 'anterior', next: 'següent'},
  381. 'da': {previous: 'forrige', next: 'næste'},
  382. 'de': {previous: 'vorige', next: 'weiter'},
  383. 'en-au': {previous: 'previous', next: 'next'},
  384. 'en-gb': {previous: 'previous', next: 'next'},
  385. 'en': {previous: 'previous', next: 'next'},
  386. 'es-us': {previous: 'atrás', next: 'siguiente'},
  387. 'es': {previous: 'atrás', next: 'siguiente'},
  388. 'fi': {previous: 'edellinen', next: 'seuraava'},
  389. 'fr': {previous: 'précédent', next: 'suivant'},
  390. 'hu': {previous: 'előző', next: 'következő'},
  391. 'it': {previous: 'precedente', next: 'successivo'},
  392. 'ja': {previous: '前へ', next: '次へ'},
  393. 'ml': {previous: 'മുൻപുള്ളത്', next: 'അടുത്തത്'},
  394. 'nl': {previous: 'vorige', next: 'volgende'},
  395. 'pl': {previous: 'poprzednia', next: 'następna'},
  396. 'pt-br': {previous: 'anteriores', next: 'próximos'},
  397. 'pt': {previous: 'anterior', next: 'próximo'},
  398. 'ro': {previous: 'anterior', next: 'următor'},
  399. 'ru': {previous: 'предыдущая', next: 'следующая'},
  400. 'sk': {previous: 'predošlá', next: 'ďalšia'},
  401. 'sv': {previous: 'föregående', next: 'nästa'},
  402. 'tr': {previous: 'önceki', next: 'sonraki'},
  403. 'uk': {previous: 'назад', next: 'далі'},
  404. 'zh-cn': {previous: '上一页', next: '下一页'},
  405. 'zh-tw': {previous: '上一頁', next: '下一頁'}
  406. }
  407. var screenReader = defaultLocalization[moment.locale().toLowerCase()]
  408. return angular.extend({}, defaultConfiguration, {screenReader: screenReader})
  409. }
  410. DateTimePickerValidatorService.$inject = ['$log']
  411. function DateTimePickerValidatorService ($log) {
  412. return {
  413. validate: validator
  414. }
  415. function validator (configuration) {
  416. var validOptions = [
  417. 'configureOn',
  418. 'dropdownSelector',
  419. 'minuteStep',
  420. 'minView',
  421. 'modelType',
  422. 'parseFormat',
  423. 'renderOn',
  424. 'startView',
  425. 'screenReader'
  426. ]
  427. var invalidOptions = Object.keys(configuration).filter(function (key) {
  428. return (validOptions.indexOf(key) < 0)
  429. })
  430. if (invalidOptions.length) {
  431. throw new Error('Invalid options: ' + invalidOptions.join(', '))
  432. }
  433. // Order of the elements in the validViews array is significant.
  434. var validViews = ['minute', 'hour', 'day', 'month', 'year']
  435. if (validViews.indexOf(configuration.startView) < 0) {
  436. throw new Error('invalid startView value: ' + configuration.startView)
  437. }
  438. if (validViews.indexOf(configuration.minView) < 0) {
  439. throw new Error('invalid minView value: ' + configuration.minView)
  440. }
  441. if (validViews.indexOf(configuration.minView) > validViews.indexOf(configuration.startView)) {
  442. throw new Error('startView must be greater than minView')
  443. }
  444. if (!angular.isNumber(configuration.minuteStep)) {
  445. throw new Error('minuteStep must be numeric')
  446. }
  447. if (configuration.minuteStep <= 0 || configuration.minuteStep >= 60) {
  448. throw new Error('minuteStep must be greater than zero and less than 60')
  449. }
  450. if (configuration.configureOn !== null && !angular.isString(configuration.configureOn)) {
  451. throw new Error('configureOn must be a string')
  452. }
  453. if (configuration.configureOn !== null && configuration.configureOn.length < 1) {
  454. throw new Error('configureOn must not be an empty string')
  455. }
  456. if (configuration.renderOn !== null && !angular.isString(configuration.renderOn)) {
  457. throw new Error('renderOn must be a string')
  458. }
  459. if (configuration.renderOn !== null && configuration.renderOn.length < 1) {
  460. throw new Error('renderOn must not be an empty string')
  461. }
  462. if (configuration.modelType !== null && !angular.isString(configuration.modelType)) {
  463. throw new Error('modelType must be a string')
  464. }
  465. if (configuration.modelType !== null && configuration.modelType.length < 1) {
  466. throw new Error('modelType must not be an empty string')
  467. }
  468. if (configuration.modelType !== 'Date' && configuration.modelType !== 'moment' && configuration.modelType !== 'milliseconds') {
  469. // modelType contains string format, overriding parseFormat with modelType
  470. configuration.parseFormat = configuration.modelType
  471. }
  472. if (configuration.dropdownSelector !== null && !angular.isString(configuration.dropdownSelector)) {
  473. throw new Error('dropdownSelector must be a string')
  474. }
  475. /* istanbul ignore next */
  476. if (configuration.dropdownSelector !== null && ((typeof jQuery === 'undefined') || (typeof jQuery().dropdown !== 'function'))) {
  477. $log.error('Please DO NOT specify the dropdownSelector option unless you are using jQuery AND Bootstrap.js. ' +
  478. 'Please include jQuery AND Bootstrap.js, or write code to close the dropdown in the on-set-time callback. \n\n' +
  479. 'The dropdownSelector configuration option is being removed because it will not function properly.')
  480. delete configuration.dropdownSelector
  481. }
  482. }
  483. }
  484. })); // eslint-disable-line semi
  485. //todo datetimepicker.templates.js 在异步加载首次运行有问题,只能将其直接合并。。。
  486. 'use strict'
  487. angular.module('ui.bootstrap.datetimepicker').run(['$templateCache', function ($templateCache) {
  488. $templateCache.put('templates/datetimepicker.html', '<div class="datetimepicker table-responsive">\n <table class="table table-condensed {{ data.currentView }}-view">\n <thead>\n <tr>\n <th class="left" data-ng-click="changeView(data.currentView, data.leftDate, $event)" data-ng-show="data.leftDate.selectable"><i class="glyphicon glyphicon-arrow-left"><span class="sr-only">{{ screenReader.previous }}</span></i>\n </th>\n <th class="switch" colspan="5" data-ng-show="data.previousViewDate.selectable" data-ng-click="changeView(data.previousView, data.previousViewDate, $event)">{{ data.previousViewDate.display }}</th>\n <th class="right" data-ng-click="changeView(data.currentView, data.rightDate, $event)" data-ng-show="data.rightDate.selectable"><i class="glyphicon glyphicon-arrow-right"><span class="sr-only">{{ screenReader.next }}</span></i>\n </th>\n </tr>\n <tr>\n <th class="dow" data-ng-repeat="day in data.dayNames">{{ day }}</th>\n </tr>\n </thead>\n <tbody>\n <tr data-ng-if="data.currentView !== \'day\'">\n <td colspan="7">\n <span class="{{ data.currentView }}" data-ng-repeat="dateObject in data.dates" data-ng-class="{current: dateObject.current, active: dateObject.active, past: dateObject.past, future: dateObject.future, disabled: !dateObject.selectable}" data-ng-click="changeView(data.nextView, dateObject, $event)">{{ dateObject.display }}</span></td>\n </tr>\n <tr data-ng-if="data.currentView === \'day\'" data-ng-repeat="week in data.weeks">\n <td data-ng-repeat="dateObject in week.dates" data-ng-click="changeView(data.nextView, dateObject, $event)" class="day" data-ng-class="{current: dateObject.current, active: dateObject.active, past: dateObject.past, future: dateObject.future, disabled: !dateObject.selectable}">{{ dateObject.display }}</td>\n </tr>\n </tbody>\n </table>\n</div>\n')
  489. }])