simple_form_datetimepicker 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e358a20cf9be74fe6274b634de177ce5d7f4d735
4
+ data.tar.gz: c60d8881114f83385c0980f9824dbb371ac0eef6
5
+ SHA512:
6
+ metadata.gz: 04a4310cbd606b469c6ad744dc9bb4f055cbbfcc40ed5b502c4e82a56ea45ae12955a17456461db326ba92ea9d3e7f271c21068f59d136ea95d7a70460caa824
7
+ data.tar.gz: e937a0a7ab039d25acfd235f2f3524e5e4e465589bb37ddb7bc7bafe44f977c8418cf159513efea42ebf3977c779757d9aff311dd1ac665513522e639e44f8bc
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ /.idea
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in simple_form_datetimepicker.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 smit1625
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # SimpleFormDatetimepicker
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'simple_form_datetimepicker'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install simple_form_datetimepicker
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,24 @@
1
+ require 'rails/generators'
2
+
3
+ module SimpleFormDatetimepicker
4
+ module Generators
5
+ class InstallGenerator < ::Rails::Generators::Base
6
+ desc "Installs SimpleFormDatetimepicker"
7
+
8
+ def self.source_root
9
+ @source_root ||= File.join(File.dirname(__FILE__), 'templates')
10
+ end
11
+
12
+ def copy_initializer
13
+ copy_file 'simple_form_datetimepicker.rb', 'config/initializers/simple_form_datetimepicker.rb'
14
+ inject_into_file 'app/assets/javascripts/application.js', :before => '//= require_tree .' do
15
+ "//= require simple_form_datetimepicker/init\n"
16
+ end
17
+ inject_into_file 'app/assets/stylesheets/application.css', :before => ' *= require_self' do
18
+ " *= require bootstrap-datetimepicker\n"
19
+ end
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,29 @@
1
+ module SimpleForm
2
+ module Inputs
3
+ class DateTimeInput < Base
4
+ def input
5
+ icon = input_html_options.delete(:icon) || 'glyphicon-calendar'
6
+ icon_lib = input_html_options.delete(:iconlib) || icon.split('-')[0]
7
+ defaultvalue = input_html_options.delete(:defaultvalue)
8
+ if defaultvalue.present? && defaultvalue.is_a?(Hash)
9
+ day_offset = defaultvalue.delete(:day_offset)
10
+ defaulttime = Time.zone.now.change(defaultvalue)
11
+ defaulttime += day_offset.days if day_offset.present?
12
+ defaultvalue = defaulttime
13
+ end
14
+ input_html_options[:class] << 'dtp'
15
+ if input_html_options.key?(:data)
16
+ input_html_options[:data][:defaultvalue] = defaultvalue if defaultvalue.present?
17
+ else
18
+ input_html_options[:data] = {:defaultvalue => defaultvalue} if defaultvalue.present?
19
+ end
20
+ out = '<div class="input-group">'
21
+ out << @builder.text_field(attribute_name, input_html_options)
22
+ out << '<span class="input-group-addon">'
23
+ out << "<span class='#{icon_lib} #{icon}'></span>"
24
+ out << '</span>'
25
+ (out << '</div>').html_safe
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,6 @@
1
+ require 'simple_form_datetimepicker/version'
2
+
3
+ module SimpleFormDatetimepicker
4
+ class Engine < ::Rails::Engine
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module SimpleFormDatetimepicker
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'simple_form_datetimepicker/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "simple_form_datetimepicker"
8
+ spec.version = SimpleFormDatetimepicker::VERSION
9
+ spec.authors = ["smit1625"]
10
+ spec.email = ["smit1625@msu.edu"]
11
+ spec.description = %q{Beautifies the default datetime input for SimpleForm}
12
+ spec.summary = %q{Uses bootstrap-datetimepicker to enhance SimpleForm's default datetime input}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_dependency "railties"
24
+ spec.add_dependency "simple_form"
25
+ spec.add_dependency "american_date"
26
+ end
@@ -0,0 +1,1222 @@
1
+ /*
2
+ Version 3.0.0
3
+ =========================================================
4
+ bootstrap-datetimepicker.js
5
+ https://github.com/Eonasdan/bootstrap-datetimepicker
6
+ =========================================================
7
+ The MIT License (MIT)
8
+
9
+ Copyright (c) 2014 Jonathan Peterson
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in
19
+ all copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
+ THE SOFTWARE.
28
+ */
29
+ ; (function (factory) {
30
+ if (typeof define === 'function' && define.amd) {
31
+ // AMD is used - Register as an anonymous module.
32
+ define(['jquery', 'moment'], factory);
33
+ } else {
34
+ // AMD is not used - Attempt to fetch dependencies from scope.
35
+ if (!jQuery) {
36
+ throw 'bootstrap-datetimepicker requires jQuery to be loaded first';
37
+ } else if (!moment) {
38
+ throw 'bootstrap-datetimepicker requires moment.js to be loaded first';
39
+ } else {
40
+ factory(jQuery, moment);
41
+ }
42
+ }
43
+ }
44
+
45
+ (function ($, moment) {
46
+ if (typeof moment === 'undefined') {
47
+ alert("momentjs is requried");
48
+ throw new Error('momentjs is required');
49
+ };
50
+
51
+ var dpgId = 0,
52
+
53
+ pMoment = moment,
54
+
55
+ // ReSharper disable once InconsistentNaming
56
+ DateTimePicker = function (element, options) {
57
+ var defaults = {
58
+ pickDate: true,
59
+ pickTime: true,
60
+ useMinutes: true,
61
+ useSeconds: false,
62
+ useCurrent: true,
63
+ minuteStepping: 1,
64
+ minDate: new pMoment({ y: 1900 }),
65
+ maxDate: new pMoment().add(100, "y"),
66
+ showToday: true,
67
+ collapse: true,
68
+ language: "en",
69
+ defaultDate: "",
70
+ disabledDates: false,
71
+ enabledDates: false,
72
+ icons: {},
73
+ useStrict: false,
74
+ direction: "auto",
75
+ sideBySide: false,
76
+ daysOfWeekDisabled: false
77
+ },
78
+
79
+ icons = {
80
+ time: 'glyphicon glyphicon-time',
81
+ date: 'glyphicon glyphicon-calendar',
82
+ up: 'glyphicon glyphicon-chevron-up',
83
+ down: 'glyphicon glyphicon-chevron-down'
84
+ },
85
+
86
+ picker = this,
87
+
88
+ init = function () {
89
+
90
+ var icon = false, i, dDate, longDateFormat;
91
+ picker.options = $.extend({}, defaults, options);
92
+ picker.options.icons = $.extend({}, icons, picker.options.icons);
93
+
94
+ picker.element = $(element);
95
+
96
+ dataToOptions();
97
+
98
+ if (!(picker.options.pickTime || picker.options.pickDate))
99
+ throw new Error('Must choose at least one picker');
100
+
101
+ picker.id = dpgId++;
102
+ pMoment.lang(picker.options.language);
103
+ picker.date = pMoment();
104
+ picker.unset = false;
105
+ picker.isInput = picker.element.is('input');
106
+ picker.component = false;
107
+
108
+ if (picker.element.hasClass('input-group')) {
109
+ if (picker.element.find('.datepickerbutton').size() == 0) {//in case there is more then one 'input-group-addon' Issue #48
110
+ picker.component = picker.element.find("[class^='input-group-']");
111
+ }
112
+ else {
113
+ picker.component = picker.element.find('.datepickerbutton');
114
+ }
115
+ }
116
+ picker.format = picker.options.format;
117
+
118
+ longDateFormat = pMoment()._lang._longDateFormat;
119
+
120
+ if (!picker.format) {
121
+ picker.format = (picker.options.pickDate ? longDateFormat.L : '');
122
+ if (picker.options.pickDate && picker.options.pickTime) picker.format += ' ';
123
+ picker.format += (picker.options.pickTime ? longDateFormat.LT : '');
124
+ if (picker.options.useSeconds) {
125
+ if (~longDateFormat.LT.indexOf(' A')) {
126
+ picker.format = picker.format.split(" A")[0] + ":ss A";
127
+ }
128
+ else {
129
+ picker.format += ':ss';
130
+ }
131
+ }
132
+ }
133
+ picker.use24hours = picker.format.toLowerCase().indexOf("a") < 1;
134
+
135
+ if (picker.component) icon = picker.component.find('span');
136
+
137
+ if (picker.options.pickTime) {
138
+ if (icon) icon.addClass(picker.options.icons.time);
139
+ }
140
+ if (picker.options.pickDate) {
141
+ if (icon) {
142
+ icon.removeClass(picker.options.icons.time);
143
+ icon.addClass(picker.options.icons.date);
144
+ }
145
+ }
146
+
147
+ picker.widget = $(getTemplate()).appendTo('body');
148
+
149
+ if (picker.options.useSeconds && !picker.use24hours) {
150
+ picker.widget.width(300);
151
+ }
152
+
153
+ picker.minViewMode = picker.options.minViewMode || 0;
154
+ if (typeof picker.minViewMode === 'string') {
155
+ switch (picker.minViewMode) {
156
+ case 'months':
157
+ picker.minViewMode = 1;
158
+ break;
159
+ case 'years':
160
+ picker.minViewMode = 2;
161
+ break;
162
+ default:
163
+ picker.minViewMode = 0;
164
+ break;
165
+ }
166
+ }
167
+ picker.viewMode = picker.options.viewMode || 0;
168
+ if (typeof picker.viewMode === 'string') {
169
+ switch (picker.viewMode) {
170
+ case 'months':
171
+ picker.viewMode = 1;
172
+ break;
173
+ case 'years':
174
+ picker.viewMode = 2;
175
+ break;
176
+ default:
177
+ picker.viewMode = 0;
178
+ break;
179
+ }
180
+ }
181
+
182
+ picker.options.disabledDates = indexGivenDates(picker.options.disabledDates);
183
+ picker.options.enabledDates = indexGivenDates(picker.options.enabledDates);
184
+
185
+ picker.startViewMode = picker.viewMode;
186
+ picker.setMinDate(picker.options.minDate);
187
+ picker.setMaxDate(picker.options.maxDate);
188
+ fillDow();
189
+ fillMonths();
190
+ fillHours();
191
+ fillMinutes();
192
+ fillSeconds();
193
+ update();
194
+ showMode();
195
+ attachDatePickerEvents();
196
+ if (picker.options.defaultDate !== "" && getPickerInput().val() == "") picker.setValue(picker.options.defaultDate);
197
+ if (picker.options.minuteStepping !== 1) {
198
+ var rInterval = picker.options.minuteStepping;
199
+ picker.date.minutes((Math.round(picker.date.minutes() / rInterval) * rInterval) % 60).seconds(0);
200
+ }
201
+ },
202
+
203
+ getPickerInput = function () {
204
+ if (picker.isInput) {
205
+ return picker.element;
206
+ } else {
207
+ return dateStr = picker.element.find('input');
208
+ }
209
+ },
210
+
211
+ dataToOptions = function () {
212
+ var eData
213
+ if (picker.element.is('input')) {
214
+ eData = picker.element.data();
215
+ }
216
+ else {
217
+ eData = picker.element.data();
218
+ }
219
+ if (eData.dateFormat !== undefined) picker.options.format = eData.dateFormat;
220
+ if (eData.datePickdate !== undefined) picker.options.pickDate = eData.datePickdate;
221
+ if (eData.datePicktime !== undefined) picker.options.pickTime = eData.datePicktime;
222
+ if (eData.dateUseminutes !== undefined) picker.options.useMinutes = eData.dateUseminutes;
223
+ if (eData.dateUseseconds !== undefined) picker.options.useSeconds = eData.dateUseseconds;
224
+ if (eData.dateUsecurrent !== undefined) picker.options.useCurrent = eData.dateUsecurrent;
225
+ if (eData.dateMinutestepping !== undefined) picker.options.minuteStepping = eData.dateMinutestepping;
226
+ if (eData.dateMindate !== undefined) picker.options.minDate = eData.dateMindate;
227
+ if (eData.dateMaxdate !== undefined) picker.options.maxDate = eData.dateMaxdate;
228
+ if (eData.dateShowtoday !== undefined) picker.options.showToday = eData.dateShowtoday;
229
+ if (eData.dateCollapse !== undefined) picker.options.collapse = eData.dateCollapse;
230
+ if (eData.dateLanguage !== undefined) picker.options.language = eData.dateLanguage;
231
+ if (eData.dateDefaultdate !== undefined) picker.options.defaultDate = eData.dateDefaultdate;
232
+ if (eData.dateDisableddates !== undefined) picker.options.disabledDates = eData.dateDisableddates;
233
+ if (eData.dateEnableddates !== undefined) picker.options.enabledDates = eData.dateEnableddates;
234
+ if (eData.dateIcons !== undefined) picker.options.icons = eData.dateIcons;
235
+ if (eData.dateUsestrict !== undefined) picker.options.useStrict = eData.dateUsestrict;
236
+ if (eData.dateDirection !== undefined) picker.options.direction = eData.dateDirection;
237
+ if (eData.dateSidebyside !== undefined) picker.options.sideBySide = eData.dateSidebyside;
238
+ },
239
+
240
+ place = function () {
241
+ var position = 'absolute',
242
+ offset = picker.component ? picker.component.offset() : picker.element.offset(), $window = $(window);
243
+ picker.width = picker.component ? picker.component.outerWidth() : picker.element.outerWidth();
244
+ offset.top = offset.top + picker.element.outerHeight();
245
+
246
+ var placePosition;
247
+ if (picker.options.direction === 'up') {
248
+ placePosition = 'top'
249
+ } else if (picker.options.direction === 'bottom') {
250
+ placePosition = 'bottom'
251
+ } else if (picker.options.direction === 'auto') {
252
+ if (offset.top + picker.widget.height() > $window.height() + $window.scrollTop() && picker.widget.height() + picker.element.outerHeight() < offset.top) {
253
+ placePosition = 'top';
254
+ } else {
255
+ placePosition = 'bottom';
256
+ }
257
+ };
258
+ if (placePosition === 'top') {
259
+ offset.top -= picker.widget.height() + picker.element.outerHeight() + 15;
260
+ picker.widget.addClass('top').removeClass('bottom');
261
+ } else {
262
+ offset.top += 1;
263
+ picker.widget.addClass('bottom').removeClass('top');
264
+ }
265
+
266
+ if (picker.options.width !== undefined) {
267
+ picker.widget.width(picker.options.width);
268
+ }
269
+
270
+ if (picker.options.orientation === 'left') {
271
+ picker.widget.addClass('left-oriented');
272
+ offset.left = offset.left - picker.widget.width() + 20;
273
+ }
274
+
275
+ if (isInFixed()) {
276
+ position = 'fixed';
277
+ offset.top -= $window.scrollTop();
278
+ offset.left -= $window.scrollLeft();
279
+ }
280
+
281
+ if ($window.width() < offset.left + picker.widget.outerWidth()) {
282
+ offset.right = $window.width() - offset.left - picker.width;
283
+ offset.left = 'auto';
284
+ picker.widget.addClass('pull-right');
285
+ } else {
286
+ offset.right = 'auto';
287
+ picker.widget.removeClass('pull-right');
288
+ }
289
+
290
+ picker.widget.css({
291
+ position: position,
292
+ top: offset.top,
293
+ left: offset.left,
294
+ right: offset.right
295
+ });
296
+ },
297
+
298
+ notifyChange = function (oldDate, eventType) {
299
+ if (pMoment(picker.date).isSame(pMoment(oldDate))) return;
300
+ picker.element.trigger({
301
+ type: 'dp.change',
302
+ date: pMoment(picker.date),
303
+ oldDate: pMoment(oldDate)
304
+ });
305
+
306
+ if (eventType !== 'change')
307
+ picker.element.change();
308
+ },
309
+
310
+ notifyError = function (date) {
311
+ picker.element.trigger({
312
+ type: 'dp.error',
313
+ date: pMoment(date)
314
+ });
315
+ },
316
+
317
+ update = function (newDate) {
318
+ pMoment.lang(picker.options.language);
319
+ var dateStr = newDate;
320
+ if (!dateStr) {
321
+ dateStr = getPickerInput().val()
322
+ if (dateStr) picker.date = pMoment(dateStr, picker.format, picker.options.useStrict);
323
+ if (!picker.date) picker.date = pMoment();
324
+ }
325
+ picker.viewDate = pMoment(picker.date).startOf("month");
326
+ fillDate();
327
+ fillTime();
328
+ },
329
+
330
+ fillDow = function () {
331
+ pMoment.lang(picker.options.language);
332
+ var html = $('<tr>'), weekdaysMin = pMoment.weekdaysMin(), i;
333
+ if (pMoment()._lang._week.dow == 0) { // starts on Sunday
334
+ for (i = 0; i < 7; i++) {
335
+ html.append('<th class="dow">' + weekdaysMin[i] + '</th>');
336
+ }
337
+ } else {
338
+ for (i = 1; i < 8; i++) {
339
+ if (i == 7) {
340
+ html.append('<th class="dow">' + weekdaysMin[0] + '</th>');
341
+ } else {
342
+ html.append('<th class="dow">' + weekdaysMin[i] + '</th>');
343
+ }
344
+ }
345
+ }
346
+ picker.widget.find('.datepicker-days thead').append(html);
347
+ },
348
+
349
+ fillMonths = function () {
350
+ pMoment.lang(picker.options.language);
351
+ var html = '', i = 0, monthsShort = pMoment.monthsShort();
352
+ while (i < 12) {
353
+ html += '<span class="month">' + monthsShort[i++] + '</span>';
354
+ }
355
+ picker.widget.find('.datepicker-months td').append(html);
356
+ },
357
+
358
+ fillDate = function () {
359
+ if(!picker.options.pickDate) return;
360
+ pMoment.lang(picker.options.language);
361
+ var year = picker.viewDate.year(),
362
+ month = picker.viewDate.month(),
363
+ startYear = picker.options.minDate.year(),
364
+ startMonth = picker.options.minDate.month(),
365
+ endYear = picker.options.maxDate.year(),
366
+ endMonth = picker.options.maxDate.month(),
367
+ currentDate,
368
+ prevMonth, nextMonth, html = [], row, clsName, i, days, yearCont, currentYear, months = pMoment.months();
369
+
370
+ picker.widget.find('.datepicker-days').find('.disabled').removeClass('disabled');
371
+ picker.widget.find('.datepicker-months').find('.disabled').removeClass('disabled');
372
+ picker.widget.find('.datepicker-years').find('.disabled').removeClass('disabled');
373
+
374
+ picker.widget.find('.datepicker-days th:eq(1)').text(
375
+ months[month] + ' ' + year);
376
+
377
+ prevMonth = pMoment(picker.viewDate).subtract("months", 1);
378
+ days = prevMonth.daysInMonth();
379
+ prevMonth.date(days).startOf('week');
380
+ if ((year == startYear && month <= startMonth) || year < startYear) {
381
+ picker.widget.find('.datepicker-days th:eq(0)').addClass('disabled');
382
+ }
383
+ if ((year == endYear && month >= endMonth) || year > endYear) {
384
+ picker.widget.find('.datepicker-days th:eq(2)').addClass('disabled');
385
+ }
386
+
387
+ nextMonth = pMoment(prevMonth).add(42, "d");
388
+ while (prevMonth.isBefore(nextMonth)) {
389
+ if (prevMonth.weekday() === pMoment().startOf('week').weekday()) {
390
+ row = $('<tr>');
391
+ html.push(row);
392
+ }
393
+ clsName = '';
394
+ if (prevMonth.year() < year || (prevMonth.year() == year && prevMonth.month() < month)) {
395
+ clsName += ' old';
396
+ } else if (prevMonth.year() > year || (prevMonth.year() == year && prevMonth.month() > month)) {
397
+ clsName += ' new';
398
+ }
399
+ if (prevMonth.isSame(pMoment({ y: picker.date.year(), M: picker.date.month(), d: picker.date.date() }))) {
400
+ clsName += ' active';
401
+ }
402
+ if (isInDisableDates(prevMonth) || !isInEnableDates(prevMonth)) {
403
+ clsName += ' disabled';
404
+ }
405
+ if (picker.options.showToday === true) {
406
+ if (prevMonth.isSame(pMoment(), 'day')) {
407
+ clsName += ' today';
408
+ }
409
+ }
410
+ if (picker.options.daysOfWeekDisabled) {
411
+ for (i in picker.options.daysOfWeekDisabled) {
412
+ if (prevMonth.day() == picker.options.daysOfWeekDisabled[i]) {
413
+ clsName += ' disabled';
414
+ break;
415
+ }
416
+ }
417
+ }
418
+ row.append('<td class="day' + clsName + '">' + prevMonth.date() + '</td>');
419
+
420
+ currentDate = prevMonth.date();
421
+ prevMonth.add(1, "d");
422
+
423
+ if (currentDate == prevMonth.date()) {
424
+ prevMonth.add(1, "d");
425
+ }
426
+ }
427
+ picker.widget.find('.datepicker-days tbody').empty().append(html);
428
+ currentYear = picker.date.year(), months = picker.widget.find('.datepicker-months')
429
+ .find('th:eq(1)').text(year).end().find('span').removeClass('active');
430
+ if (currentYear === year) {
431
+ months.eq(picker.date.month()).addClass('active');
432
+ }
433
+ if (currentYear - 1 < startYear) {
434
+ picker.widget.find('.datepicker-months th:eq(0)').addClass('disabled');
435
+ }
436
+ if (currentYear + 1 > endYear) {
437
+ picker.widget.find('.datepicker-months th:eq(2)').addClass('disabled');
438
+ }
439
+ for (i = 0; i < 12; i++) {
440
+ if ((year == startYear && startMonth > i) || (year < startYear)) {
441
+ $(months[i]).addClass('disabled');
442
+ } else if ((year == endYear && endMonth < i) || (year > endYear)) {
443
+ $(months[i]).addClass('disabled');
444
+ }
445
+ }
446
+
447
+ html = '';
448
+ year = parseInt(year / 10, 10) * 10;
449
+ yearCont = picker.widget.find('.datepicker-years').find(
450
+ 'th:eq(1)').text(year + '-' + (year + 9)).end().find('td');
451
+ picker.widget.find('.datepicker-years').find('th').removeClass('disabled');
452
+ if (startYear > year) {
453
+ picker.widget.find('.datepicker-years').find('th:eq(0)').addClass('disabled');
454
+ }
455
+ if (endYear < year + 9) {
456
+ picker.widget.find('.datepicker-years').find('th:eq(2)').addClass('disabled');
457
+ }
458
+ year -= 1;
459
+ for (i = -1; i < 11; i++) {
460
+ html += '<span class="year' + (i === -1 || i === 10 ? ' old' : '') + (currentYear === year ? ' active' : '') + ((year < startYear || year > endYear) ? ' disabled' : '') + '">' + year + '</span>';
461
+ year += 1;
462
+ }
463
+ yearCont.html(html);
464
+ },
465
+
466
+ fillHours = function () {
467
+ pMoment.lang(picker.options.language);
468
+ var table = picker.widget.find('.timepicker .timepicker-hours table'), html = '', current, i, j;
469
+ table.parent().hide();
470
+ if (picker.use24hours) {
471
+ current = 0;
472
+ for (i = 0; i < 6; i += 1) {
473
+ html += '<tr>';
474
+ for (j = 0; j < 4; j += 1) {
475
+ html += '<td class="hour">' + padLeft(current.toString()) + '</td>';
476
+ current++;
477
+ }
478
+ html += '</tr>';
479
+ }
480
+ }
481
+ else {
482
+ current = 1;
483
+ for (i = 0; i < 3; i += 1) {
484
+ html += '<tr>';
485
+ for (j = 0; j < 4; j += 1) {
486
+ html += '<td class="hour">' + padLeft(current.toString()) + '</td>';
487
+ current++;
488
+ }
489
+ html += '</tr>';
490
+ }
491
+ }
492
+ table.html(html);
493
+ },
494
+
495
+ fillMinutes = function () {
496
+ var table = picker.widget.find('.timepicker .timepicker-minutes table'), html = '', current = 0, i, j, step = picker.options.minuteStepping;
497
+ table.parent().hide();
498
+ if (step == 1) step = 5;
499
+ for (i = 0; i < Math.ceil(60 / step / 4) ; i++) {
500
+ html += '<tr>';
501
+ for (j = 0; j < 4; j += 1) {
502
+ if (current < 60) {
503
+ html += '<td class="minute">' + padLeft(current.toString()) + '</td>';
504
+ current += step;
505
+ } else {
506
+ html += '<td></td>';
507
+ }
508
+ }
509
+ html += '</tr>';
510
+ }
511
+ table.html(html);
512
+ },
513
+
514
+ fillSeconds = function () {
515
+ var table = picker.widget.find('.timepicker .timepicker-seconds table'), html = '', current = 0, i, j;
516
+ table.parent().hide();
517
+ for (i = 0; i < 3; i++) {
518
+ html += '<tr>';
519
+ for (j = 0; j < 4; j += 1) {
520
+ html += '<td class="second">' + padLeft(current.toString()) + '</td>';
521
+ current += 5;
522
+ }
523
+ html += '</tr>';
524
+ }
525
+ table.html(html);
526
+ },
527
+
528
+ fillTime = function () {
529
+ if (!picker.date) return;
530
+ var timeComponents = picker.widget.find('.timepicker span[data-time-component]'),
531
+ hour = picker.date.hours(),
532
+ period = 'AM';
533
+ if (!picker.use24hours) {
534
+ if (hour >= 12) period = 'PM';
535
+ if (hour === 0) hour = 12;
536
+ else if (hour != 12) hour = hour % 12;
537
+ picker.widget.find('.timepicker [data-action=togglePeriod]').text(period);
538
+ }
539
+ timeComponents.filter('[data-time-component=hours]').text(padLeft(hour));
540
+ timeComponents.filter('[data-time-component=minutes]').text(padLeft(picker.date.minutes()));
541
+ timeComponents.filter('[data-time-component=seconds]').text(padLeft(picker.date.second()));
542
+ },
543
+
544
+ click = function (e) {
545
+ e.stopPropagation();
546
+ e.preventDefault();
547
+ picker.unset = false;
548
+ var target = $(e.target).closest('span, td, th'), month, year, step, day, oldDate = pMoment(picker.date);
549
+ if (target.length === 1) {
550
+ if (!target.is('.disabled')) {
551
+ switch (target[0].nodeName.toLowerCase()) {
552
+ case 'th':
553
+ switch (target[0].className) {
554
+ case 'switch':
555
+ showMode(1);
556
+ break;
557
+ case 'prev':
558
+ case 'next':
559
+ step = dpGlobal.modes[picker.viewMode].navStep;
560
+ if (target[0].className === 'prev') step = step * -1;
561
+ picker.viewDate.add(step, dpGlobal.modes[picker.viewMode].navFnc);
562
+ fillDate();
563
+ break;
564
+ }
565
+ break;
566
+ case 'span':
567
+ if (target.is('.month')) {
568
+ month = target.parent().find('span').index(target);
569
+ picker.viewDate.month(month);
570
+ } else {
571
+ year = parseInt(target.text(), 10) || 0;
572
+ picker.viewDate.year(year);
573
+ }
574
+ if (picker.viewMode === picker.minViewMode) {
575
+ picker.date = pMoment({
576
+ y: picker.viewDate.year(),
577
+ M: picker.viewDate.month(),
578
+ d: picker.viewDate.date(),
579
+ h: picker.date.hours(),
580
+ m: picker.date.minutes(),
581
+ s: picker.date.seconds()
582
+ });
583
+ notifyChange(oldDate, e.type);
584
+ set();
585
+ }
586
+ showMode(-1);
587
+ fillDate();
588
+ break;
589
+ case 'td':
590
+ if (target.is('.day')) {
591
+ day = parseInt(target.text(), 10) || 1;
592
+ month = picker.viewDate.month();
593
+ year = picker.viewDate.year();
594
+ if (target.is('.old')) {
595
+ if (month === 0) {
596
+ month = 11;
597
+ year -= 1;
598
+ } else {
599
+ month -= 1;
600
+ }
601
+ } else if (target.is('.new')) {
602
+ if (month == 11) {
603
+ month = 0;
604
+ year += 1;
605
+ } else {
606
+ month += 1;
607
+ }
608
+ }
609
+ picker.date = pMoment({
610
+ y: year,
611
+ M: month,
612
+ d: day,
613
+ h: picker.date.hours(),
614
+ m: picker.date.minutes(),
615
+ s: picker.date.seconds()
616
+ }
617
+ );
618
+ picker.viewDate = pMoment({
619
+ y: year, M: month, d: Math.min(28, day)
620
+ });
621
+ fillDate();
622
+ set();
623
+ notifyChange(oldDate, e.type);
624
+ }
625
+ break;
626
+ }
627
+ }
628
+ }
629
+ },
630
+
631
+ actions = {
632
+ incrementHours: function () {
633
+ checkDate("add", "hours", 1);
634
+ },
635
+
636
+ incrementMinutes: function () {
637
+ checkDate("add", "minutes", picker.options.minuteStepping);
638
+ },
639
+
640
+ incrementSeconds: function () {
641
+ checkDate("add", "seconds", 1);
642
+ },
643
+
644
+ decrementHours: function () {
645
+ checkDate("subtract", "hours", 1);
646
+ },
647
+
648
+ decrementMinutes: function () {
649
+ checkDate("subtract", "minutes", picker.options.minuteStepping);
650
+ },
651
+
652
+ decrementSeconds: function () {
653
+ checkDate("subtract", "seconds", 1);
654
+ },
655
+
656
+ togglePeriod: function () {
657
+ var hour = picker.date.hours();
658
+ if (hour >= 12) hour -= 12;
659
+ else hour += 12;
660
+ picker.date.hours(hour);
661
+ },
662
+
663
+ showPicker: function () {
664
+ picker.widget.find('.timepicker > div:not(.timepicker-picker)').hide();
665
+ picker.widget.find('.timepicker .timepicker-picker').show();
666
+ },
667
+
668
+ showHours: function () {
669
+ picker.widget.find('.timepicker .timepicker-picker').hide();
670
+ picker.widget.find('.timepicker .timepicker-hours').show();
671
+ },
672
+
673
+ showMinutes: function () {
674
+ picker.widget.find('.timepicker .timepicker-picker').hide();
675
+ picker.widget.find('.timepicker .timepicker-minutes').show();
676
+ },
677
+
678
+ showSeconds: function () {
679
+ picker.widget.find('.timepicker .timepicker-picker').hide();
680
+ picker.widget.find('.timepicker .timepicker-seconds').show();
681
+ },
682
+
683
+ selectHour: function (e) {
684
+ var period = picker.widget.find('.timepicker [data-action=togglePeriod]').text(), hour = parseInt($(e.target).text(), 10);
685
+ if (period == "PM") hour += 12
686
+ picker.date.hours(hour);
687
+ actions.showPicker.call(picker);
688
+ },
689
+
690
+ selectMinute: function (e) {
691
+ picker.date.minutes(parseInt($(e.target).text(), 10));
692
+ actions.showPicker.call(picker);
693
+ },
694
+
695
+ selectSecond: function (e) {
696
+ picker.date.seconds(parseInt($(e.target).text(), 10));
697
+ actions.showPicker.call(picker);
698
+ }
699
+ },
700
+
701
+ doAction = function (e) {
702
+ var oldDate = pMoment(picker.date), action = $(e.currentTarget).data('action'), rv = actions[action].apply(picker, arguments);
703
+ stopEvent(e);
704
+ if (!picker.date) picker.date = pMoment({ y: 1970 });
705
+ set();
706
+ fillTime();
707
+ notifyChange(oldDate, e.type);
708
+ return rv;
709
+ },
710
+
711
+ stopEvent = function (e) {
712
+ e.stopPropagation();
713
+ e.preventDefault();
714
+ },
715
+
716
+ change = function (e) {
717
+ pMoment.lang(picker.options.language);
718
+ var input = $(e.target), oldDate = pMoment(picker.date), newDate = pMoment(input.val(), picker.format, picker.options.useStrict);
719
+ if (newDate.isValid() && !isInDisableDates(newDate) && isInEnableDates(newDate)) {
720
+ update();
721
+ picker.setValue(newDate);
722
+ notifyChange(oldDate, e.type);
723
+ set();
724
+ }
725
+ else {
726
+ picker.viewDate = oldDate;
727
+ notifyChange(oldDate, e.type);
728
+ notifyError(newDate);
729
+ picker.unset = true;
730
+ }
731
+ },
732
+
733
+ showMode = function (dir) {
734
+ if (dir) {
735
+ picker.viewMode = Math.max(picker.minViewMode, Math.min(2, picker.viewMode + dir));
736
+ }
737
+ var f = dpGlobal.modes[picker.viewMode].clsName;
738
+ picker.widget.find('.datepicker > div').hide().filter('.datepicker-' + dpGlobal.modes[picker.viewMode].clsName).show();
739
+ },
740
+
741
+ attachDatePickerEvents = function () {
742
+ var $this, $parent, expanded, closed, collapseData;
743
+ picker.widget.on('click', '.datepicker *', $.proxy(click, this)); // this handles date picker clicks
744
+ picker.widget.on('click', '[data-action]', $.proxy(doAction, this)); // this handles time picker clicks
745
+ picker.widget.on('mousedown', $.proxy(stopEvent, this));
746
+ if (picker.options.pickDate && picker.options.pickTime) {
747
+ picker.widget.on('click.togglePicker', '.accordion-toggle', function (e) {
748
+ e.stopPropagation();
749
+ $this = $(this);
750
+ $parent = $this.closest('ul');
751
+ expanded = $parent.find('.in');
752
+ closed = $parent.find('.collapse:not(.in)');
753
+
754
+ if (expanded && expanded.length) {
755
+ collapseData = expanded.data('collapse');
756
+ if (collapseData && collapseData.date - transitioning) return;
757
+ expanded.collapse('hide');
758
+ closed.collapse('show');
759
+ $this.find('span').toggleClass(picker.options.icons.time + ' ' + picker.options.icons.date);
760
+ picker.element.find('.input-group-addon span').toggleClass(picker.options.icons.time + ' ' + picker.options.icons.date);
761
+ }
762
+ });
763
+ }
764
+ if (picker.isInput) {
765
+ picker.element.on({
766
+ 'focus': $.proxy(picker.show, this),
767
+ 'change': $.proxy(change, this),
768
+ 'blur': $.proxy(picker.hide, this)
769
+ });
770
+ } else {
771
+ picker.element.on({
772
+ 'change': $.proxy(change, this)
773
+ }, 'input');
774
+ if (picker.component) {
775
+ picker.component.on('click', $.proxy(picker.show, this));
776
+ } else {
777
+ picker.element.on('click', $.proxy(picker.show, this));
778
+ }
779
+ }
780
+ },
781
+
782
+ attachDatePickerGlobalEvents = function () {
783
+ $(window).on(
784
+ 'resize.datetimepicker' + picker.id, $.proxy(place, this));
785
+ if (!picker.isInput) {
786
+ $(document).on(
787
+ 'mousedown.datetimepicker' + picker.id, $.proxy(picker.hide, this));
788
+ }
789
+ },
790
+
791
+ detachDatePickerEvents = function () {
792
+ picker.widget.off('click', '.datepicker *', picker.click);
793
+ picker.widget.off('click', '[data-action]');
794
+ picker.widget.off('mousedown', picker.stopEvent);
795
+ if (picker.options.pickDate && picker.options.pickTime) {
796
+ picker.widget.off('click.togglePicker');
797
+ }
798
+ if (picker.isInput) {
799
+ picker.element.off({
800
+ 'focus': picker.show,
801
+ 'change': picker.change
802
+ });
803
+ } else {
804
+ picker.element.off({
805
+ 'change': picker.change
806
+ }, 'input');
807
+ if (picker.component) {
808
+ picker.component.off('click', picker.show);
809
+ } else {
810
+ picker.element.off('click', picker.show);
811
+ }
812
+ }
813
+ },
814
+
815
+ detachDatePickerGlobalEvents = function () {
816
+ $(window).off('resize.datetimepicker' + picker.id);
817
+ if (!picker.isInput) {
818
+ $(document).off('mousedown.datetimepicker' + picker.id);
819
+ }
820
+ },
821
+
822
+ isInFixed = function () {
823
+ if (picker.element) {
824
+ var parents = picker.element.parents(), inFixed = false, i;
825
+ for (i = 0; i < parents.length; i++) {
826
+ if ($(parents[i]).css('position') == 'fixed') {
827
+ inFixed = true;
828
+ break;
829
+ }
830
+ }
831
+ ;
832
+ return inFixed;
833
+ } else {
834
+ return false;
835
+ }
836
+ },
837
+
838
+ set = function () {
839
+ pMoment.lang(picker.options.language);
840
+ var formatted = '', input;
841
+ if (!picker.unset) formatted = pMoment(picker.date).format(picker.format);
842
+ getPickerInput().val(formatted);
843
+ picker.element.data('date', formatted);
844
+ if (!picker.options.pickTime) picker.hide();
845
+ },
846
+
847
+ checkDate = function (direction, unit, amount) {
848
+ pMoment.lang(picker.options.language);
849
+ var newDate;
850
+ if (direction == "add") {
851
+ newDate = pMoment(picker.date);
852
+ if (newDate.hours() == 23) newDate.add(amount, unit);
853
+ newDate.add(amount, unit);
854
+ }
855
+ else {
856
+ newDate = pMoment(picker.date).subtract(amount, unit);
857
+ }
858
+ if (isInDisableDates(pMoment(newDate.subtract(amount, unit))) || isInDisableDates(newDate)) {
859
+ notifyError(newDate.format(picker.format));
860
+ return;
861
+ }
862
+
863
+ if (direction == "add") {
864
+ picker.date.add(amount, unit);
865
+ }
866
+ else {
867
+ picker.date.subtract(amount, unit);
868
+ }
869
+ picker.unset = false;
870
+ },
871
+
872
+ isInDisableDates = function (date) {
873
+ pMoment.lang(picker.options.language);
874
+ if (date.isAfter(picker.options.maxDate) || date.isBefore(picker.options.minDate)) return true;
875
+ if (picker.options.disabledDates === false) {
876
+ return false;
877
+ }
878
+ return picker.options.disabledDates[pMoment(date).format("YYYY-MM-DD")] === true;
879
+ },
880
+ isInEnableDates = function (date) {
881
+ pMoment.lang(picker.options.language);
882
+ if (picker.options.enabledDates === false) {
883
+ return true;
884
+ }
885
+ return picker.options.enabledDates[pMoment(date).format("YYYY-MM-DD")] === true;
886
+ },
887
+
888
+ indexGivenDates = function (givenDatesArray) {
889
+ // Store given enabledDates and disabledDates as keys.
890
+ // This way we can check their existence in O(1) time instead of looping through whole array.
891
+ // (for example: picker.options.enabledDates['2014-02-27'] === true)
892
+ var givenDatesIndexed = {};
893
+ var givenDatesCount = 0;
894
+ for (i = 0; i < givenDatesArray.length; i++) {
895
+ dDate = pMoment(givenDatesArray[i]);
896
+ if (dDate.isValid()) {
897
+ givenDatesIndexed[dDate.format("YYYY-MM-DD")] = true;
898
+ givenDatesCount++;
899
+ }
900
+ }
901
+ if (givenDatesCount > 0) {
902
+ return givenDatesIndexed;
903
+ }
904
+ return false;
905
+ },
906
+
907
+ padLeft = function (string) {
908
+ string = string.toString();
909
+ if (string.length >= 2) return string;
910
+ else return '0' + string;
911
+ },
912
+
913
+ getTemplate = function () {
914
+ if (picker.options.pickDate && picker.options.pickTime) {
915
+ var ret = '';
916
+ ret = '<div class="bootstrap-datetimepicker-widget' + (picker.options.sideBySide ? ' timepicker-sbs' : '') + ' dropdown-menu" style="z-index:9999 !important;">';
917
+ if (picker.options.sideBySide) {
918
+ ret += '<div class="row">' +
919
+ '<div class="col-sm-6 datepicker">' + dpGlobal.template + '</div>' +
920
+ '<div class="col-sm-6 timepicker">' + tpGlobal.getTemplate() + '</div>' +
921
+ '</div>';
922
+ } else {
923
+ ret += '<ul class="list-unstyled">' +
924
+ '<li' + (picker.options.collapse ? ' class="collapse in"' : '') + '>' +
925
+ '<div class="datepicker">' + dpGlobal.template + '</div>' +
926
+ '</li>' +
927
+ '<li class="picker-switch accordion-toggle"><a class="btn" style="width:100%"><span class="' + picker.options.icons.time + '"></span></a></li>' +
928
+ '<li' + (picker.options.collapse ? ' class="collapse"' : '') + '>' +
929
+ '<div class="timepicker">' + tpGlobal.getTemplate() + '</div>' +
930
+ '</li>' +
931
+ '</ul>';
932
+ }
933
+ ret += '</div>';
934
+ return ret;
935
+ } else if (picker.options.pickTime) {
936
+ return (
937
+ '<div class="bootstrap-datetimepicker-widget dropdown-menu">' +
938
+ '<div class="timepicker">' + tpGlobal.getTemplate() + '</div>' +
939
+ '</div>'
940
+ );
941
+ } else {
942
+ return (
943
+ '<div class="bootstrap-datetimepicker-widget dropdown-menu">' +
944
+ '<div class="datepicker">' + dpGlobal.template + '</div>' +
945
+ '</div>'
946
+ );
947
+ }
948
+ },
949
+
950
+ dpGlobal = {
951
+ modes: [
952
+ {
953
+ clsName: 'days',
954
+ navFnc: 'month',
955
+ navStep: 1
956
+ },
957
+ {
958
+ clsName: 'months',
959
+ navFnc: 'year',
960
+ navStep: 1
961
+ },
962
+ {
963
+ clsName: 'years',
964
+ navFnc: 'year',
965
+ navStep: 10
966
+ }],
967
+ headTemplate:
968
+ '<thead>' +
969
+ '<tr>' +
970
+ '<th class="prev">&lsaquo;</th><th colspan="5" class="switch"></th><th class="next">&rsaquo;</th>' +
971
+ '</tr>' +
972
+ '</thead>',
973
+ contTemplate:
974
+ '<tbody><tr><td colspan="7"></td></tr></tbody>'
975
+ },
976
+
977
+ tpGlobal = {
978
+ hourTemplate: '<span data-action="showHours" data-time-component="hours" class="timepicker-hour"></span>',
979
+ minuteTemplate: '<span data-action="showMinutes" data-time-component="minutes" class="timepicker-minute"></span>',
980
+ secondTemplate: '<span data-action="showSeconds" data-time-component="seconds" class="timepicker-second"></span>'
981
+ };
982
+
983
+ dpGlobal.template =
984
+ '<div class="datepicker-days">' +
985
+ '<table class="table-condensed">' + dpGlobal.headTemplate + '<tbody></tbody></table>' +
986
+ '</div>' +
987
+ '<div class="datepicker-months">' +
988
+ '<table class="table-condensed">' + dpGlobal.headTemplate + dpGlobal.contTemplate + '</table>' +
989
+ '</div>' +
990
+ '<div class="datepicker-years">' +
991
+ '<table class="table-condensed">' + dpGlobal.headTemplate + dpGlobal.contTemplate + '</table>' +
992
+ '</div>';
993
+
994
+ tpGlobal.getTemplate = function () {
995
+ return (
996
+ '<div class="timepicker-picker">' +
997
+ '<table class="table-condensed">' +
998
+ '<tr>' +
999
+ '<td><a href="#" class="btn" data-action="incrementHours"><span class="' + picker.options.icons.up + '"></span></a></td>' +
1000
+ '<td class="separator"></td>' +
1001
+ '<td>' + (picker.options.useMinutes ? '<a href="#" class="btn" data-action="incrementMinutes"><span class="' + picker.options.icons.up + '"></span></a>' : '') + '</td>' +
1002
+ (picker.options.useSeconds ?
1003
+ '<td class="separator"></td><td><a href="#" class="btn" data-action="incrementSeconds"><span class="' + picker.options.icons.up + '"></span></a></td>' : '') +
1004
+ (picker.use24hours ? '' : '<td class="separator"></td>') +
1005
+ '</tr>' +
1006
+ '<tr>' +
1007
+ '<td>' + tpGlobal.hourTemplate + '</td> ' +
1008
+ '<td class="separator">:</td>' +
1009
+ '<td>' + (picker.options.useMinutes ? tpGlobal.minuteTemplate : '<span class="timepicker-minute">00</span>') + '</td> ' +
1010
+ (picker.options.useSeconds ?
1011
+ '<td class="separator">:</td><td>' + tpGlobal.secondTemplate + '</td>' : '') +
1012
+ (picker.use24hours ? '' : '<td class="separator"></td>' +
1013
+ '<td><button type="button" class="btn btn-primary" data-action="togglePeriod"></button></td>') +
1014
+ '</tr>' +
1015
+ '<tr>' +
1016
+ '<td><a href="#" class="btn" data-action="decrementHours"><span class="' + picker.options.icons.down + '"></span></a></td>' +
1017
+ '<td class="separator"></td>' +
1018
+ '<td>' + (picker.options.useMinutes ? '<a href="#" class="btn" data-action="decrementMinutes"><span class="' + picker.options.icons.down + '"></span></a>' : '') + '</td>' +
1019
+ (picker.options.useSeconds ?
1020
+ '<td class="separator"></td><td><a href="#" class="btn" data-action="decrementSeconds"><span class="' + picker.options.icons.down + '"></span></a></td>' : '') +
1021
+ (picker.use24hours ? '' : '<td class="separator"></td>') +
1022
+ '</tr>' +
1023
+ '</table>' +
1024
+ '</div>' +
1025
+ '<div class="timepicker-hours" data-action="selectHour">' +
1026
+ '<table class="table-condensed"></table>' +
1027
+ '</div>' +
1028
+ '<div class="timepicker-minutes" data-action="selectMinute">' +
1029
+ '<table class="table-condensed"></table>' +
1030
+ '</div>' +
1031
+ (picker.options.useSeconds ?
1032
+ '<div class="timepicker-seconds" data-action="selectSecond"><table class="table-condensed"></table></div>' : '')
1033
+ );
1034
+ };
1035
+
1036
+ picker.destroy = function () {
1037
+ detachDatePickerEvents();
1038
+ detachDatePickerGlobalEvents();
1039
+ picker.widget.remove();
1040
+ picker.element.removeData('DateTimePicker');
1041
+ if (picker.component)
1042
+ picker.component.removeData('DateTimePicker');
1043
+ };
1044
+
1045
+ picker.show = function (e) {
1046
+ if (picker.options.useCurrent) {
1047
+ if (getPickerInput().val() == '') {
1048
+ if (picker.options.minuteStepping !== 1) {
1049
+ var mDate = pMoment(),
1050
+ rInterval = picker.options.minuteStepping;
1051
+ mDate.minutes((Math.round(mDate.minutes() / rInterval) * rInterval) % 60)
1052
+ .seconds(0);
1053
+ picker.setValue(mDate.format(picker.format))
1054
+ } else {
1055
+ picker.setValue(pMoment().format(picker.format))
1056
+ }
1057
+ };
1058
+ }
1059
+ if (picker.widget.hasClass("picker-open")) {
1060
+ picker.widget.hide();
1061
+ picker.widget.removeClass("picker-open");
1062
+ }
1063
+ else {
1064
+ picker.widget.show();
1065
+ picker.widget.addClass("picker-open");
1066
+ }
1067
+ picker.height = picker.component ? picker.component.outerHeight() : picker.element.outerHeight();
1068
+ place();
1069
+ picker.element.trigger({
1070
+ type: 'dp.show',
1071
+ date: pMoment(picker.date)
1072
+ });
1073
+ attachDatePickerGlobalEvents();
1074
+ if (e) {
1075
+ stopEvent(e);
1076
+ }
1077
+ },
1078
+
1079
+ picker.disable = function () {
1080
+ var input = picker.element.find('input');
1081
+ if (input.prop('disabled')) return;
1082
+
1083
+ input.prop('disabled', true);
1084
+ detachDatePickerEvents();
1085
+ },
1086
+
1087
+ picker.enable = function () {
1088
+ var input = picker.element.find('input');
1089
+ if (!input.prop('disabled')) return;
1090
+
1091
+ input.prop('disabled', false);
1092
+ attachDatePickerEvents();
1093
+ },
1094
+
1095
+ picker.hide = function (event) {
1096
+ if (event && $(event.target).is(picker.element.attr("id")))
1097
+ return;
1098
+ // Ignore event if in the middle of a picker transition
1099
+ var collapse = picker.widget.find('.collapse'), i, collapseData;
1100
+ for (i = 0; i < collapse.length; i++) {
1101
+ collapseData = collapse.eq(i).data('collapse');
1102
+ if (collapseData && collapseData.date - transitioning)
1103
+ return;
1104
+ }
1105
+ picker.widget.hide();
1106
+ picker.widget.removeClass("picker-open");
1107
+ picker.viewMode = picker.startViewMode;
1108
+ showMode();
1109
+ picker.element.trigger({
1110
+ type: 'dp.hide',
1111
+ date: pMoment(picker.date)
1112
+ });
1113
+ detachDatePickerGlobalEvents();
1114
+ },
1115
+
1116
+ picker.setValue = function (newDate) {
1117
+ pMoment.lang(picker.options.language);
1118
+ if (!newDate) {
1119
+ picker.unset = true;
1120
+ set();
1121
+ } else {
1122
+ picker.unset = false;
1123
+ }
1124
+ if (!pMoment.isMoment(newDate)) newDate = pMoment(newDate, picker.format);
1125
+ if (newDate.isValid()) {
1126
+ picker.date = newDate;
1127
+ set();
1128
+ picker.viewDate = pMoment({ y: picker.date.year(), M: picker.date.month() });
1129
+ fillDate();
1130
+ fillTime();
1131
+ }
1132
+ else {
1133
+ notifyError(newDate);
1134
+ }
1135
+ },
1136
+
1137
+ picker.getDate = function () {
1138
+ if (picker.unset) return null;
1139
+ return picker.date;
1140
+ },
1141
+
1142
+ picker.setDate = function (date) {
1143
+ var oldDate = pMoment(picker.date);
1144
+ if (!date) {
1145
+ picker.setValue(null);
1146
+ } else {
1147
+ picker.setValue(date);
1148
+ }
1149
+ notifyChange(oldDate, "function");
1150
+ },
1151
+
1152
+ picker.setDisabledDates = function (dates) {
1153
+ picker.options.disabledDates = indexGivenDates(dates);
1154
+ if (picker.viewDate) update();
1155
+ },
1156
+ picker.setEnabledDates = function (dates) {
1157
+ picker.options.enabledDates = indexGivenDates(dates);
1158
+ if (picker.viewDate) update();
1159
+ },
1160
+
1161
+ picker.setMaxDate = function (date) {
1162
+ if (date == undefined) return;
1163
+ picker.options.maxDate = pMoment(date);
1164
+ if (picker.viewDate) update();
1165
+ },
1166
+
1167
+ picker.setMinDate = function (date) {
1168
+ if (date == undefined) return;
1169
+ picker.options.minDate = pMoment(date);
1170
+ if (picker.viewDate) update();
1171
+ };
1172
+
1173
+ init();
1174
+ };
1175
+
1176
+ $.fn.datetimepicker = function (options) {
1177
+ return this.each(function () {
1178
+ var $this = $(this), data = $this.data('DateTimePicker');
1179
+ if (!data) $this.data('DateTimePicker', new DateTimePicker(this, options));
1180
+ });
1181
+ };
1182
+
1183
+
1184
+ $(document).ready(function() {
1185
+ var momentFromRubyTimestamp;
1186
+ momentFromRubyTimestamp = function(timestamp) {
1187
+ var output, r, regex;
1188
+ if (timestamp.charAt(0) === '"') {
1189
+ timestamp = timestamp.slice(1, timestamp.length - 1);
1190
+ }
1191
+ console.log("Replacing timestamp " + timestamp);
1192
+ regex = /\ [-+][0-9]+$/;
1193
+ output = regex.test(timestamp) ? (r = timestamp.replace(regex, ''), moment(r, "YYYY-MM-DD HH:mm:ss")) : (regex = /\.[0-9]{3}[-+][0-9]{2}\:[0-9]{2}$/, regex.test(timestamp) ? (r = timestamp.replace(regex, '').replace('T', ' '), moment(r, "YYYY-MM-DD HH:mm:ss")) : moment(timestamp));
1194
+ return output;
1195
+ };
1196
+ $(".dtp").each(function() {
1197
+ var dV, format, m, v;
1198
+ v = $(this).val();
1199
+ dV = $(this).data('defaultvalue');
1200
+ if ((v != null) && v.length > 0 && v !== 'Invalid date') {
1201
+ m = momentFromRubyTimestamp(v);
1202
+ } else if (dV != null) {
1203
+ m = momentFromRubyTimestamp(dV);
1204
+ }
1205
+ if (m != null) {
1206
+ $(this).val(m.format('MM/DD/YYYY h:mm A'));
1207
+ }
1208
+ $(this).attr('autocomplete', 'off').datetimepicker({
1209
+ sideBySide: true
1210
+ });
1211
+ format = $(this).data('DateTimePicker').options.pickDate ? 'MM/DD/YYYY h:mm A' : 'h:mm A';
1212
+ if (m != null) {
1213
+ $(this).data('DateTimePicker').setDate(m.format(format));
1214
+ }
1215
+ $(this).siblings('.input-group-addon').click((function(_this) {
1216
+ return function(e) {
1217
+ return $(_this).data('DateTimePicker').show();
1218
+ };
1219
+ })(this));
1220
+ });
1221
+ });
1222
+ }));