simple_form_datetimepicker 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }));