EZP Coming Soon Page - Version 1.0.0

Version Description

  • Countdown timer now supports time in addition to date
  • UI tweaks
Download this release

Release Info

Developer bobriley
Plugin Icon 128x128 EZP Coming Soon Page
Version 1.0.0
Comparing to
See all releases

Code changes from version 0.6.4 to 1.0.0

classes/class-ezp-cs-constants.php CHANGED
@@ -32,7 +32,7 @@ if (!class_exists('EZP_CS_Constants')) {
32
  const COMPOUND_OPTION_NAME = 'easy-pie-cs-options';
33
  const MAIN_PAGE_KEY = 'easy-pie-cs-main-page';
34
  const PLUGIN_SLUG = 'easy-pie-coming-soon';
35
- const PLUGIN_VERSION = "0.6.4"; // RSR Version
36
 
37
 
38
 
32
  const COMPOUND_OPTION_NAME = 'easy-pie-cs-options';
33
  const MAIN_PAGE_KEY = 'easy-pie-cs-main-page';
34
  const PLUGIN_SLUG = 'easy-pie-coming-soon';
35
+ const PLUGIN_VERSION = "1.0.0"; // RSR Version
36
 
37
 
38
 
classes/class-ezp-cs.php CHANGED
@@ -432,7 +432,9 @@ if (!class_exists('EZP_CS'))
432
  else
433
  {
434
  // Implies it is the content tab
435
- wp_enqueue_script('jquery-ui-datepicker');
 
 
436
  }
437
 
438
  wp_enqueue_media();
@@ -468,6 +470,10 @@ if (!class_exists('EZP_CS'))
468
  {
469
  wp_enqueue_style('spectrum.css', $jQueryPluginRoot . '/spectrum-picker/spectrum.css', array(), EZP_CS_Constants::PLUGIN_VERSION);
470
  }
 
 
 
 
471
  }
472
 
473
  if (isset($_GET['page']) && ($_GET['page'] == EZP_CS_Constants::$COMING_SOON_PAGE_ELITE_SUBMENU_SLUG))
@@ -585,12 +591,5 @@ if (!class_exists('EZP_CS'))
585
  {
586
  $this->display_options_page('page-coming-soon-page-elite.php');
587
  }
588
-
589
- function display_preview_page()
590
- {
591
- $this->display_options_page('page-preview.php');
592
- }
593
-
594
  }
595
-
596
  }
432
  else
433
  {
434
  // Implies it is the content tab
435
+ // wp_enqueue_script('jquery-ui-datepicker');
436
+ wp_enqueue_script('jquery-ui-slider');
437
+ wp_enqueue_script('jquery-ui-timepicker-addon.js', $jQueryPluginRoot . '/jquery-timepicker/jquery-ui-timepicker-addon.js', array('jquery-ui-datepicker', 'jquery-ui-slider'), EZP_CS_Constants::PLUGIN_VERSION);
438
  }
439
 
440
  wp_enqueue_media();
470
  {
471
  wp_enqueue_style('spectrum.css', $jQueryPluginRoot . '/spectrum-picker/spectrum.css', array(), EZP_CS_Constants::PLUGIN_VERSION);
472
  }
473
+ else if (isset($_GET['tab']) && ($_GET['tab'] == 'content'))
474
+ {
475
+ wp_enqueue_style('jquery-ui-timepicker-addon.css', $jQueryPluginRoot . '/jquery-timepicker/jquery-ui-timepicker-addon.css', array(), EZP_CS_Constants::PLUGIN_VERSION);
476
+ }
477
  }
478
 
479
  if (isset($_GET['page']) && ($_GET['page'] == EZP_CS_Constants::$COMING_SOON_PAGE_ELITE_SUBMENU_SLUG))
591
  {
592
  $this->display_options_page('page-coming-soon-page-elite.php');
593
  }
 
 
 
 
 
 
594
  }
 
595
  }
easy-pie-coming-soon.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Coming Soon Page
4
  Plugin URI: http://easypiewp.com/easy-pie-coming-soon-faq/
5
  Description: Let people know that your site is 'coming soon'. Visitors can submit their email addresses for future notification.
6
- Version: 0.6.4
7
  Author: Bob Riley
8
  Author URI: http://www.easypiewp.com
9
  Text Domain: easy-pie-coming-soon
3
  Plugin Name: Coming Soon Page
4
  Plugin URI: http://easypiewp.com/easy-pie-coming-soon-faq/
5
  Description: Let people know that your site is 'coming soon'. Visitors can submit their email addresses for future notification.
6
+ Version: 1.0.0
7
  Author: Bob Riley
8
  Author URI: http://www.easypiewp.com
9
  Text Domain: easy-pie-coming-soon
jquery-plugins/jquery-timepicker/jquery-ui-timepicker-addon.css ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }
2
+ .ui-timepicker-div dl { text-align: left; }
3
+ .ui-timepicker-div dl dt { float: left; clear:left; padding: 0 0 0 5px; }
4
+ .ui-timepicker-div dl dd { margin: 0 10px 10px 40%; }
5
+ .ui-timepicker-div td { font-size: 90%; }
6
+ .ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; }
7
+ .ui-timepicker-div .ui_tpicker_unit_hide{ display: none; }
8
+
9
+ .ui-timepicker-rtl{ direction: rtl; }
10
+ .ui-timepicker-rtl dl { text-align: right; padding: 0 5px 0 0; }
11
+ .ui-timepicker-rtl dl dt{ float: right; clear: right; }
12
+ .ui-timepicker-rtl dl dd { margin: 0 40% 10px 10px; }
13
+
14
+ /* Shortened version style */
15
+ .ui-timepicker-div.ui-timepicker-oneLine { padding-right: 2px; }
16
+ .ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time,
17
+ .ui-timepicker-div.ui-timepicker-oneLine dt { display: none; }
18
+ .ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_time_label { display: block; padding-top: 2px; }
19
+ .ui-timepicker-div.ui-timepicker-oneLine dl { text-align: right; }
20
+ .ui-timepicker-div.ui-timepicker-oneLine dl dd,
21
+ .ui-timepicker-div.ui-timepicker-oneLine dl dd > div { display:inline-block; margin:0; }
22
+ .ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_minute:before,
23
+ .ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_second:before { content:':'; display:inline-block; }
24
+ .ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_millisec:before,
25
+ .ui-timepicker-div.ui-timepicker-oneLine dl dd.ui_tpicker_microsec:before { content:'.'; display:inline-block; }
26
+ .ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide,
27
+ .ui-timepicker-div.ui-timepicker-oneLine .ui_tpicker_unit_hide:before{ display: none; }
jquery-plugins/jquery-timepicker/jquery-ui-timepicker-addon.js ADDED
@@ -0,0 +1,2244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! jQuery Timepicker Addon - v1.5.2 - 2015-03-15
2
+ * http://trentrichardson.com/examples/timepicker
3
+ * Copyright (c) 2015 Trent Richardson; Licensed MIT */
4
+ (function (factory) {
5
+ if (typeof define === 'function' && define.amd) {
6
+ define(['jquery', 'jquery.ui'], factory);
7
+ } else {
8
+ factory(jQuery);
9
+ }
10
+ }(function ($) {
11
+
12
+ /*
13
+ * Lets not redefine timepicker, Prevent "Uncaught RangeError: Maximum call stack size exceeded"
14
+ */
15
+ $.ui.timepicker = $.ui.timepicker || {};
16
+ if ($.ui.timepicker.version) {
17
+ return;
18
+ }
19
+
20
+ /*
21
+ * Extend jQueryUI, get it started with our version number
22
+ */
23
+ $.extend($.ui, {
24
+ timepicker: {
25
+ version: "1.5.2"
26
+ }
27
+ });
28
+
29
+ /*
30
+ * Timepicker manager.
31
+ * Use the singleton instance of this class, $.timepicker, to interact with the time picker.
32
+ * Settings for (groups of) time pickers are maintained in an instance object,
33
+ * allowing multiple different settings on the same page.
34
+ */
35
+ var Timepicker = function () {
36
+ this.regional = []; // Available regional settings, indexed by language code
37
+ this.regional[''] = { // Default regional settings
38
+ currentText: 'Now',
39
+ closeText: 'Done',
40
+ amNames: ['AM', 'A'],
41
+ pmNames: ['PM', 'P'],
42
+ timeFormat: 'HH:mm',
43
+ timeSuffix: '',
44
+ timeOnlyTitle: 'Choose Time',
45
+ timeText: 'Time',
46
+ hourText: 'Hour',
47
+ minuteText: 'Minute',
48
+ secondText: 'Second',
49
+ millisecText: 'Millisecond',
50
+ microsecText: 'Microsecond',
51
+ timezoneText: 'Time Zone',
52
+ isRTL: false
53
+ };
54
+ this._defaults = { // Global defaults for all the datetime picker instances
55
+ showButtonPanel: true,
56
+ timeOnly: false,
57
+ timeOnlyShowDate: false,
58
+ showHour: null,
59
+ showMinute: null,
60
+ showSecond: null,
61
+ showMillisec: null,
62
+ showMicrosec: null,
63
+ showTimezone: null,
64
+ showTime: true,
65
+ stepHour: 1,
66
+ stepMinute: 1,
67
+ stepSecond: 1,
68
+ stepMillisec: 1,
69
+ stepMicrosec: 1,
70
+ hour: 0,
71
+ minute: 0,
72
+ second: 0,
73
+ millisec: 0,
74
+ microsec: 0,
75
+ timezone: null,
76
+ hourMin: 0,
77
+ minuteMin: 0,
78
+ secondMin: 0,
79
+ millisecMin: 0,
80
+ microsecMin: 0,
81
+ hourMax: 23,
82
+ minuteMax: 59,
83
+ secondMax: 59,
84
+ millisecMax: 999,
85
+ microsecMax: 999,
86
+ minDateTime: null,
87
+ maxDateTime: null,
88
+ maxTime: null,
89
+ minTime: null,
90
+ onSelect: null,
91
+ hourGrid: 0,
92
+ minuteGrid: 0,
93
+ secondGrid: 0,
94
+ millisecGrid: 0,
95
+ microsecGrid: 0,
96
+ alwaysSetTime: true,
97
+ separator: ' ',
98
+ altFieldTimeOnly: true,
99
+ altTimeFormat: null,
100
+ altSeparator: null,
101
+ altTimeSuffix: null,
102
+ altRedirectFocus: true,
103
+ pickerTimeFormat: null,
104
+ pickerTimeSuffix: null,
105
+ showTimepicker: true,
106
+ timezoneList: null,
107
+ addSliderAccess: false,
108
+ sliderAccessArgs: null,
109
+ controlType: 'slider',
110
+ oneLine: false,
111
+ defaultValue: null,
112
+ parse: 'strict',
113
+ afterInject: null
114
+ };
115
+ $.extend(this._defaults, this.regional['']);
116
+ };
117
+
118
+ $.extend(Timepicker.prototype, {
119
+ $input: null,
120
+ $altInput: null,
121
+ $timeObj: null,
122
+ inst: null,
123
+ hour_slider: null,
124
+ minute_slider: null,
125
+ second_slider: null,
126
+ millisec_slider: null,
127
+ microsec_slider: null,
128
+ timezone_select: null,
129
+ maxTime: null,
130
+ minTime: null,
131
+ hour: 0,
132
+ minute: 0,
133
+ second: 0,
134
+ millisec: 0,
135
+ microsec: 0,
136
+ timezone: null,
137
+ hourMinOriginal: null,
138
+ minuteMinOriginal: null,
139
+ secondMinOriginal: null,
140
+ millisecMinOriginal: null,
141
+ microsecMinOriginal: null,
142
+ hourMaxOriginal: null,
143
+ minuteMaxOriginal: null,
144
+ secondMaxOriginal: null,
145
+ millisecMaxOriginal: null,
146
+ microsecMaxOriginal: null,
147
+ ampm: '',
148
+ formattedDate: '',
149
+ formattedTime: '',
150
+ formattedDateTime: '',
151
+ timezoneList: null,
152
+ units: ['hour', 'minute', 'second', 'millisec', 'microsec'],
153
+ support: {},
154
+ control: null,
155
+
156
+ /*
157
+ * Override the default settings for all instances of the time picker.
158
+ * @param {Object} settings object - the new settings to use as defaults (anonymous object)
159
+ * @return {Object} the manager object
160
+ */
161
+ setDefaults: function (settings) {
162
+ extendRemove(this._defaults, settings || {});
163
+ return this;
164
+ },
165
+
166
+ /*
167
+ * Create a new Timepicker instance
168
+ */
169
+ _newInst: function ($input, opts) {
170
+ var tp_inst = new Timepicker(),
171
+ inlineSettings = {},
172
+ fns = {},
173
+ overrides, i;
174
+
175
+ for (var attrName in this._defaults) {
176
+ if (this._defaults.hasOwnProperty(attrName)) {
177
+ var attrValue = $input.attr('time:' + attrName);
178
+ if (attrValue) {
179
+ try {
180
+ inlineSettings[attrName] = eval(attrValue);
181
+ } catch (err) {
182
+ inlineSettings[attrName] = attrValue;
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+ overrides = {
189
+ beforeShow: function (input, dp_inst) {
190
+ if ($.isFunction(tp_inst._defaults.evnts.beforeShow)) {
191
+ return tp_inst._defaults.evnts.beforeShow.call($input[0], input, dp_inst, tp_inst);
192
+ }
193
+ },
194
+ onChangeMonthYear: function (year, month, dp_inst) {
195
+ // Update the time as well : this prevents the time from disappearing from the $input field.
196
+ // tp_inst._updateDateTime(dp_inst);
197
+ if ($.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)) {
198
+ tp_inst._defaults.evnts.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst);
199
+ }
200
+ },
201
+ onClose: function (dateText, dp_inst) {
202
+ if (tp_inst.timeDefined === true && $input.val() !== '') {
203
+ tp_inst._updateDateTime(dp_inst);
204
+ }
205
+ if ($.isFunction(tp_inst._defaults.evnts.onClose)) {
206
+ tp_inst._defaults.evnts.onClose.call($input[0], dateText, dp_inst, tp_inst);
207
+ }
208
+ }
209
+ };
210
+ for (i in overrides) {
211
+ if (overrides.hasOwnProperty(i)) {
212
+ fns[i] = opts[i] || null;
213
+ }
214
+ }
215
+
216
+ tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, opts, overrides, {
217
+ evnts: fns,
218
+ timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker');
219
+ });
220
+ tp_inst.amNames = $.map(tp_inst._defaults.amNames, function (val) {
221
+ return val.toUpperCase();
222
+ });
223
+ tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function (val) {
224
+ return val.toUpperCase();
225
+ });
226
+
227
+ // detect which units are supported
228
+ tp_inst.support = detectSupport(
229
+ tp_inst._defaults.timeFormat +
230
+ (tp_inst._defaults.pickerTimeFormat ? tp_inst._defaults.pickerTimeFormat : '') +
231
+ (tp_inst._defaults.altTimeFormat ? tp_inst._defaults.altTimeFormat : ''));
232
+
233
+ // controlType is string - key to our this._controls
234
+ if (typeof(tp_inst._defaults.controlType) === 'string') {
235
+ if (tp_inst._defaults.controlType === 'slider' && typeof($.ui.slider) === 'undefined') {
236
+ tp_inst._defaults.controlType = 'select';
237
+ }
238
+ tp_inst.control = tp_inst._controls[tp_inst._defaults.controlType];
239
+ }
240
+ // controlType is an object and must implement create, options, value methods
241
+ else {
242
+ tp_inst.control = tp_inst._defaults.controlType;
243
+ }
244
+
245
+ // prep the timezone options
246
+ var timezoneList = [-720, -660, -600, -570, -540, -480, -420, -360, -300, -270, -240, -210, -180, -120, -60,
247
+ 0, 60, 120, 180, 210, 240, 270, 300, 330, 345, 360, 390, 420, 480, 525, 540, 570, 600, 630, 660, 690, 720, 765, 780, 840];
248
+ if (tp_inst._defaults.timezoneList !== null) {
249
+ timezoneList = tp_inst._defaults.timezoneList;
250
+ }
251
+ var tzl = timezoneList.length, tzi = 0, tzv = null;
252
+ if (tzl > 0 && typeof timezoneList[0] !== 'object') {
253
+ for (; tzi < tzl; tzi++) {
254
+ tzv = timezoneList[tzi];
255
+ timezoneList[tzi] = { value: tzv, label: $.timepicker.timezoneOffsetString(tzv, tp_inst.support.iso8601) };
256
+ }
257
+ }
258
+ tp_inst._defaults.timezoneList = timezoneList;
259
+
260
+ // set the default units
261
+ tp_inst.timezone = tp_inst._defaults.timezone !== null ? $.timepicker.timezoneOffsetNumber(tp_inst._defaults.timezone) :
262
+ ((new Date()).getTimezoneOffset() * -1);
263
+ tp_inst.hour = tp_inst._defaults.hour < tp_inst._defaults.hourMin ? tp_inst._defaults.hourMin :
264
+ tp_inst._defaults.hour > tp_inst._defaults.hourMax ? tp_inst._defaults.hourMax : tp_inst._defaults.hour;
265
+ tp_inst.minute = tp_inst._defaults.minute < tp_inst._defaults.minuteMin ? tp_inst._defaults.minuteMin :
266
+ tp_inst._defaults.minute > tp_inst._defaults.minuteMax ? tp_inst._defaults.minuteMax : tp_inst._defaults.minute;
267
+ tp_inst.second = tp_inst._defaults.second < tp_inst._defaults.secondMin ? tp_inst._defaults.secondMin :
268
+ tp_inst._defaults.second > tp_inst._defaults.secondMax ? tp_inst._defaults.secondMax : tp_inst._defaults.second;
269
+ tp_inst.millisec = tp_inst._defaults.millisec < tp_inst._defaults.millisecMin ? tp_inst._defaults.millisecMin :
270
+ tp_inst._defaults.millisec > tp_inst._defaults.millisecMax ? tp_inst._defaults.millisecMax : tp_inst._defaults.millisec;
271
+ tp_inst.microsec = tp_inst._defaults.microsec < tp_inst._defaults.microsecMin ? tp_inst._defaults.microsecMin :
272
+ tp_inst._defaults.microsec > tp_inst._defaults.microsecMax ? tp_inst._defaults.microsecMax : tp_inst._defaults.microsec;
273
+ tp_inst.ampm = '';
274
+ tp_inst.$input = $input;
275
+
276
+ if (tp_inst._defaults.altField) {
277
+ tp_inst.$altInput = $(tp_inst._defaults.altField);
278
+ if (tp_inst._defaults.altRedirectFocus === true) {
279
+ tp_inst.$altInput.css({
280
+ cursor: 'pointer'
281
+ }).focus(function () {
282
+ $input.trigger("focus");
283
+ });
284
+ }
285
+ }
286
+
287
+ if (tp_inst._defaults.minDate === 0 || tp_inst._defaults.minDateTime === 0) {
288
+ tp_inst._defaults.minDate = new Date();
289
+ }
290
+ if (tp_inst._defaults.maxDate === 0 || tp_inst._defaults.maxDateTime === 0) {
291
+ tp_inst._defaults.maxDate = new Date();
292
+ }
293
+
294
+ // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime..
295
+ if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) {
296
+ tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime());
297
+ }
298
+ if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) {
299
+ tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime());
300
+ }
301
+ if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) {
302
+ tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime());
303
+ }
304
+ if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) {
305
+ tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime());
306
+ }
307
+ tp_inst.$input.bind('focus', function () {
308
+ tp_inst._onFocus();
309
+ });
310
+
311
+ return tp_inst;
312
+ },
313
+
314
+ /*
315
+ * add our sliders to the calendar
316
+ */
317
+ _addTimePicker: function (dp_inst) {
318
+ var currDT = $.trim((this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val());
319
+
320
+ this.timeDefined = this._parseTime(currDT);
321
+ this._limitMinMaxDateTime(dp_inst, false);
322
+ this._injectTimePicker();
323
+ this._afterInject();
324
+ },
325
+
326
+ /*
327
+ * parse the time string from input value or _setTime
328
+ */
329
+ _parseTime: function (timeString, withDate) {
330
+ if (!this.inst) {
331
+ this.inst = $.datepicker._getInst(this.$input[0]);
332
+ }
333
+
334
+ if (withDate || !this._defaults.timeOnly) {
335
+ var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');
336
+ try {
337
+ var parseRes = parseDateTimeInternal(dp_dateFormat, this._defaults.timeFormat, timeString, $.datepicker._getFormatConfig(this.inst), this._defaults);
338
+ if (!parseRes.timeObj) {
339
+ return false;
340
+ }
341
+ $.extend(this, parseRes.timeObj);
342
+ } catch (err) {
343
+ $.timepicker.log("Error parsing the date/time string: " + err +
344
+ "\ndate/time string = " + timeString +
345
+ "\ntimeFormat = " + this._defaults.timeFormat +
346
+ "\ndateFormat = " + dp_dateFormat);
347
+ return false;
348
+ }
349
+ return true;
350
+ } else {
351
+ var timeObj = $.datepicker.parseTime(this._defaults.timeFormat, timeString, this._defaults);
352
+ if (!timeObj) {
353
+ return false;
354
+ }
355
+ $.extend(this, timeObj);
356
+ return true;
357
+ }
358
+ },
359
+
360
+ /*
361
+ * Handle callback option after injecting timepicker
362
+ */
363
+ _afterInject: function() {
364
+ var o = this.inst.settings;
365
+ if ($.isFunction(o.afterInject)) {
366
+ o.afterInject.call(this);
367
+ }
368
+ },
369
+
370
+ /*
371
+ * generate and inject html for timepicker into ui datepicker
372
+ */
373
+ _injectTimePicker: function () {
374
+ var $dp = this.inst.dpDiv,
375
+ o = this.inst.settings,
376
+ tp_inst = this,
377
+ litem = '',
378
+ uitem = '',
379
+ show = null,
380
+ max = {},
381
+ gridSize = {},
382
+ size = null,
383
+ i = 0,
384
+ l = 0;
385
+
386
+ // Prevent displaying twice
387
+ if ($dp.find("div.ui-timepicker-div").length === 0 && o.showTimepicker) {
388
+ var noDisplay = ' ui_tpicker_unit_hide',
389
+ html = '<div class="ui-timepicker-div' + (o.isRTL ? ' ui-timepicker-rtl' : '') + (o.oneLine && o.controlType === 'select' ? ' ui-timepicker-oneLine' : '') + '"><dl>' + '<dt class="ui_tpicker_time_label"' + ((o.showTime) ? '' : noDisplay) + '>' + o.timeText + '</dt>' +
390
+ '<dd class="ui_tpicker_time '+ ((o.showTime) ? '' : noDisplay) + '"></dd>';
391
+
392
+ // Create the markup
393
+ for (i = 0, l = this.units.length; i < l; i++) {
394
+ litem = this.units[i];
395
+ uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1);
396
+ show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem];
397
+
398
+ // Added by Peter Medeiros:
399
+ // - Figure out what the hour/minute/second max should be based on the step values.
400
+ // - Example: if stepMinute is 15, then minMax is 45.
401
+ max[litem] = parseInt((o[litem + 'Max'] - ((o[litem + 'Max'] - o[litem + 'Min']) % o['step' + uitem])), 10);
402
+ gridSize[litem] = 0;
403
+
404
+ html += '<dt class="ui_tpicker_' + litem + '_label' + (show ? '' : noDisplay) + '">' + o[litem + 'Text'] + '</dt>' +
405
+ '<dd class="ui_tpicker_' + litem + (show ? '' : noDisplay) + '"><div class="ui_tpicker_' + litem + '_slider' + (show ? '' : noDisplay) + '"></div>';
406
+
407
+ if (show && o[litem + 'Grid'] > 0) {
408
+ html += '<div style="padding-left: 1px"><table class="ui-tpicker-grid-label"><tr>';
409
+
410
+ if (litem === 'hour') {
411
+ for (var h = o[litem + 'Min']; h <= max[litem]; h += parseInt(o[litem + 'Grid'], 10)) {
412
+ gridSize[litem]++;
413
+ var tmph = $.datepicker.formatTime(this.support.ampm ? 'hht' : 'HH', {hour: h}, o);
414
+ html += '<td data-for="' + litem + '">' + tmph + '</td>';
415
+ }
416
+ }
417
+ else {
418
+ for (var m = o[litem + 'Min']; m <= max[litem]; m += parseInt(o[litem + 'Grid'], 10)) {
419
+ gridSize[litem]++;
420
+ html += '<td data-for="' + litem + '">' + ((m < 10) ? '0' : '') + m + '</td>';
421
+ }
422
+ }
423
+
424
+ html += '</tr></table></div>';
425
+ }
426
+ html += '</dd>';
427
+ }
428
+
429
+ // Timezone
430
+ var showTz = o.showTimezone !== null ? o.showTimezone : this.support.timezone;
431
+ html += '<dt class="ui_tpicker_timezone_label' + (showTz ? '' : noDisplay) + '">' + o.timezoneText + '</dt>';
432
+ html += '<dd class="ui_tpicker_timezone' + (showTz ? '' : noDisplay) + '"></dd>';
433
+
434
+ // Create the elements from string
435
+ html += '</dl></div>';
436
+ var $tp = $(html);
437
+
438
+ // if we only want time picker...
439
+ if (o.timeOnly === true) {
440
+ $tp.prepend('<div class="ui-widget-header ui-helper-clearfix ui-corner-all">' + '<div class="ui-datepicker-title">' + o.timeOnlyTitle + '</div>' + '</div>');
441
+ $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide();
442
+ }
443
+
444
+ // add sliders, adjust grids, add events
445
+ for (i = 0, l = tp_inst.units.length; i < l; i++) {
446
+ litem = tp_inst.units[i];
447
+ uitem = litem.substr(0, 1).toUpperCase() + litem.substr(1);
448
+ show = o['show' + uitem] !== null ? o['show' + uitem] : this.support[litem];
449
+
450
+ // add the slider
451
+ tp_inst[litem + '_slider'] = tp_inst.control.create(tp_inst, $tp.find('.ui_tpicker_' + litem + '_slider'), litem, tp_inst[litem], o[litem + 'Min'], max[litem], o['step' + uitem]);
452
+
453
+ // adjust the grid and add click event
454
+ if (show && o[litem + 'Grid'] > 0) {
455
+ size = 100 * gridSize[litem] * o[litem + 'Grid'] / (max[litem] - o[litem + 'Min']);
456
+ $tp.find('.ui_tpicker_' + litem + ' table').css({
457
+ width: size + "%",
458
+ marginLeft: o.isRTL ? '0' : ((size / (-2 * gridSize[litem])) + "%"),
459
+ marginRight: o.isRTL ? ((size / (-2 * gridSize[litem])) + "%") : '0',
460
+ borderCollapse: 'collapse'
461
+ }).find("td").click(function (e) {
462
+ var $t = $(this),
463
+ h = $t.html(),
464
+ n = parseInt(h.replace(/[^0-9]/g), 10),
465
+ ap = h.replace(/[^apm]/ig),
466
+ f = $t.data('for'); // loses scope, so we use data-for
467
+
468
+ if (f === 'hour') {
469
+ if (ap.indexOf('p') !== -1 && n < 12) {
470
+ n += 12;
471
+ }
472
+ else {
473
+ if (ap.indexOf('a') !== -1 && n === 12) {
474
+ n = 0;
475
+ }
476
+ }
477
+ }
478
+
479
+ tp_inst.control.value(tp_inst, tp_inst[f + '_slider'], litem, n);
480
+
481
+ tp_inst._onTimeChange();
482
+ tp_inst._onSelectHandler();
483
+ }).css({
484
+ cursor: 'pointer',
485
+ width: (100 / gridSize[litem]) + '%',
486
+ textAlign: 'center',
487
+ overflow: 'hidden'
488
+ });
489
+ } // end if grid > 0
490
+ } // end for loop
491
+
492
+ // Add timezone options
493
+ this.timezone_select = $tp.find('.ui_tpicker_timezone').append('<select></select>').find("select");
494
+ $.fn.append.apply(this.timezone_select,
495
+ $.map(o.timezoneList, function (val, idx) {
496
+ return $("<option />").val(typeof val === "object" ? val.value : val).text(typeof val === "object" ? val.label : val);
497
+ }));
498
+ if (typeof(this.timezone) !== "undefined" && this.timezone !== null && this.timezone !== "") {
499
+ var local_timezone = (new Date(this.inst.selectedYear, this.inst.selectedMonth, this.inst.selectedDay, 12)).getTimezoneOffset() * -1;
500
+ if (local_timezone === this.timezone) {
501
+ selectLocalTimezone(tp_inst);
502
+ } else {
503
+ this.timezone_select.val(this.timezone);
504
+ }
505
+ } else {
506
+ if (typeof(this.hour) !== "undefined" && this.hour !== null && this.hour !== "") {
507
+ this.timezone_select.val(o.timezone);
508
+ } else {
509
+ selectLocalTimezone(tp_inst);
510
+ }
511
+ }
512
+ this.timezone_select.change(function () {
513
+ tp_inst._onTimeChange();
514
+ tp_inst._onSelectHandler();
515
+ tp_inst._afterInject();
516
+ });
517
+ // End timezone options
518
+
519
+ // inject timepicker into datepicker
520
+ var $buttonPanel = $dp.find('.ui-datepicker-buttonpane');
521
+ if ($buttonPanel.length) {
522
+ $buttonPanel.before($tp);
523
+ } else {
524
+ $dp.append($tp);
525
+ }
526
+
527
+ this.$timeObj = $tp.find('.ui_tpicker_time');
528
+
529
+ if (this.inst !== null) {
530
+ var timeDefined = this.timeDefined;
531
+ this._onTimeChange();
532
+ this.timeDefined = timeDefined;
533
+ }
534
+
535
+ // slideAccess integration: http://trentrichardson.com/2011/11/11/jquery-ui-sliders-and-touch-accessibility/
536
+ if (this._defaults.addSliderAccess) {
537
+ var sliderAccessArgs = this._defaults.sliderAccessArgs,
538
+ rtl = this._defaults.isRTL;
539
+ sliderAccessArgs.isRTL = rtl;
540
+
541
+ setTimeout(function () { // fix for inline mode
542
+ if ($tp.find('.ui-slider-access').length === 0) {
543
+ $tp.find('.ui-slider:visible').sliderAccess(sliderAccessArgs);
544
+
545
+ // fix any grids since sliders are shorter
546
+ var sliderAccessWidth = $tp.find('.ui-slider-access:eq(0)').outerWidth(true);
547
+ if (sliderAccessWidth) {
548
+ $tp.find('table:visible').each(function () {
549
+ var $g = $(this),
550
+ oldWidth = $g.outerWidth(),
551
+ oldMarginLeft = $g.css(rtl ? 'marginRight' : 'marginLeft').toString().replace('%', ''),
552
+ newWidth = oldWidth - sliderAccessWidth,
553
+ newMarginLeft = ((oldMarginLeft * newWidth) / oldWidth) + '%',
554
+ css = { width: newWidth, marginRight: 0, marginLeft: 0 };
555
+ css[rtl ? 'marginRight' : 'marginLeft'] = newMarginLeft;
556
+ $g.css(css);
557
+ });
558
+ }
559
+ }
560
+ }, 10);
561
+ }
562
+ // end slideAccess integration
563
+
564
+ tp_inst._limitMinMaxDateTime(this.inst, true);
565
+ }
566
+ },
567
+
568
+ /*
569
+ * This function tries to limit the ability to go outside the
570
+ * min/max date range
571
+ */
572
+ _limitMinMaxDateTime: function (dp_inst, adjustSliders) {
573
+ var o = this._defaults,
574
+ dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay);
575
+
576
+ if (!this._defaults.showTimepicker) {
577
+ return;
578
+ } // No time so nothing to check here
579
+
580
+ if ($.datepicker._get(dp_inst, 'minDateTime') !== null && $.datepicker._get(dp_inst, 'minDateTime') !== undefined && dp_date) {
581
+ var minDateTime = $.datepicker._get(dp_inst, 'minDateTime'),
582
+ minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0);
583
+
584
+ if (this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null || this.millisecMinOriginal === null || this.microsecMinOriginal === null) {
585
+ this.hourMinOriginal = o.hourMin;
586
+ this.minuteMinOriginal = o.minuteMin;
587
+ this.secondMinOriginal = o.secondMin;
588
+ this.millisecMinOriginal = o.millisecMin;
589
+ this.microsecMinOriginal = o.microsecMin;
590
+ }
591
+
592
+ if (dp_inst.settings.timeOnly || minDateTimeDate.getTime() === dp_date.getTime()) {
593
+ this._defaults.hourMin = minDateTime.getHours();
594
+ if (this.hour <= this._defaults.hourMin) {
595
+ this.hour = this._defaults.hourMin;
596
+ this._defaults.minuteMin = minDateTime.getMinutes();
597
+ if (this.minute <= this._defaults.minuteMin) {
598
+ this.minute = this._defaults.minuteMin;
599
+ this._defaults.secondMin = minDateTime.getSeconds();
600
+ if (this.second <= this._defaults.secondMin) {
601
+ this.second = this._defaults.secondMin;
602
+ this._defaults.millisecMin = minDateTime.getMilliseconds();
603
+ if (this.millisec <= this._defaults.millisecMin) {
604
+ this.millisec = this._defaults.millisecMin;
605
+ this._defaults.microsecMin = minDateTime.getMicroseconds();
606
+ } else {
607
+ if (this.microsec < this._defaults.microsecMin) {
608
+ this.microsec = this._defaults.microsecMin;
609
+ }
610
+ this._defaults.microsecMin = this.microsecMinOriginal;
611
+ }
612
+ } else {
613
+ this._defaults.millisecMin = this.millisecMinOriginal;
614
+ this._defaults.microsecMin = this.microsecMinOriginal;
615
+ }
616
+ } else {
617
+ this._defaults.secondMin = this.secondMinOriginal;
618
+ this._defaults.millisecMin = this.millisecMinOriginal;
619
+ this._defaults.microsecMin = this.microsecMinOriginal;
620
+ }
621
+ } else {
622
+ this._defaults.minuteMin = this.minuteMinOriginal;
623
+ this._defaults.secondMin = this.secondMinOriginal;
624
+ this._defaults.millisecMin = this.millisecMinOriginal;
625
+ this._defaults.microsecMin = this.microsecMinOriginal;
626
+ }
627
+ } else {
628
+ this._defaults.hourMin = this.hourMinOriginal;
629
+ this._defaults.minuteMin = this.minuteMinOriginal;
630
+ this._defaults.secondMin = this.secondMinOriginal;
631
+ this._defaults.millisecMin = this.millisecMinOriginal;
632
+ this._defaults.microsecMin = this.microsecMinOriginal;
633
+ }
634
+ }
635
+
636
+ if ($.datepicker._get(dp_inst, 'maxDateTime') !== null && $.datepicker._get(dp_inst, 'maxDateTime') !== undefined && dp_date) {
637
+ var maxDateTime = $.datepicker._get(dp_inst, 'maxDateTime'),
638
+ maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0);
639
+
640
+ if (this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null || this.millisecMaxOriginal === null) {
641
+ this.hourMaxOriginal = o.hourMax;
642
+ this.minuteMaxOriginal = o.minuteMax;
643
+ this.secondMaxOriginal = o.secondMax;
644
+ this.millisecMaxOriginal = o.millisecMax;
645
+ this.microsecMaxOriginal = o.microsecMax;
646
+ }
647
+
648
+ if (dp_inst.settings.timeOnly || maxDateTimeDate.getTime() === dp_date.getTime()) {
649
+ this._defaults.hourMax = maxDateTime.getHours();
650
+ if (this.hour >= this._defaults.hourMax) {
651
+ this.hour = this._defaults.hourMax;
652
+ this._defaults.minuteMax = maxDateTime.getMinutes();
653
+ if (this.minute >= this._defaults.minuteMax) {
654
+ this.minute = this._defaults.minuteMax;
655
+ this._defaults.secondMax = maxDateTime.getSeconds();
656
+ if (this.second >= this._defaults.secondMax) {
657
+ this.second = this._defaults.secondMax;
658
+ this._defaults.millisecMax = maxDateTime.getMilliseconds();
659
+ if (this.millisec >= this._defaults.millisecMax) {
660
+ this.millisec = this._defaults.millisecMax;
661
+ this._defaults.microsecMax = maxDateTime.getMicroseconds();
662
+ } else {
663
+ if (this.microsec > this._defaults.microsecMax) {
664
+ this.microsec = this._defaults.microsecMax;
665
+ }
666
+ this._defaults.microsecMax = this.microsecMaxOriginal;
667
+ }
668
+ } else {
669
+ this._defaults.millisecMax = this.millisecMaxOriginal;
670
+ this._defaults.microsecMax = this.microsecMaxOriginal;
671
+ }
672
+ } else {
673
+ this._defaults.secondMax = this.secondMaxOriginal;
674
+ this._defaults.millisecMax = this.millisecMaxOriginal;
675
+ this._defaults.microsecMax = this.microsecMaxOriginal;
676
+ }
677
+ } else {
678
+ this._defaults.minuteMax = this.minuteMaxOriginal;
679
+ this._defaults.secondMax = this.secondMaxOriginal;
680
+ this._defaults.millisecMax = this.millisecMaxOriginal;
681
+ this._defaults.microsecMax = this.microsecMaxOriginal;
682
+ }
683
+ } else {
684
+ this._defaults.hourMax = this.hourMaxOriginal;
685
+ this._defaults.minuteMax = this.minuteMaxOriginal;
686
+ this._defaults.secondMax = this.secondMaxOriginal;
687
+ this._defaults.millisecMax = this.millisecMaxOriginal;
688
+ this._defaults.microsecMax = this.microsecMaxOriginal;
689
+ }
690
+ }
691
+
692
+ if (dp_inst.settings.minTime!==null) {
693
+ var tempMinTime=new Date("01/01/1970 " + dp_inst.settings.minTime);
694
+ if (this.hour<tempMinTime.getHours()) {
695
+ this.hour=this._defaults.hourMin=tempMinTime.getHours();
696
+ this.minute=this._defaults.minuteMin=tempMinTime.getMinutes();
697
+ } else if (this.hour===tempMinTime.getHours() && this.minute<tempMinTime.getMinutes()) {
698
+ this.minute=this._defaults.minuteMin=tempMinTime.getMinutes();
699
+ } else {
700
+ if (this._defaults.hourMin<tempMinTime.getHours()) {
701
+ this._defaults.hourMin=tempMinTime.getHours();
702
+ this._defaults.minuteMin=tempMinTime.getMinutes();
703
+ } else if (this._defaults.hourMin===tempMinTime.getHours()===this.hour && this._defaults.minuteMin<tempMinTime.getMinutes()) {
704
+ this._defaults.minuteMin=tempMinTime.getMinutes();
705
+ } else {
706
+ this._defaults.minuteMin=0;
707
+ }
708
+ }
709
+ }
710
+
711
+ if (dp_inst.settings.maxTime!==null) {
712
+ var tempMaxTime=new Date("01/01/1970 " + dp_inst.settings.maxTime);
713
+ if (this.hour>tempMaxTime.getHours()) {
714
+ this.hour=this._defaults.hourMax=tempMaxTime.getHours();
715
+ this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes();
716
+ } else if (this.hour===tempMaxTime.getHours() && this.minute>tempMaxTime.getMinutes()) {
717
+ this.minute=this._defaults.minuteMax=tempMaxTime.getMinutes();
718
+ } else {
719
+ if (this._defaults.hourMax>tempMaxTime.getHours()) {
720
+ this._defaults.hourMax=tempMaxTime.getHours();
721
+ this._defaults.minuteMax=tempMaxTime.getMinutes();
722
+ } else if (this._defaults.hourMax===tempMaxTime.getHours()===this.hour && this._defaults.minuteMax>tempMaxTime.getMinutes()) {
723
+ this._defaults.minuteMax=tempMaxTime.getMinutes();
724
+ } else {
725
+ this._defaults.minuteMax=59;
726
+ }
727
+ }
728
+ }
729
+
730
+ if (adjustSliders !== undefined && adjustSliders === true) {
731
+ var hourMax = parseInt((this._defaults.hourMax - ((this._defaults.hourMax - this._defaults.hourMin) % this._defaults.stepHour)), 10),
732
+ minMax = parseInt((this._defaults.minuteMax - ((this._defaults.minuteMax - this._defaults.minuteMin) % this._defaults.stepMinute)), 10),
733
+ secMax = parseInt((this._defaults.secondMax - ((this._defaults.secondMax - this._defaults.secondMin) % this._defaults.stepSecond)), 10),
734
+ millisecMax = parseInt((this._defaults.millisecMax - ((this._defaults.millisecMax - this._defaults.millisecMin) % this._defaults.stepMillisec)), 10),
735
+ microsecMax = parseInt((this._defaults.microsecMax - ((this._defaults.microsecMax - this._defaults.microsecMin) % this._defaults.stepMicrosec)), 10);
736
+
737
+ if (this.hour_slider) {
738
+ this.control.options(this, this.hour_slider, 'hour', { min: this._defaults.hourMin, max: hourMax, step: this._defaults.stepHour });
739
+ this.control.value(this, this.hour_slider, 'hour', this.hour - (this.hour % this._defaults.stepHour));
740
+ }
741
+ if (this.minute_slider) {
742
+ this.control.options(this, this.minute_slider, 'minute', { min: this._defaults.minuteMin, max: minMax, step: this._defaults.stepMinute });
743
+ this.control.value(this, this.minute_slider, 'minute', this.minute - (this.minute % this._defaults.stepMinute));
744
+ }
745
+ if (this.second_slider) {
746
+ this.control.options(this, this.second_slider, 'second', { min: this._defaults.secondMin, max: secMax, step: this._defaults.stepSecond });
747
+ this.control.value(this, this.second_slider, 'second', this.second - (this.second % this._defaults.stepSecond));
748
+ }
749
+ if (this.millisec_slider) {
750
+ this.control.options(this, this.millisec_slider, 'millisec', { min: this._defaults.millisecMin, max: millisecMax, step: this._defaults.stepMillisec });
751
+ this.control.value(this, this.millisec_slider, 'millisec', this.millisec - (this.millisec % this._defaults.stepMillisec));
752
+ }
753
+ if (this.microsec_slider) {
754
+ this.control.options(this, this.microsec_slider, 'microsec', { min: this._defaults.microsecMin, max: microsecMax, step: this._defaults.stepMicrosec });
755
+ this.control.value(this, this.microsec_slider, 'microsec', this.microsec - (this.microsec % this._defaults.stepMicrosec));
756
+ }
757
+ }
758
+
759
+ },
760
+
761
+ /*
762
+ * when a slider moves, set the internal time...
763
+ * on time change is also called when the time is updated in the text field
764
+ */
765
+ _onTimeChange: function () {
766
+ if (!this._defaults.showTimepicker) {
767
+ return;
768
+ }
769
+ var hour = (this.hour_slider) ? this.control.value(this, this.hour_slider, 'hour') : false,
770
+ minute = (this.minute_slider) ? this.control.value(this, this.minute_slider, 'minute') : false,
771
+ second = (this.second_slider) ? this.control.value(this, this.second_slider, 'second') : false,
772
+ millisec = (this.millisec_slider) ? this.control.value(this, this.millisec_slider, 'millisec') : false,
773
+ microsec = (this.microsec_slider) ? this.control.value(this, this.microsec_slider, 'microsec') : false,
774
+ timezone = (this.timezone_select) ? this.timezone_select.val() : false,
775
+ o = this._defaults,
776
+ pickerTimeFormat = o.pickerTimeFormat || o.timeFormat,
777
+ pickerTimeSuffix = o.pickerTimeSuffix || o.timeSuffix;
778
+
779
+ if (typeof(hour) === 'object') {
780
+ hour = false;
781
+ }
782
+ if (typeof(minute) === 'object') {
783
+ minute = false;
784
+ }
785
+ if (typeof(second) === 'object') {
786
+ second = false;
787
+ }
788
+ if (typeof(millisec) === 'object') {
789
+ millisec = false;
790
+ }
791
+ if (typeof(microsec) === 'object') {
792
+ microsec = false;
793
+ }
794
+ if (typeof(timezone) === 'object') {
795
+ timezone = false;
796
+ }
797
+
798
+ if (hour !== false) {
799
+ hour = parseInt(hour, 10);
800
+ }
801
+ if (minute !== false) {
802
+ minute = parseInt(minute, 10);
803
+ }
804
+ if (second !== false) {
805
+ second = parseInt(second, 10);
806
+ }
807
+ if (millisec !== false) {
808
+ millisec = parseInt(millisec, 10);
809
+ }
810
+ if (microsec !== false) {
811
+ microsec = parseInt(microsec, 10);
812
+ }
813
+ if (timezone !== false) {
814
+ timezone = timezone.toString();
815
+ }
816
+
817
+ var ampm = o[hour < 12 ? 'amNames' : 'pmNames'][0];
818
+
819
+ // If the update was done in the input field, the input field should not be updated.
820
+ // If the update was done using the sliders, update the input field.
821
+ var hasChanged = (
822
+ hour !== parseInt(this.hour,10) || // sliders should all be numeric
823
+ minute !== parseInt(this.minute,10) ||
824
+ second !== parseInt(this.second,10) ||
825
+ millisec !== parseInt(this.millisec,10) ||
826
+ microsec !== parseInt(this.microsec,10) ||
827
+ (this.ampm.length > 0 && (hour < 12) !== ($.inArray(this.ampm.toUpperCase(), this.amNames) !== -1)) ||
828
+ (this.timezone !== null && timezone !== this.timezone.toString()) // could be numeric or "EST" format, so use toString()
829
+ );
830
+
831
+ if (hasChanged) {
832
+
833
+ if (hour !== false) {
834
+ this.hour = hour;
835
+ }
836
+ if (minute !== false) {
837
+ this.minute = minute;
838
+ }
839
+ if (second !== false) {
840
+ this.second = second;
841
+ }
842
+ if (millisec !== false) {
843
+ this.millisec = millisec;
844
+ }
845
+ if (microsec !== false) {
846
+ this.microsec = microsec;
847
+ }
848
+ if (timezone !== false) {
849
+ this.timezone = timezone;
850
+ }
851
+
852
+ if (!this.inst) {
853
+ this.inst = $.datepicker._getInst(this.$input[0]);
854
+ }
855
+
856
+ this._limitMinMaxDateTime(this.inst, true);
857
+ }
858
+ if (this.support.ampm) {
859
+ this.ampm = ampm;
860
+ }
861
+
862
+ // Updates the time within the timepicker
863
+ this.formattedTime = $.datepicker.formatTime(o.timeFormat, this, o);
864
+ if (this.$timeObj) {
865
+ if (pickerTimeFormat === o.timeFormat) {
866
+ this.$timeObj.text(this.formattedTime + pickerTimeSuffix);
867
+ }
868
+ else {
869
+ this.$timeObj.text($.datepicker.formatTime(pickerTimeFormat, this, o) + pickerTimeSuffix);
870
+ }
871
+ }
872
+
873
+ this.timeDefined = true;
874
+ if (hasChanged) {
875
+ this._updateDateTime();
876
+ //this.$input.focus(); // may automatically open the picker on setDate
877
+ }
878
+ },
879
+
880
+ /*
881
+ * call custom onSelect.
882
+ * bind to sliders slidestop, and grid click.
883
+ */
884
+ _onSelectHandler: function () {
885
+ var onSelect = this._defaults.onSelect || this.inst.settings.onSelect;
886
+ var inputEl = this.$input ? this.$input[0] : null;
887
+ if (onSelect && inputEl) {
888
+ onSelect.apply(inputEl, [this.formattedDateTime, this]);
889
+ }
890
+ },
891
+
892
+ /*
893
+ * update our input with the new date time..
894
+ */
895
+ _updateDateTime: function (dp_inst) {
896
+ dp_inst = this.inst || dp_inst;
897
+ var dtTmp = (dp_inst.currentYear > 0?
898
+ new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay) :
899
+ new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),
900
+ dt = $.datepicker._daylightSavingAdjust(dtTmp),
901
+ //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay)),
902
+ //dt = $.datepicker._daylightSavingAdjust(new Date(dp_inst.currentYear, dp_inst.currentMonth, dp_inst.currentDay)),
903
+ dateFmt = $.datepicker._get(dp_inst, 'dateFormat'),
904
+ formatCfg = $.datepicker._getFormatConfig(dp_inst),
905
+ timeAvailable = dt !== null && this.timeDefined;
906
+ this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg);
907
+ var formattedDateTime = this.formattedDate;
908
+
909
+ // if a slider was changed but datepicker doesn't have a value yet, set it
910
+ if (dp_inst.lastVal === "") {
911
+ dp_inst.currentYear = dp_inst.selectedYear;
912
+ dp_inst.currentMonth = dp_inst.selectedMonth;
913
+ dp_inst.currentDay = dp_inst.selectedDay;
914
+ }
915
+
916
+ /*
917
+ * remove following lines to force every changes in date picker to change the input value
918
+ * Bug descriptions: when an input field has a default value, and click on the field to pop up the date picker.
919
+ * If the user manually empty the value in the input field, the date picker will never change selected value.
920
+ */
921
+ //if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0)) {
922
+ // return;
923
+ //}
924
+
925
+ if (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === false) {
926
+ formattedDateTime = this.formattedTime;
927
+ } else if ((this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) || (this._defaults.timeOnly === true && this._defaults.timeOnlyShowDate === true)) {
928
+ formattedDateTime += this._defaults.separator + this.formattedTime + this._defaults.timeSuffix;
929
+ }
930
+
931
+ this.formattedDateTime = formattedDateTime;
932
+
933
+ if (!this._defaults.showTimepicker) {
934
+ this.$input.val(this.formattedDate);
935
+ } else if (this.$altInput && this._defaults.timeOnly === false && this._defaults.altFieldTimeOnly === true) {
936
+ this.$altInput.val(this.formattedTime);
937
+ this.$input.val(this.formattedDate);
938
+ } else if (this.$altInput) {
939
+ this.$input.val(formattedDateTime);
940
+ var altFormattedDateTime = '',
941
+ altSeparator = this._defaults.altSeparator !== null ? this._defaults.altSeparator : this._defaults.separator,
942
+ altTimeSuffix = this._defaults.altTimeSuffix !== null ? this._defaults.altTimeSuffix : this._defaults.timeSuffix;
943
+
944
+ if (!this._defaults.timeOnly) {
945
+ if (this._defaults.altFormat) {
946
+ altFormattedDateTime = $.datepicker.formatDate(this._defaults.altFormat, (dt === null ? new Date() : dt), formatCfg);
947
+ }
948
+ else {
949
+ altFormattedDateTime = this.formattedDate;
950
+ }
951
+
952
+ if (altFormattedDateTime) {
953
+ altFormattedDateTime += altSeparator;
954
+ }
955
+ }
956
+
957
+ if (this._defaults.altTimeFormat !== null) {
958
+ altFormattedDateTime += $.datepicker.formatTime(this._defaults.altTimeFormat, this, this._defaults) + altTimeSuffix;
959
+ }
960
+ else {
961
+ altFormattedDateTime += this.formattedTime + altTimeSuffix;
962
+ }
963
+ this.$altInput.val(altFormattedDateTime);
964
+ } else {
965
+ this.$input.val(formattedDateTime);
966
+ }
967
+
968
+ this.$input.trigger("change");
969
+ },
970
+
971
+ _onFocus: function () {
972
+ if (!this.$input.val() && this._defaults.defaultValue) {
973
+ this.$input.val(this._defaults.defaultValue);
974
+ var inst = $.datepicker._getInst(this.$input.get(0)),
975
+ tp_inst = $.datepicker._get(inst, 'timepicker');
976
+ if (tp_inst) {
977
+ if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) {
978
+ try {
979
+ $.datepicker._updateDatepicker(inst);
980
+ } catch (err) {
981
+ $.timepicker.log(err);
982
+ }
983
+ }
984
+ }
985
+ }
986
+ },
987
+
988
+ /*
989
+ * Small abstraction to control types
990
+ * We can add more, just be sure to follow the pattern: create, options, value
991
+ */
992
+ _controls: {
993
+ // slider methods
994
+ slider: {
995
+ create: function (tp_inst, obj, unit, val, min, max, step) {
996
+ var rtl = tp_inst._defaults.isRTL; // if rtl go -60->0 instead of 0->60
997
+ return obj.prop('slide', null).slider({
998
+ orientation: "horizontal",
999
+ value: rtl ? val * -1 : val,
1000
+ min: rtl ? max * -1 : min,
1001
+ max: rtl ? min * -1 : max,
1002
+ step: step,
1003
+ slide: function (event, ui) {
1004
+ tp_inst.control.value(tp_inst, $(this), unit, rtl ? ui.value * -1 : ui.value);
1005
+ tp_inst._onTimeChange();
1006
+ },
1007
+ stop: function (event, ui) {
1008
+ tp_inst._onSelectHandler();
1009
+ }
1010
+ });
1011
+ },
1012
+ options: function (tp_inst, obj, unit, opts, val) {
1013
+ if (tp_inst._defaults.isRTL) {
1014
+ if (typeof(opts) === 'string') {
1015
+ if (opts === 'min' || opts === 'max') {
1016
+ if (val !== undefined) {
1017
+ return obj.slider(opts, val * -1);
1018
+ }
1019
+ return Math.abs(obj.slider(opts));
1020
+ }
1021
+ return obj.slider(opts);
1022
+ }
1023
+ var min = opts.min,
1024
+ max = opts.max;
1025
+ opts.min = opts.max = null;
1026
+ if (min !== undefined) {
1027
+ opts.max = min * -1;
1028
+ }
1029
+ if (max !== undefined) {
1030
+ opts.min = max * -1;
1031
+ }
1032
+ return obj.slider(opts);
1033
+ }
1034
+ if (typeof(opts) === 'string' && val !== undefined) {
1035
+ return obj.slider(opts, val);
1036
+ }
1037
+ return obj.slider(opts);
1038
+ },
1039
+ value: function (tp_inst, obj, unit, val) {
1040
+ if (tp_inst._defaults.isRTL) {
1041
+ if (val !== undefined) {
1042
+ return obj.slider('value', val * -1);
1043
+ }
1044
+ return Math.abs(obj.slider('value'));
1045
+ }
1046
+ if (val !== undefined) {
1047
+ return obj.slider('value', val);
1048
+ }
1049
+ return obj.slider('value');
1050
+ }
1051
+ },
1052
+ // select methods
1053
+ select: {
1054
+ create: function (tp_inst, obj, unit, val, min, max, step) {
1055
+ var sel = '<select class="ui-timepicker-select ui-state-default ui-corner-all" data-unit="' + unit + '" data-min="' + min + '" data-max="' + max + '" data-step="' + step + '">',
1056
+ format = tp_inst._defaults.pickerTimeFormat || tp_inst._defaults.timeFormat;
1057
+
1058
+ for (var i = min; i <= max; i += step) {
1059
+ sel += '<option value="' + i + '"' + (i === val ? ' selected' : '') + '>';
1060
+ if (unit === 'hour') {
1061
+ sel += $.datepicker.formatTime($.trim(format.replace(/[^ht ]/ig, '')), {hour: i}, tp_inst._defaults);
1062
+ }
1063
+ else if (unit === 'millisec' || unit === 'microsec' || i >= 10) { sel += i; }
1064
+ else {sel += '0' + i.toString(); }
1065
+ sel += '</option>';
1066
+ }
1067
+ sel += '</select>';
1068
+
1069
+ obj.children('select').remove();
1070
+
1071
+ $(sel).appendTo(obj).change(function (e) {
1072
+ tp_inst._onTimeChange();
1073
+ tp_inst._onSelectHandler();
1074
+ tp_inst._afterInject();
1075
+ });
1076
+
1077
+ return obj;
1078
+ },
1079
+ options: function (tp_inst, obj, unit, opts, val) {
1080
+ var o = {},
1081
+ $t = obj.children('select');
1082
+ if (typeof(opts) === 'string') {
1083
+ if (val === undefined) {
1084
+ return $t.data(opts);
1085
+ }
1086
+ o[opts] = val;
1087
+ }
1088
+ else { o = opts; }
1089
+ return tp_inst.control.create(tp_inst, obj, $t.data('unit'), $t.val(), o.min>=0 ? o.min : $t.data('min'), o.max || $t.data('max'), o.step || $t.data('step'));
1090
+ },
1091
+ value: function (tp_inst, obj, unit, val) {
1092
+ var $t = obj.children('select');
1093
+ if (val !== undefined) {
1094
+ return $t.val(val);
1095
+ }
1096
+ return $t.val();
1097
+ }
1098
+ }
1099
+ } // end _controls
1100
+
1101
+ });
1102
+
1103
+ $.fn.extend({
1104
+ /*
1105
+ * shorthand just to use timepicker.
1106
+ */
1107
+ timepicker: function (o) {
1108
+ o = o || {};
1109
+ var tmp_args = Array.prototype.slice.call(arguments);
1110
+
1111
+ if (typeof o === 'object') {
1112
+ tmp_args[0] = $.extend(o, {
1113
+ timeOnly: true
1114
+ });
1115
+ }
1116
+
1117
+ return $(this).each(function () {
1118
+ $.fn.datetimepicker.apply($(this), tmp_args);
1119
+ });
1120
+ },
1121
+
1122
+ /*
1123
+ * extend timepicker to datepicker
1124
+ */
1125
+ datetimepicker: function (o) {
1126
+ o = o || {};
1127
+ var tmp_args = arguments;
1128
+
1129
+ if (typeof(o) === 'string') {
1130
+ if (o === 'getDate' || (o === 'option' && tmp_args.length === 2 && typeof (tmp_args[1]) === 'string')) {
1131
+ return $.fn.datepicker.apply($(this[0]), tmp_args);
1132
+ } else {
1133
+ return this.each(function () {
1134
+ var $t = $(this);
1135
+ $t.datepicker.apply($t, tmp_args);
1136
+ });
1137
+ }
1138
+ } else {
1139
+ return this.each(function () {
1140
+ var $t = $(this);
1141
+ $t.datepicker($.timepicker._newInst($t, o)._defaults);
1142
+ });
1143
+ }
1144
+ }
1145
+ });
1146
+
1147
+ /*
1148
+ * Public Utility to parse date and time
1149
+ */
1150
+ $.datepicker.parseDateTime = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {
1151
+ var parseRes = parseDateTimeInternal(dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings);
1152
+ if (parseRes.timeObj) {
1153
+ var t = parseRes.timeObj;
1154
+ parseRes.date.setHours(t.hour, t.minute, t.second, t.millisec);
1155
+ parseRes.date.setMicroseconds(t.microsec);
1156
+ }
1157
+
1158
+ return parseRes.date;
1159
+ };
1160
+
1161
+ /*
1162
+ * Public utility to parse time
1163
+ */
1164
+ $.datepicker.parseTime = function (timeFormat, timeString, options) {
1165
+ var o = extendRemove(extendRemove({}, $.timepicker._defaults), options || {}),
1166
+ iso8601 = (timeFormat.replace(/\'.*?\'/g, '').indexOf('Z') !== -1);
1167
+
1168
+ // Strict parse requires the timeString to match the timeFormat exactly
1169
+ var strictParse = function (f, s, o) {
1170
+
1171
+ // pattern for standard and localized AM/PM markers
1172
+ var getPatternAmpm = function (amNames, pmNames) {
1173
+ var markers = [];
1174
+ if (amNames) {
1175
+ $.merge(markers, amNames);
1176
+ }
1177
+ if (pmNames) {
1178
+ $.merge(markers, pmNames);
1179
+ }
1180
+ markers = $.map(markers, function (val) {
1181
+ return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&');
1182
+ });
1183
+ return '(' + markers.join('|') + ')?';
1184
+ };
1185
+
1186
+ // figure out position of time elements.. cause js cant do named captures
1187
+ var getFormatPositions = function (timeFormat) {
1188
+ var finds = timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|c{1}|t{1,2}|z|'.*?')/g),
1189
+ orders = {
1190
+ h: -1,
1191
+ m: -1,
1192
+ s: -1,
1193
+ l: -1,
1194
+ c: -1,
1195
+ t: -1,
1196
+ z: -1
1197
+ };
1198
+
1199
+ if (finds) {
1200
+ for (var i = 0; i < finds.length; i++) {
1201
+ if (orders[finds[i].toString().charAt(0)] === -1) {
1202
+ orders[finds[i].toString().charAt(0)] = i + 1;
1203
+ }
1204
+ }
1205
+ }
1206
+ return orders;
1207
+ };
1208
+
1209
+ var regstr = '^' + f.toString()
1210
+ .replace(/([hH]{1,2}|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {
1211
+ var ml = match.length;
1212
+ switch (match.charAt(0).toLowerCase()) {
1213
+ case 'h':
1214
+ return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})';
1215
+ case 'm':
1216
+ return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})';
1217
+ case 's':
1218
+ return ml === 1 ? '(\\d?\\d)' : '(\\d{' + ml + '})';
1219
+ case 'l':
1220
+ return '(\\d?\\d?\\d)';
1221
+ case 'c':
1222
+ return '(\\d?\\d?\\d)';
1223
+ case 'z':
1224
+ return '(z|[-+]\\d\\d:?\\d\\d|\\S+)?';
1225
+ case 't':
1226
+ return getPatternAmpm(o.amNames, o.pmNames);
1227
+ default: // literal escaped in quotes
1228
+ return '(' + match.replace(/\'/g, "").replace(/(\.|\$|\^|\\|\/|\(|\)|\[|\]|\?|\+|\*)/g, function (m) { return "\\" + m; }) + ')?';
1229
+ }
1230
+ })
1231
+ .replace(/\s/g, '\\s?') +
1232
+ o.timeSuffix + '$',
1233
+ order = getFormatPositions(f),
1234
+ ampm = '',
1235
+ treg;
1236
+
1237
+ treg = s.match(new RegExp(regstr, 'i'));
1238
+
1239
+ var resTime = {
1240
+ hour: 0,
1241
+ minute: 0,
1242
+ second: 0,
1243
+ millisec: 0,
1244
+ microsec: 0
1245
+ };
1246
+
1247
+ if (treg) {
1248
+ if (order.t !== -1) {
1249
+ if (treg[order.t] === undefined || treg[order.t].length === 0) {
1250
+ ampm = '';
1251
+ resTime.ampm = '';
1252
+ } else {
1253
+ ampm = $.inArray(treg[order.t].toUpperCase(), $.map(o.amNames, function (x,i) { return x.toUpperCase(); })) !== -1 ? 'AM' : 'PM';
1254
+ resTime.ampm = o[ampm === 'AM' ? 'amNames' : 'pmNames'][0];
1255
+ }
1256
+ }
1257
+
1258
+ if (order.h !== -1) {
1259
+ if (ampm === 'AM' && treg[order.h] === '12') {
1260
+ resTime.hour = 0; // 12am = 0 hour
1261
+ } else {
1262
+ if (ampm === 'PM' && treg[order.h] !== '12') {
1263
+ resTime.hour = parseInt(treg[order.h], 10) + 12; // 12pm = 12 hour, any other pm = hour + 12
1264
+ } else {
1265
+ resTime.hour = Number(treg[order.h]);
1266
+ }
1267
+ }
1268
+ }
1269
+
1270
+ if (order.m !== -1) {
1271
+ resTime.minute = Number(treg[order.m]);
1272
+ }
1273
+ if (order.s !== -1) {
1274
+ resTime.second = Number(treg[order.s]);
1275
+ }
1276
+ if (order.l !== -1) {
1277
+ resTime.millisec = Number(treg[order.l]);
1278
+ }
1279
+ if (order.c !== -1) {
1280
+ resTime.microsec = Number(treg[order.c]);
1281
+ }
1282
+ if (order.z !== -1 && treg[order.z] !== undefined) {
1283
+ resTime.timezone = $.timepicker.timezoneOffsetNumber(treg[order.z]);
1284
+ }
1285
+
1286
+
1287
+ return resTime;
1288
+ }
1289
+ return false;
1290
+ };// end strictParse
1291
+
1292
+ // First try JS Date, if that fails, use strictParse
1293
+ var looseParse = function (f, s, o) {
1294
+ try {
1295
+ var d = new Date('2012-01-01 ' + s);
1296
+ if (isNaN(d.getTime())) {
1297
+ d = new Date('2012-01-01T' + s);
1298
+ if (isNaN(d.getTime())) {
1299
+ d = new Date('01/01/2012 ' + s);
1300
+ if (isNaN(d.getTime())) {
1301
+ throw "Unable to parse time with native Date: " + s;
1302
+ }
1303
+ }
1304
+ }
1305
+
1306
+ return {
1307
+ hour: d.getHours(),
1308
+ minute: d.getMinutes(),
1309
+ second: d.getSeconds(),
1310
+ millisec: d.getMilliseconds(),
1311
+ microsec: d.getMicroseconds(),
1312
+ timezone: d.getTimezoneOffset() * -1
1313
+ };
1314
+ }
1315
+ catch (err) {
1316
+ try {
1317
+ return strictParse(f, s, o);
1318
+ }
1319
+ catch (err2) {
1320
+ $.timepicker.log("Unable to parse \ntimeString: " + s + "\ntimeFormat: " + f);
1321
+ }
1322
+ }
1323
+ return false;
1324
+ }; // end looseParse
1325
+
1326
+ if (typeof o.parse === "function") {
1327
+ return o.parse(timeFormat, timeString, o);
1328
+ }
1329
+ if (o.parse === 'loose') {
1330
+ return looseParse(timeFormat, timeString, o);
1331
+ }
1332
+ return strictParse(timeFormat, timeString, o);
1333
+ };
1334
+
1335
+ /**
1336
+ * Public utility to format the time
1337
+ * @param {string} format format of the time
1338
+ * @param {Object} time Object not a Date for timezones
1339
+ * @param {Object} [options] essentially the regional[].. amNames, pmNames, ampm
1340
+ * @returns {string} the formatted time
1341
+ */
1342
+ $.datepicker.formatTime = function (format, time, options) {
1343
+ options = options || {};
1344
+ options = $.extend({}, $.timepicker._defaults, options);
1345
+ time = $.extend({
1346
+ hour: 0,
1347
+ minute: 0,
1348
+ second: 0,
1349
+ millisec: 0,
1350
+ microsec: 0,
1351
+ timezone: null
1352
+ }, time);
1353
+
1354
+ var tmptime = format,
1355
+ ampmName = options.amNames[0],
1356
+ hour = parseInt(time.hour, 10);
1357
+
1358
+ if (hour > 11) {
1359
+ ampmName = options.pmNames[0];
1360
+ }
1361
+
1362
+ tmptime = tmptime.replace(/(?:HH?|hh?|mm?|ss?|[tT]{1,2}|[zZ]|[lc]|'.*?')/g, function (match) {
1363
+ switch (match) {
1364
+ case 'HH':
1365
+ return ('0' + hour).slice(-2);
1366
+ case 'H':
1367
+ return hour;
1368
+ case 'hh':
1369
+ return ('0' + convert24to12(hour)).slice(-2);
1370
+ case 'h':
1371
+ return convert24to12(hour);
1372
+ case 'mm':
1373
+ return ('0' + time.minute).slice(-2);
1374
+ case 'm':
1375
+ return time.minute;
1376
+ case 'ss':
1377
+ return ('0' + time.second).slice(-2);
1378
+ case 's':
1379
+ return time.second;
1380
+ case 'l':
1381
+ return ('00' + time.millisec).slice(-3);
1382
+ case 'c':
1383
+ return ('00' + time.microsec).slice(-3);
1384
+ case 'z':
1385
+ return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, false);
1386
+ case 'Z':
1387
+ return $.timepicker.timezoneOffsetString(time.timezone === null ? options.timezone : time.timezone, true);
1388
+ case 'T':
1389
+ return ampmName.charAt(0).toUpperCase();
1390
+ case 'TT':
1391
+ return ampmName.toUpperCase();
1392
+ case 't':
1393
+ return ampmName.charAt(0).toLowerCase();
1394
+ case 'tt':
1395
+ return ampmName.toLowerCase();
1396
+ default:
1397
+ return match.replace(/'/g, "");
1398
+ }
1399
+ });
1400
+
1401
+ return tmptime;
1402
+ };
1403
+
1404
+ /*
1405
+ * the bad hack :/ override datepicker so it doesn't close on select
1406
+ // inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378
1407
+ */
1408
+ $.datepicker._base_selectDate = $.datepicker._selectDate;
1409
+ $.datepicker._selectDate = function (id, dateStr) {
1410
+ var inst = this._getInst($(id)[0]),
1411
+ tp_inst = this._get(inst, 'timepicker'),
1412
+ was_inline;
1413
+
1414
+ if (tp_inst && inst.settings.showTimepicker) {
1415
+ tp_inst._limitMinMaxDateTime(inst, true);
1416
+ was_inline = inst.inline;
1417
+ inst.inline = inst.stay_open = true;
1418
+ //This way the onSelect handler called from calendarpicker get the full dateTime
1419
+ this._base_selectDate(id, dateStr);
1420
+ inst.inline = was_inline;
1421
+ inst.stay_open = false;
1422
+ this._notifyChange(inst);
1423
+ this._updateDatepicker(inst);
1424
+ } else {
1425
+ this._base_selectDate(id, dateStr);
1426
+ }
1427
+ };
1428
+
1429
+ /*
1430
+ * second bad hack :/ override datepicker so it triggers an event when changing the input field
1431
+ * and does not redraw the datepicker on every selectDate event
1432
+ */
1433
+ $.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker;
1434
+ $.datepicker._updateDatepicker = function (inst) {
1435
+
1436
+ // don't popup the datepicker if there is another instance already opened
1437
+ var input = inst.input[0];
1438
+ if ($.datepicker._curInst && $.datepicker._curInst !== inst && $.datepicker._datepickerShowing && $.datepicker._lastInput !== input) {
1439
+ return;
1440
+ }
1441
+
1442
+ if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) {
1443
+
1444
+ this._base_updateDatepicker(inst);
1445
+
1446
+ // Reload the time control when changing something in the input text field.
1447
+ var tp_inst = this._get(inst, 'timepicker');
1448
+ if (tp_inst) {
1449
+ tp_inst._addTimePicker(inst);
1450
+ }
1451
+ }
1452
+ };
1453
+
1454
+ /*
1455
+ * third bad hack :/ override datepicker so it allows spaces and colon in the input field
1456
+ */
1457
+ $.datepicker._base_doKeyPress = $.datepicker._doKeyPress;
1458
+ $.datepicker._doKeyPress = function (event) {
1459
+ var inst = $.datepicker._getInst(event.target),
1460
+ tp_inst = $.datepicker._get(inst, 'timepicker');
1461
+
1462
+ if (tp_inst) {
1463
+ if ($.datepicker._get(inst, 'constrainInput')) {
1464
+ var ampm = tp_inst.support.ampm,
1465
+ tz = tp_inst._defaults.showTimezone !== null ? tp_inst._defaults.showTimezone : tp_inst.support.timezone,
1466
+ dateChars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')),
1467
+ datetimeChars = tp_inst._defaults.timeFormat.toString()
1468
+ .replace(/[hms]/g, '')
1469
+ .replace(/TT/g, ampm ? 'APM' : '')
1470
+ .replace(/Tt/g, ampm ? 'AaPpMm' : '')
1471
+ .replace(/tT/g, ampm ? 'AaPpMm' : '')
1472
+ .replace(/T/g, ampm ? 'AP' : '')
1473
+ .replace(/tt/g, ampm ? 'apm' : '')
1474
+ .replace(/t/g, ampm ? 'ap' : '') +
1475
+ " " + tp_inst._defaults.separator +
1476
+ tp_inst._defaults.timeSuffix +
1477
+ (tz ? tp_inst._defaults.timezoneList.join('') : '') +
1478
+ (tp_inst._defaults.amNames.join('')) + (tp_inst._defaults.pmNames.join('')) +
1479
+ dateChars,
1480
+ chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode);
1481
+ return event.ctrlKey || (chr < ' ' || !dateChars || datetimeChars.indexOf(chr) > -1);
1482
+ }
1483
+ }
1484
+
1485
+ return $.datepicker._base_doKeyPress(event);
1486
+ };
1487
+
1488
+ /*
1489
+ * Fourth bad hack :/ override _updateAlternate function used in inline mode to init altField
1490
+ * Update any alternate field to synchronise with the main field.
1491
+ */
1492
+ $.datepicker._base_updateAlternate = $.datepicker._updateAlternate;
1493
+ $.datepicker._updateAlternate = function (inst) {
1494
+ var tp_inst = this._get(inst, 'timepicker');
1495
+ if (tp_inst) {
1496
+ var altField = tp_inst._defaults.altField;
1497
+ if (altField) { // update alternate field too
1498
+ var altFormat = tp_inst._defaults.altFormat || tp_inst._defaults.dateFormat,
1499
+ date = this._getDate(inst),
1500
+ formatCfg = $.datepicker._getFormatConfig(inst),
1501
+ altFormattedDateTime = '',
1502
+ altSeparator = tp_inst._defaults.altSeparator ? tp_inst._defaults.altSeparator : tp_inst._defaults.separator,
1503
+ altTimeSuffix = tp_inst._defaults.altTimeSuffix ? tp_inst._defaults.altTimeSuffix : tp_inst._defaults.timeSuffix,
1504
+ altTimeFormat = tp_inst._defaults.altTimeFormat !== null ? tp_inst._defaults.altTimeFormat : tp_inst._defaults.timeFormat;
1505
+
1506
+ altFormattedDateTime += $.datepicker.formatTime(altTimeFormat, tp_inst, tp_inst._defaults) + altTimeSuffix;
1507
+ if (!tp_inst._defaults.timeOnly && !tp_inst._defaults.altFieldTimeOnly && date !== null) {
1508
+ if (tp_inst._defaults.altFormat) {
1509
+ altFormattedDateTime = $.datepicker.formatDate(tp_inst._defaults.altFormat, date, formatCfg) + altSeparator + altFormattedDateTime;
1510
+ }
1511
+ else {
1512
+ altFormattedDateTime = tp_inst.formattedDate + altSeparator + altFormattedDateTime;
1513
+ }
1514
+ }
1515
+ $(altField).val( inst.input.val() ? altFormattedDateTime : "");
1516
+ }
1517
+ }
1518
+ else {
1519
+ $.datepicker._base_updateAlternate(inst);
1520
+ }
1521
+ };
1522
+
1523
+ /*
1524
+ * Override key up event to sync manual input changes.
1525
+ */
1526
+ $.datepicker._base_doKeyUp = $.datepicker._doKeyUp;
1527
+ $.datepicker._doKeyUp = function (event) {
1528
+ var inst = $.datepicker._getInst(event.target),
1529
+ tp_inst = $.datepicker._get(inst, 'timepicker');
1530
+
1531
+ if (tp_inst) {
1532
+ if (tp_inst._defaults.timeOnly && (inst.input.val() !== inst.lastVal)) {
1533
+ try {
1534
+ $.datepicker._updateDatepicker(inst);
1535
+ } catch (err) {
1536
+ $.timepicker.log(err);
1537
+ }
1538
+ }
1539
+ }
1540
+
1541
+ return $.datepicker._base_doKeyUp(event);
1542
+ };
1543
+
1544
+ /*
1545
+ * override "Today" button to also grab the time.
1546
+ */
1547
+ $.datepicker._base_gotoToday = $.datepicker._gotoToday;
1548
+ $.datepicker._gotoToday = function (id) {
1549
+ var inst = this._getInst($(id)[0]),
1550
+ $dp = inst.dpDiv;
1551
+ this._base_gotoToday(id);
1552
+ var tp_inst = this._get(inst, 'timepicker');
1553
+ selectLocalTimezone(tp_inst);
1554
+ var now = new Date();
1555
+ this._setTime(inst, now);
1556
+ this._setDate(inst, now);
1557
+ };
1558
+
1559
+ /*
1560
+ * Disable & enable the Time in the datetimepicker
1561
+ */
1562
+ $.datepicker._disableTimepickerDatepicker = function (target) {
1563
+ var inst = this._getInst(target);
1564
+ if (!inst) {
1565
+ return;
1566
+ }
1567
+
1568
+ var tp_inst = this._get(inst, 'timepicker');
1569
+ $(target).datepicker('getDate'); // Init selected[Year|Month|Day]
1570
+ if (tp_inst) {
1571
+ inst.settings.showTimepicker = false;
1572
+ tp_inst._defaults.showTimepicker = false;
1573
+ tp_inst._updateDateTime(inst);
1574
+ }
1575
+ };
1576
+
1577
+ $.datepicker._enableTimepickerDatepicker = function (target) {
1578
+ var inst = this._getInst(target);
1579
+ if (!inst) {
1580
+ return;
1581
+ }
1582
+
1583
+ var tp_inst = this._get(inst, 'timepicker');
1584
+ $(target).datepicker('getDate'); // Init selected[Year|Month|Day]
1585
+ if (tp_inst) {
1586
+ inst.settings.showTimepicker = true;
1587
+ tp_inst._defaults.showTimepicker = true;
1588
+ tp_inst._addTimePicker(inst); // Could be disabled on page load
1589
+ tp_inst._updateDateTime(inst);
1590
+ }
1591
+ };
1592
+
1593
+ /*
1594
+ * Create our own set time function
1595
+ */
1596
+ $.datepicker._setTime = function (inst, date) {
1597
+ var tp_inst = this._get(inst, 'timepicker');
1598
+ if (tp_inst) {
1599
+ var defaults = tp_inst._defaults;
1600
+
1601
+ // calling _setTime with no date sets time to defaults
1602
+ tp_inst.hour = date ? date.getHours() : defaults.hour;
1603
+ tp_inst.minute = date ? date.getMinutes() : defaults.minute;
1604
+ tp_inst.second = date ? date.getSeconds() : defaults.second;
1605
+ tp_inst.millisec = date ? date.getMilliseconds() : defaults.millisec;
1606
+ tp_inst.microsec = date ? date.getMicroseconds() : defaults.microsec;
1607
+
1608
+ //check if within min/max times..
1609
+ tp_inst._limitMinMaxDateTime(inst, true);
1610
+
1611
+ tp_inst._onTimeChange();
1612
+ tp_inst._updateDateTime(inst);
1613
+ }
1614
+ };
1615
+
1616
+ /*
1617
+ * Create new public method to set only time, callable as $().datepicker('setTime', date)
1618
+ */
1619
+ $.datepicker._setTimeDatepicker = function (target, date, withDate) {
1620
+ var inst = this._getInst(target);
1621
+ if (!inst) {
1622
+ return;
1623
+ }
1624
+
1625
+ var tp_inst = this._get(inst, 'timepicker');
1626
+
1627
+ if (tp_inst) {
1628
+ this._setDateFromField(inst);
1629
+ var tp_date;
1630
+ if (date) {
1631
+ if (typeof date === "string") {
1632
+ tp_inst._parseTime(date, withDate);
1633
+ tp_date = new Date();
1634
+ tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);
1635
+ tp_date.setMicroseconds(tp_inst.microsec);
1636
+ } else {
1637
+ tp_date = new Date(date.getTime());
1638
+ tp_date.setMicroseconds(date.getMicroseconds());
1639
+ }
1640
+ if (tp_date.toString() === 'Invalid Date') {
1641
+ tp_date = undefined;
1642
+ }
1643
+ this._setTime(inst, tp_date);
1644
+ }
1645
+ }
1646
+
1647
+ };
1648
+
1649
+ /*
1650
+ * override setDate() to allow setting time too within Date object
1651
+ */
1652
+ $.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker;
1653
+ $.datepicker._setDateDatepicker = function (target, _date) {
1654
+ var inst = this._getInst(target);
1655
+ var date = _date;
1656
+ if (!inst) {
1657
+ return;
1658
+ }
1659
+
1660
+ if (typeof(_date) === 'string') {
1661
+ date = new Date(_date);
1662
+ if (!date.getTime()) {
1663
+ this._base_setDateDatepicker.apply(this, arguments);
1664
+ date = $(target).datepicker('getDate');
1665
+ }
1666
+ }
1667
+
1668
+ var tp_inst = this._get(inst, 'timepicker');
1669
+ var tp_date;
1670
+ if (date instanceof Date) {
1671
+ tp_date = new Date(date.getTime());
1672
+ tp_date.setMicroseconds(date.getMicroseconds());
1673
+ } else {
1674
+ tp_date = date;
1675
+ }
1676
+
1677
+ // This is important if you are using the timezone option, javascript's Date
1678
+ // object will only return the timezone offset for the current locale, so we
1679
+ // adjust it accordingly. If not using timezone option this won't matter..
1680
+ // If a timezone is different in tp, keep the timezone as is
1681
+ if (tp_inst && tp_date) {
1682
+ // look out for DST if tz wasn't specified
1683
+ if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) {
1684
+ tp_inst.timezone = tp_date.getTimezoneOffset() * -1;
1685
+ }
1686
+ date = $.timepicker.timezoneAdjust(date, tp_inst.timezone);
1687
+ tp_date = $.timepicker.timezoneAdjust(tp_date, tp_inst.timezone);
1688
+ }
1689
+
1690
+ this._updateDatepicker(inst);
1691
+ this._base_setDateDatepicker.apply(this, arguments);
1692
+ this._setTimeDatepicker(target, tp_date, true);
1693
+ };
1694
+
1695
+ /*
1696
+ * override getDate() to allow getting time too within Date object
1697
+ */
1698
+ $.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker;
1699
+ $.datepicker._getDateDatepicker = function (target, noDefault) {
1700
+ var inst = this._getInst(target);
1701
+ if (!inst) {
1702
+ return;
1703
+ }
1704
+
1705
+ var tp_inst = this._get(inst, 'timepicker');
1706
+
1707
+ if (tp_inst) {
1708
+ // if it hasn't yet been defined, grab from field
1709
+ if (inst.lastVal === undefined) {
1710
+ this._setDateFromField(inst, noDefault);
1711
+ }
1712
+
1713
+ var date = this._getDate(inst);
1714
+ if (date && tp_inst._parseTime($(target).val(), tp_inst.timeOnly)) {
1715
+ date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second, tp_inst.millisec);
1716
+ date.setMicroseconds(tp_inst.microsec);
1717
+
1718
+ // This is important if you are using the timezone option, javascript's Date
1719
+ // object will only return the timezone offset for the current locale, so we
1720
+ // adjust it accordingly. If not using timezone option this won't matter..
1721
+ if (tp_inst.timezone != null) {
1722
+ // look out for DST if tz wasn't specified
1723
+ if (!tp_inst.support.timezone && tp_inst._defaults.timezone === null) {
1724
+ tp_inst.timezone = date.getTimezoneOffset() * -1;
1725
+ }
1726
+ date = $.timepicker.timezoneAdjust(date, tp_inst.timezone);
1727
+ }
1728
+ }
1729
+ return date;
1730
+ }
1731
+ return this._base_getDateDatepicker(target, noDefault);
1732
+ };
1733
+
1734
+ /*
1735
+ * override parseDate() because UI 1.8.14 throws an error about "Extra characters"
1736
+ * An option in datapicker to ignore extra format characters would be nicer.
1737
+ */
1738
+ $.datepicker._base_parseDate = $.datepicker.parseDate;
1739
+ $.datepicker.parseDate = function (format, value, settings) {
1740
+ var date;
1741
+ try {
1742
+ date = this._base_parseDate(format, value, settings);
1743
+ } catch (err) {
1744
+ // Hack! The error message ends with a colon, a space, and
1745
+ // the "extra" characters. We rely on that instead of
1746
+ // attempting to perfectly reproduce the parsing algorithm.
1747
+ if (err.indexOf(":") >= 0) {
1748
+ date = this._base_parseDate(format, value.substring(0, value.length - (err.length - err.indexOf(':') - 2)), settings);
1749
+ $.timepicker.log("Error parsing the date string: " + err + "\ndate string = " + value + "\ndate format = " + format);
1750
+ } else {
1751
+ throw err;
1752
+ }
1753
+ }
1754
+ return date;
1755
+ };
1756
+
1757
+ /*
1758
+ * override formatDate to set date with time to the input
1759
+ */
1760
+ $.datepicker._base_formatDate = $.datepicker._formatDate;
1761
+ $.datepicker._formatDate = function (inst, day, month, year) {
1762
+ var tp_inst = this._get(inst, 'timepicker');
1763
+ if (tp_inst) {
1764
+ tp_inst._updateDateTime(inst);
1765
+ return tp_inst.$input.val();
1766
+ }
1767
+ return this._base_formatDate(inst);
1768
+ };
1769
+
1770
+ /*
1771
+ * override options setter to add time to maxDate(Time) and minDate(Time). MaxDate
1772
+ */
1773
+ $.datepicker._base_optionDatepicker = $.datepicker._optionDatepicker;
1774
+ $.datepicker._optionDatepicker = function (target, name, value) {
1775
+ var inst = this._getInst(target),
1776
+ name_clone;
1777
+ if (!inst) {
1778
+ return null;
1779
+ }
1780
+
1781
+ var tp_inst = this._get(inst, 'timepicker');
1782
+ if (tp_inst) {
1783
+ var min = null,
1784
+ max = null,
1785
+ onselect = null,
1786
+ overrides = tp_inst._defaults.evnts,
1787
+ fns = {},
1788
+ prop,
1789
+ ret,
1790
+ oldVal,
1791
+ $target;
1792
+ if (typeof name === 'string') { // if min/max was set with the string
1793
+ if (name === 'minDate' || name === 'minDateTime') {
1794
+ min = value;
1795
+ } else if (name === 'maxDate' || name === 'maxDateTime') {
1796
+ max = value;
1797
+ } else if (name === 'onSelect') {
1798
+ onselect = value;
1799
+ } else if (overrides.hasOwnProperty(name)) {
1800
+ if (typeof (value) === 'undefined') {
1801
+ return overrides[name];
1802
+ }
1803
+ fns[name] = value;
1804
+ name_clone = {}; //empty results in exiting function after overrides updated
1805
+ }
1806
+ } else if (typeof name === 'object') { //if min/max was set with the JSON
1807
+ if (name.minDate) {
1808
+ min = name.minDate;
1809
+ } else if (name.minDateTime) {
1810
+ min = name.minDateTime;
1811
+ } else if (name.maxDate) {
1812
+ max = name.maxDate;
1813
+ } else if (name.maxDateTime) {
1814
+ max = name.maxDateTime;
1815
+ }
1816
+ for (prop in overrides) {
1817
+ if (overrides.hasOwnProperty(prop) && name[prop]) {
1818
+ fns[prop] = name[prop];
1819
+ }
1820
+ }
1821
+ }
1822
+ for (prop in fns) {
1823
+ if (fns.hasOwnProperty(prop)) {
1824
+ overrides[prop] = fns[prop];
1825
+ if (!name_clone) { name_clone = $.extend({}, name); }
1826
+ delete name_clone[prop];
1827
+ }
1828
+ }
1829
+ if (name_clone && isEmptyObject(name_clone)) { return; }
1830
+ if (min) { //if min was set
1831
+ if (min === 0) {
1832
+ min = new Date();
1833
+ } else {
1834
+ min = new Date(min);
1835
+ }
1836
+ tp_inst._defaults.minDate = min;
1837
+ tp_inst._defaults.minDateTime = min;
1838
+ } else if (max) { //if max was set
1839
+ if (max === 0) {
1840
+ max = new Date();
1841
+ } else {
1842
+ max = new Date(max);
1843
+ }
1844
+ tp_inst._defaults.maxDate = max;
1845
+ tp_inst._defaults.maxDateTime = max;
1846
+ } else if (onselect) {
1847
+ tp_inst._defaults.onSelect = onselect;
1848
+ }
1849
+
1850
+ // Datepicker will override our date when we call _base_optionDatepicker when
1851
+ // calling minDate/maxDate, so we will first grab the value, call
1852
+ // _base_optionDatepicker, then set our value back.
1853
+ if(min || max){
1854
+ $target = $(target);
1855
+ oldVal = $target.datetimepicker('getDate');
1856
+ ret = this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value);
1857
+ $target.datetimepicker('setDate', oldVal);
1858
+ return ret;
1859
+ }
1860
+ }
1861
+ if (value === undefined) {
1862
+ return this._base_optionDatepicker.call($.datepicker, target, name);
1863
+ }
1864
+ return this._base_optionDatepicker.call($.datepicker, target, name_clone || name, value);
1865
+ };
1866
+
1867
+ /*
1868
+ * jQuery isEmptyObject does not check hasOwnProperty - if someone has added to the object prototype,
1869
+ * it will return false for all objects
1870
+ */
1871
+ var isEmptyObject = function (obj) {
1872
+ var prop;
1873
+ for (prop in obj) {
1874
+ if (obj.hasOwnProperty(prop)) {
1875
+ return false;
1876
+ }
1877
+ }
1878
+ return true;
1879
+ };
1880
+
1881
+ /*
1882
+ * jQuery extend now ignores nulls!
1883
+ */
1884
+ var extendRemove = function (target, props) {
1885
+ $.extend(target, props);
1886
+ for (var name in props) {
1887
+ if (props[name] === null || props[name] === undefined) {
1888
+ target[name] = props[name];
1889
+ }
1890
+ }
1891
+ return target;
1892
+ };
1893
+
1894
+ /*
1895
+ * Determine by the time format which units are supported
1896
+ * Returns an object of booleans for each unit
1897
+ */
1898
+ var detectSupport = function (timeFormat) {
1899
+ var tf = timeFormat.replace(/'.*?'/g, '').toLowerCase(), // removes literals
1900
+ isIn = function (f, t) { // does the format contain the token?
1901
+ return f.indexOf(t) !== -1 ? true : false;
1902
+ };
1903
+ return {
1904
+ hour: isIn(tf, 'h'),
1905
+ minute: isIn(tf, 'm'),
1906
+ second: isIn(tf, 's'),
1907
+ millisec: isIn(tf, 'l'),
1908
+ microsec: isIn(tf, 'c'),
1909
+ timezone: isIn(tf, 'z'),
1910
+ ampm: isIn(tf, 't') && isIn(timeFormat, 'h'),
1911
+ iso8601: isIn(timeFormat, 'Z')
1912
+ };
1913
+ };
1914
+
1915
+ /*
1916
+ * Converts 24 hour format into 12 hour
1917
+ * Returns 12 hour without leading 0
1918
+ */
1919
+ var convert24to12 = function (hour) {
1920
+ hour %= 12;
1921
+
1922
+ if (hour === 0) {
1923
+ hour = 12;
1924
+ }
1925
+
1926
+ return String(hour);
1927
+ };
1928
+
1929
+ var computeEffectiveSetting = function (settings, property) {
1930
+ return settings && settings[property] ? settings[property] : $.timepicker._defaults[property];
1931
+ };
1932
+
1933
+ /*
1934
+ * Splits datetime string into date and time substrings.
1935
+ * Throws exception when date can't be parsed
1936
+ * Returns {dateString: dateString, timeString: timeString}
1937
+ */
1938
+ var splitDateTime = function (dateTimeString, timeSettings) {
1939
+ // The idea is to get the number separator occurrences in datetime and the time format requested (since time has
1940
+ // fewer unknowns, mostly numbers and am/pm). We will use the time pattern to split.
1941
+ var separator = computeEffectiveSetting(timeSettings, 'separator'),
1942
+ format = computeEffectiveSetting(timeSettings, 'timeFormat'),
1943
+ timeParts = format.split(separator), // how many occurrences of separator may be in our format?
1944
+ timePartsLen = timeParts.length,
1945
+ allParts = dateTimeString.split(separator),
1946
+ allPartsLen = allParts.length;
1947
+
1948
+ if (allPartsLen > 1) {
1949
+ return {
1950
+ dateString: allParts.splice(0, allPartsLen - timePartsLen).join(separator),
1951
+ timeString: allParts.splice(0, timePartsLen).join(separator)
1952
+ };
1953
+ }
1954
+
1955
+ return {
1956
+ dateString: dateTimeString,
1957
+ timeString: ''
1958
+ };
1959
+ };
1960
+
1961
+ /*
1962
+ * Internal function to parse datetime interval
1963
+ * Returns: {date: Date, timeObj: Object}, where
1964
+ * date - parsed date without time (type Date)
1965
+ * timeObj = {hour: , minute: , second: , millisec: , microsec: } - parsed time. Optional
1966
+ */
1967
+ var parseDateTimeInternal = function (dateFormat, timeFormat, dateTimeString, dateSettings, timeSettings) {
1968
+ var date,
1969
+ parts,
1970
+ parsedTime;
1971
+
1972
+ parts = splitDateTime(dateTimeString, timeSettings);
1973
+ date = $.datepicker._base_parseDate(dateFormat, parts.dateString, dateSettings);
1974
+
1975
+ if (parts.timeString === '') {
1976
+ return {
1977
+ date: date
1978
+ };
1979
+ }
1980
+
1981
+ parsedTime = $.datepicker.parseTime(timeFormat, parts.timeString, timeSettings);
1982
+
1983
+ if (!parsedTime) {
1984
+ throw 'Wrong time format';
1985
+ }
1986
+
1987
+ return {
1988
+ date: date,
1989
+ timeObj: parsedTime
1990
+ };
1991
+ };
1992
+
1993
+ /*
1994
+ * Internal function to set timezone_select to the local timezone
1995
+ */
1996
+ var selectLocalTimezone = function (tp_inst, date) {
1997
+ if (tp_inst && tp_inst.timezone_select) {
1998
+ var now = date || new Date();
1999
+ tp_inst.timezone_select.val(-now.getTimezoneOffset());
2000
+ }
2001
+ };
2002
+
2003
+ /*
2004
+ * Create a Singleton Instance
2005
+ */
2006
+ $.timepicker = new Timepicker();
2007
+
2008
+ /**
2009
+ * Get the timezone offset as string from a date object (eg '+0530' for UTC+5.5)
2010
+ * @param {number} tzMinutes if not a number, less than -720 (-1200), or greater than 840 (+1400) this value is returned
2011
+ * @param {boolean} iso8601 if true formats in accordance to iso8601 "+12:45"
2012
+ * @return {string}
2013
+ */
2014
+ $.timepicker.timezoneOffsetString = function (tzMinutes, iso8601) {
2015
+ if (isNaN(tzMinutes) || tzMinutes > 840 || tzMinutes < -720) {
2016
+ return tzMinutes;
2017
+ }
2018
+
2019
+ var off = tzMinutes,
2020
+ minutes = off % 60,
2021
+ hours = (off - minutes) / 60,
2022
+ iso = iso8601 ? ':' : '',
2023
+ tz = (off >= 0 ? '+' : '-') + ('0' + Math.abs(hours)).slice(-2) + iso + ('0' + Math.abs(minutes)).slice(-2);
2024
+
2025
+ if (tz === '+00:00') {
2026
+ return 'Z';
2027
+ }
2028
+ return tz;
2029
+ };
2030
+
2031
+ /**
2032
+ * Get the number in minutes that represents a timezone string
2033
+ * @param {string} tzString formatted like "+0500", "-1245", "Z"
2034
+ * @return {number} the offset minutes or the original string if it doesn't match expectations
2035
+ */
2036
+ $.timepicker.timezoneOffsetNumber = function (tzString) {
2037
+ var normalized = tzString.toString().replace(':', ''); // excuse any iso8601, end up with "+1245"
2038
+
2039
+ if (normalized.toUpperCase() === 'Z') { // if iso8601 with Z, its 0 minute offset
2040
+ return 0;
2041
+ }
2042
+
2043
+ if (!/^(\-|\+)\d{4}$/.test(normalized)) { // possibly a user defined tz, so just give it back
2044
+ return tzString;
2045
+ }
2046
+
2047
+ return ((normalized.substr(0, 1) === '-' ? -1 : 1) * // plus or minus
2048
+ ((parseInt(normalized.substr(1, 2), 10) * 60) + // hours (converted to minutes)
2049
+ parseInt(normalized.substr(3, 2), 10))); // minutes
2050
+ };
2051
+
2052
+ /**
2053
+ * No way to set timezone in js Date, so we must adjust the minutes to compensate. (think setDate, getDate)
2054
+ * @param {Date} date
2055
+ * @param {string} toTimezone formatted like "+0500", "-1245"
2056
+ * @return {Date}
2057
+ */
2058
+ $.timepicker.timezoneAdjust = function (date, toTimezone) {
2059
+ var toTz = $.timepicker.timezoneOffsetNumber(toTimezone);
2060
+ if (!isNaN(toTz)) {
2061
+ date.setMinutes(date.getMinutes() + -date.getTimezoneOffset() - toTz);
2062
+ }
2063
+ return date;
2064
+ };
2065
+
2066
+ /**
2067
+ * Calls `timepicker()` on the `startTime` and `endTime` elements, and configures them to
2068
+ * enforce date range limits.
2069
+ * n.b. The input value must be correctly formatted (reformatting is not supported)
2070
+ * @param {Element} startTime
2071
+ * @param {Element} endTime
2072
+ * @param {Object} options Options for the timepicker() call
2073
+ * @return {jQuery}
2074
+ */
2075
+ $.timepicker.timeRange = function (startTime, endTime, options) {
2076
+ return $.timepicker.handleRange('timepicker', startTime, endTime, options);
2077
+ };
2078
+
2079
+ /**
2080
+ * Calls `datetimepicker` on the `startTime` and `endTime` elements, and configures them to
2081
+ * enforce date range limits.
2082
+ * @param {Element} startTime
2083
+ * @param {Element} endTime
2084
+ * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,
2085
+ * a boolean value that can be used to reformat the input values to the `dateFormat`.
2086
+ * @param {string} method Can be used to specify the type of picker to be added
2087
+ * @return {jQuery}
2088
+ */
2089
+ $.timepicker.datetimeRange = function (startTime, endTime, options) {
2090
+ $.timepicker.handleRange('datetimepicker', startTime, endTime, options);
2091
+ };
2092
+
2093
+ /**
2094
+ * Calls `datepicker` on the `startTime` and `endTime` elements, and configures them to
2095
+ * enforce date range limits.
2096
+ * @param {Element} startTime
2097
+ * @param {Element} endTime
2098
+ * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,
2099
+ * a boolean value that can be used to reformat the input values to the `dateFormat`.
2100
+ * @return {jQuery}
2101
+ */
2102
+ $.timepicker.dateRange = function (startTime, endTime, options) {
2103
+ $.timepicker.handleRange('datepicker', startTime, endTime, options);
2104
+ };
2105
+
2106
+ /**
2107
+ * Calls `method` on the `startTime` and `endTime` elements, and configures them to
2108
+ * enforce date range limits.
2109
+ * @param {string} method Can be used to specify the type of picker to be added
2110
+ * @param {Element} startTime
2111
+ * @param {Element} endTime
2112
+ * @param {Object} options Options for the `timepicker()` call. Also supports `reformat`,
2113
+ * a boolean value that can be used to reformat the input values to the `dateFormat`.
2114
+ * @return {jQuery}
2115
+ */
2116
+ $.timepicker.handleRange = function (method, startTime, endTime, options) {
2117
+ options = $.extend({}, {
2118
+ minInterval: 0, // min allowed interval in milliseconds
2119
+ maxInterval: 0, // max allowed interval in milliseconds
2120
+ start: {}, // options for start picker
2121
+ end: {} // options for end picker
2122
+ }, options);
2123
+
2124
+ // for the mean time this fixes an issue with calling getDate with timepicker()
2125
+ var timeOnly = false;
2126
+ if(method === 'timepicker'){
2127
+ timeOnly = true;
2128
+ method = 'datetimepicker';
2129
+ }
2130
+
2131
+ function checkDates(changed, other) {
2132
+ var startdt = startTime[method]('getDate'),
2133
+ enddt = endTime[method]('getDate'),
2134
+ changeddt = changed[method]('getDate');
2135
+
2136
+ if (startdt !== null) {
2137
+ var minDate = new Date(startdt.getTime()),
2138
+ maxDate = new Date(startdt.getTime());
2139
+
2140
+ minDate.setMilliseconds(minDate.getMilliseconds() + options.minInterval);
2141
+ maxDate.setMilliseconds(maxDate.getMilliseconds() + options.maxInterval);
2142
+
2143
+ if (options.minInterval > 0 && minDate > enddt) { // minInterval check
2144
+ endTime[method]('setDate', minDate);
2145
+ }
2146
+ else if (options.maxInterval > 0 && maxDate < enddt) { // max interval check
2147
+ endTime[method]('setDate', maxDate);
2148
+ }
2149
+ else if (startdt > enddt) {
2150
+ other[method]('setDate', changeddt);
2151
+ }
2152
+ }
2153
+ }
2154
+
2155
+ function selected(changed, other, option) {
2156
+ if (!changed.val()) {
2157
+ return;
2158
+ }
2159
+ var date = changed[method].call(changed, 'getDate');
2160
+ if (date !== null && options.minInterval > 0) {
2161
+ if (option === 'minDate') {
2162
+ date.setMilliseconds(date.getMilliseconds() + options.minInterval);
2163
+ }
2164
+ if (option === 'maxDate') {
2165
+ date.setMilliseconds(date.getMilliseconds() - options.minInterval);
2166
+ }
2167
+ }
2168
+
2169
+ if (date.getTime) {
2170
+ other[method].call(other, 'option', option, date);
2171
+ }
2172
+ }
2173
+
2174
+ $.fn[method].call(startTime, $.extend({
2175
+ timeOnly: timeOnly,
2176
+ onClose: function (dateText, inst) {
2177
+ checkDates($(this), endTime);
2178
+ },
2179
+ onSelect: function (selectedDateTime) {
2180
+ selected($(this), endTime, 'minDate');
2181
+ }
2182
+ }, options, options.start));
2183
+ $.fn[method].call(endTime, $.extend({
2184
+ timeOnly: timeOnly,
2185
+ onClose: function (dateText, inst) {
2186
+ checkDates($(this), startTime);
2187
+ },
2188
+ onSelect: function (selectedDateTime) {
2189
+ selected($(this), startTime, 'maxDate');
2190
+ }
2191
+ }, options, options.end));
2192
+
2193
+ checkDates(startTime, endTime);
2194
+
2195
+ selected(startTime, endTime, 'minDate');
2196
+ selected(endTime, startTime, 'maxDate');
2197
+
2198
+ return $([startTime.get(0), endTime.get(0)]);
2199
+ };
2200
+
2201
+ /**
2202
+ * Log error or data to the console during error or debugging
2203
+ * @param {Object} err pass any type object to log to the console during error or debugging
2204
+ * @return {void}
2205
+ */
2206
+ $.timepicker.log = function () {
2207
+ if (window.console) {
2208
+ window.console.log.apply(window.console, Array.prototype.slice.call(arguments));
2209
+ }
2210
+ };
2211
+
2212
+ /*
2213
+ * Add util object to allow access to private methods for testability.
2214
+ */
2215
+ $.timepicker._util = {
2216
+ _extendRemove: extendRemove,
2217
+ _isEmptyObject: isEmptyObject,
2218
+ _convert24to12: convert24to12,
2219
+ _detectSupport: detectSupport,
2220
+ _selectLocalTimezone: selectLocalTimezone,
2221
+ _computeEffectiveSetting: computeEffectiveSetting,
2222
+ _splitDateTime: splitDateTime,
2223
+ _parseDateTimeInternal: parseDateTimeInternal
2224
+ };
2225
+
2226
+ /*
2227
+ * Microsecond support
2228
+ */
2229
+ if (!Date.prototype.getMicroseconds) {
2230
+ Date.prototype.microseconds = 0;
2231
+ Date.prototype.getMicroseconds = function () { return this.microseconds; };
2232
+ Date.prototype.setMicroseconds = function (m) {
2233
+ this.setMilliseconds(this.getMilliseconds() + Math.floor(m / 1000));
2234
+ this.microseconds = m % 1000;
2235
+ return this;
2236
+ };
2237
+ }
2238
+
2239
+ /*
2240
+ * Keep up with the version
2241
+ */
2242
+ $.timepicker.version = "1.5.2";
2243
+
2244
+ }));
js/page-options-content-tab.js CHANGED
@@ -7,7 +7,8 @@ jQuery(document).ready(function($) {
7
  var logo_uploader;
8
 
9
 
10
- $('#ezp-countdown-due-date').datepicker({ dateFormat: ezp_cs_datepicker_date_format} );
 
11
  $('#easy-pie-cs-logo-button').click(function(e) {
12
 
13
  e.preventDefault();
7
  var logo_uploader;
8
 
9
 
10
+ //$('#ezp-countdown-due-date').datepicker({ dateFormat: ezp_cs_datepicker_date_format } );
11
+ $('#ezp-countdown-due-date').datetimepicker({ dateFormat: ezp_cs_datepicker_date_format} );
12
  $('#easy-pie-cs-logo-button').click(function(e) {
13
 
14
  e.preventDefault();
pages/page-coming-soon-page-elite.php CHANGED
@@ -74,7 +74,8 @@
74
  <li>Preview from Admin panel</li>
75
  <li>Choose 503 or 200 HTTP status</li>
76
  <li>Selectively allow viewing certain URLs</li>
77
- <li class="elite">Give site access via special URLs. Allows cutting off one group while giving another access.</li>
 
78
  </ul>
79
  </td>
80
  </tr>
74
  <li>Preview from Admin panel</li>
75
  <li>Choose 503 or 200 HTTP status</li>
76
  <li>Selectively allow viewing certain URLs</li>
77
+ <li class="elite">Sends you an email when someone subscribes</li>
78
+ <li class="elite">Advanced Access System: Give individuals or groups independent site access.</li>
79
  </ul>
80
  </td>
81
  </tr>
pages/page-options-content-tab.php CHANGED
@@ -231,7 +231,7 @@ if ($error_string != "") :
231
  </th>
232
  <td>
233
  <div class="compound-setting">
234
- <input style="width:90px;" id="ezp-countdown-due-date" class="long-input" name="countdown_due_date" type="text" value="<?php EZP_CS_Utility::_he($content->countdown_due_date); ?>" />
235
  <div><span class="description"><?php EZP_CS_Utility::_e('Countdown timer will display when populated'); ?></span></div>
236
  </div>
237
  </td>
231
  </th>
232
  <td>
233
  <div class="compound-setting">
234
+ <input style="width:130px;" id="ezp-countdown-due-date" class="long-input" name="countdown_due_date" type="text" value="<?php EZP_CS_Utility::_he($content->countdown_due_date); ?>" />
235
  <div><span class="description"><?php EZP_CS_Utility::_e('Countdown timer will display when populated'); ?></span></div>
236
  </div>
237
  </td>
pages/page-options-settings.php CHANGED
@@ -186,7 +186,7 @@
186
  </tr>
187
  <tr>
188
  <td style="padding-left:0; padding-bottom:0;" colspan="2">
189
- <small>Get more social icons with <a href="http://easypiewp.com" target="_blank">Coming Soon Page Elite</a></small>
190
  </td>
191
  </tr>
192
  </table>
@@ -261,7 +261,7 @@
261
  </tr>
262
  <tr>
263
  <td style="padding-left:0; padding-bottom:0;" colspan="2">
264
- <small>Give site access by visitor or group with <a href="http://easypiewp.com" target="_blank">Coming Soon Page Elite</a></small>
265
  </td>
266
  </tr>
267
  </table>
186
  </tr>
187
  <tr>
188
  <td style="padding-left:0; padding-bottom:0;" colspan="2">
189
+ <small>Get more social icons with <a style="color:red" href="http://easypiewp.com" target="_blank">Coming Soon Page Elite</a></small>
190
  </td>
191
  </tr>
192
  </table>
261
  </tr>
262
  <tr>
263
  <td style="padding-left:0; padding-bottom:0;" colspan="2">
264
+ <small>Advanced Access Control available in <a style="color:red" href="http://easypiewp.com" target="_blank">Coming Soon Page Elite</a></small>
265
  </td>
266
  </tr>
267
  </table>
pages/page-subscribers-list-tab.php CHANGED
@@ -170,7 +170,7 @@ $config = EZP_CS_Config_Entity::get_by_id($global->config_index);
170
  return false;"><?php EZP_CS_Utility::_e("Next"); ?><span style='float:right; margin-top:1px' class="ui-icon ui-icon-triangle-1-e"></span></button>
171
 
172
  </div>
173
- <p style="text-align:center;"><small style="margin-top:17px; ">AutoSync to MailChimp with <a target="_blank" href="http://easypiewp.com">Coming Soon Page Elite</a></small>
174
  </p>
175
  </div>
176
  </div>
170
  return false;"><?php EZP_CS_Utility::_e("Next"); ?><span style='float:right; margin-top:1px' class="ui-icon ui-icon-triangle-1-e"></span></button>
171
 
172
  </div>
173
+ <p style="text-align:center;"><small style="margin-top:17px; ">Get an email when a subscriber signs up with <a style="color:red" target="_blank" href="http://easypiewp.com">Coming Soon Page Elite</a></small>
174
  </p>
175
  </div>
176
  </div>
pages/page-subscribers-newsletter-tab.php CHANGED
@@ -78,7 +78,7 @@ $config = EZP_CS_Config_Entity::get_by_id($global->config_index);
78
  </div>
79
  </div>
80
  <p style="margin-left:8px;margin-top:10px;font-style:italic; clear:both">
81
- *Some of the above are 'affiliate links'. These do not affect the price of paid options.
82
  </p>
83
  </div>
84
  </div>
78
  </div>
79
  </div>
80
  <p style="margin-left:8px;margin-top:10px;font-style:italic; clear:both">
81
+ <small style="margin-top:17px; ">AutoSync your subscribers to MailChimp with <a style="color:red" target="_blank" href="http://easypiewp.com">Coming Soon Page Elite</a></small>
82
  </p>
83
  </div>
84
  </div>
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://easypiewp.com/donate/
4
  Tags: coming soon, coming soon page, construction, landing page, launch, launch page, maintenance, maintenance mode, offline, unavailable, under construction, underconstruction, wordpress coming soon, wordpress maintenance mode, wordpress under construction
5
  Requires at least: 3.5
6
  Tested up to: 4.1.1
7
- Stable tag: 0.6.4
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
@@ -36,6 +36,16 @@ Let your visitors know your site is Coming Soon while gathering their contact in
36
  ### Advanced Features
37
  * Export email addresses gathered by Coming Soon Page to CSV for compatibility with **MailChimp**, **AWeber** and other major email providers.
38
 
 
 
 
 
 
 
 
 
 
 
39
  ### Overview
40
  Coming Soon Page is a great way to let visitors know your site is Coming Soon. When Coming Soon Page is displayed it collects valuable emails from potential customers in a friendly and professional way. Coming Soon Page is also theme independent, having been confirmed to work well with top WordPress themes.
41
 
@@ -79,6 +89,10 @@ For the FAQ on the Coming Soon Page please visit the [Easy Pie Website](http://e
79
 
80
  == Changelog ==
81
 
 
 
 
 
82
  = 0.6.4 =
83
  * Small UI tweaks
84
 
@@ -123,29 +137,33 @@ For the FAQ on the Coming Soon Page please visit the [Easy Pie Website](http://e
123
 
124
  == Upgrade Notice ==
125
 
 
 
 
 
126
  = 0.6.4 =
127
- Small UI tweaks
128
 
129
  = 0.6.3 =
130
- Fixed bug involving name being a required field (Thanks tomtc)
131
 
132
  = 0.6.2 =
133
- Fixed typo introduced in 0.6.1 causing fatal error on subscriber list screen. (Thanks Paris Le-Tayo for reporting!)
134
 
135
  = 0.6.1 =
136
- Fixed small formatting problem
137
 
138
  = 0.6.0 =
139
- Small tweaks
140
 
141
  = 0.5.8 =
142
- Small tweaks, upped WordPress compatibility to 3.9.2
143
 
144
  = 0.5.6 =
145
- Includes minor bug fixes and usability improvements. Note that Coming Soon Page preview has been moved to the third template tab.
146
 
147
  = 0.5.4 =
148
- Added countdown timer. Also added ability to disable Coming Soon Page for specific site URLs. Additionally, made a few minor tweaks.
149
 
150
  = 0.5.2 =
151
  * Now you can change the title of your coming soon page. Also includes several usability improvements.
4
  Tags: coming soon, coming soon page, construction, landing page, launch, launch page, maintenance, maintenance mode, offline, unavailable, under construction, underconstruction, wordpress coming soon, wordpress maintenance mode, wordpress under construction
5
  Requires at least: 3.5
6
  Tested up to: 4.1.1
7
+ Stable tag: 1.0.0
8
  License: GPLv3
9
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
 
36
  ### Advanced Features
37
  * Export email addresses gathered by Coming Soon Page to CSV for compatibility with **MailChimp**, **AWeber** and other major email providers.
38
 
39
+ ### Need More? Go Elite!
40
+ Take things to the next level with [Coming Soon Page Elite](https://easypiewp.com) where you get everything and the following great features:
41
+
42
+ * Auto-sync your subscriber list to MailChimp. No need to export and import!
43
+ * Grant site access by person or group with Advanced Access Control.
44
+ * Extra social icons, including Instagram, LinkedIn, YouTube and more.
45
+ * Receive emails when subscribers sign up.
46
+ * Bonus backgrounds!
47
+ * More features being added all the time!
48
+
49
  ### Overview
50
  Coming Soon Page is a great way to let visitors know your site is Coming Soon. When Coming Soon Page is displayed it collects valuable emails from potential customers in a friendly and professional way. Coming Soon Page is also theme independent, having been confirmed to work well with top WordPress themes.
51
 
89
 
90
  == Changelog ==
91
 
92
+ = 1.0.0 =
93
+ * Countdown timer now supports time in addition to date
94
+ * UI tweaks
95
+
96
  = 0.6.4 =
97
  * Small UI tweaks
98
 
137
 
138
  == Upgrade Notice ==
139
 
140
+ = 1.0.0 =
141
+ * Countdown timer now supports time in addition to date
142
+ * UI tweaks
143
+
144
  = 0.6.4 =
145
+ * Small UI tweaks
146
 
147
  = 0.6.3 =
148
+ * Fixed bug involving name being a required field (Thanks tomtc)
149
 
150
  = 0.6.2 =
151
+ * Fixed typo introduced in 0.6.1 causing fatal error on subscriber list screen. (Thanks Paris Le-Tayo for reporting!)
152
 
153
  = 0.6.1 =
154
+ * Fixed small formatting problem
155
 
156
  = 0.6.0 =
157
+ * Small tweaks
158
 
159
  = 0.5.8 =
160
+ * Small tweaks, upped WordPress compatibility to 3.9.2
161
 
162
  = 0.5.6 =
163
+ * Includes minor bug fixes and usability improvements. Note that Coming Soon Page preview has been moved to the third template tab.
164
 
165
  = 0.5.4 =
166
+ * Added countdown timer. Also added ability to disable Coming Soon Page for specific site URLs. Additionally, made a few minor tweaks.
167
 
168
  = 0.5.2 =
169
  * Now you can change the title of your coming soon page. Also includes several usability improvements.