app_frame 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +26 -0
- data/Gemfile.lock +181 -0
- data/LICENSE.txt +20 -0
- data/README.md +25 -0
- data/Rakefile +47 -0
- data/VERSION +1 -0
- data/app/assets/javascripts/app_frame/application.js +9 -0
- data/app/assets/stylesheets/app_frame/_devise.scss +41 -0
- data/app/assets/stylesheets/app_frame/_tree.scss +31 -0
- data/app/assets/stylesheets/app_frame/application.scss +73 -0
- data/app/controllers/app_frame/devise/confirmations_controller.rb +3 -0
- data/app/controllers/app_frame/devise/passwords_controller.rb +3 -0
- data/app/controllers/app_frame/devise/registrations_controller.rb +3 -0
- data/app/controllers/app_frame/devise/sessions_controller.rb +3 -0
- data/app/helpers/app_frame/bootstrap_helper.rb +36 -0
- data/app/helpers/app_frame/breadcrumb_helper.rb +18 -0
- data/app/helpers/app_frame/menu_helper.rb +43 -0
- data/app/helpers/app_frame/pagination_helper.rb +12 -0
- data/app/helpers/app_frame/resources_helper.rb +63 -0
- data/app/helpers/app_frame/scopes_helper.rb +94 -0
- data/app/helpers/app_frame/select_helper.rb +8 -0
- data/app/helpers/app_frame/tree_nav_helper.rb +18 -0
- data/app/models/menu.rb +44 -0
- data/app/models/settings.rb +4 -0
- data/app/views/app_frame/devise/confirmations/new.html.haml +8 -0
- data/app/views/app_frame/devise/passwords/edit.html.haml +13 -0
- data/app/views/app_frame/devise/passwords/new.html.haml +8 -0
- data/app/views/app_frame/devise/registrations/edit.html.haml +19 -0
- data/app/views/app_frame/devise/registrations/new.html.haml +10 -0
- data/app/views/app_frame/devise/sessions/new.html.haml +12 -0
- data/app/views/app_frame/devise/shared/_links.html.haml +14 -0
- data/app/views/app_frame/devise/unlocks/new.html.haml +9 -0
- data/app/views/application/_brand.html.haml +1 -0
- data/app/views/application/_breadcrumb.html.haml +12 -0
- data/app/views/application/_flashes.html.haml +2 -0
- data/app/views/application/_form.html.haml +2 -0
- data/app/views/application/_head.html.haml +6 -0
- data/app/views/application/_secondary_menu.html.haml +3 -0
- data/app/views/application/_show.html.haml +5 -0
- data/app/views/application/_sidebar.html.haml +12 -0
- data/app/views/application/_sub_menu.html.haml +0 -0
- data/app/views/application/_table.html.haml +3 -0
- data/app/views/application/_toolbar.html.haml +7 -0
- data/app/views/application/_top_menu.html.haml +1 -0
- data/app/views/application/edit.html.haml +8 -0
- data/app/views/application/index.html.haml +8 -0
- data/app/views/application/new.html.haml +7 -0
- data/app/views/application/show.html.haml +10 -0
- data/app/views/kaminari/app_frame/_first_page.html.haml +9 -0
- data/app/views/kaminari/app_frame/_gap.html.haml +8 -0
- data/app/views/kaminari/app_frame/_last_page.html.haml +9 -0
- data/app/views/kaminari/app_frame/_next_page.html.haml +9 -0
- data/app/views/kaminari/app_frame/_page.html.haml +10 -0
- data/app/views/kaminari/app_frame/_paginator.html.haml +19 -0
- data/app/views/kaminari/app_frame/_prev_page.html.haml +9 -0
- data/app/views/layouts/app_frame/default.html.haml +33 -0
- data/app/views/layouts/app_frame/devise.html.haml +17 -0
- data/app_frame.gemspec +162 -0
- data/lib/app_frame.rb +27 -0
- data/lib/app_frame/controller_methods.rb +111 -0
- data/lib/app_frame/view_methods.rb +19 -0
- data/lib/assets/images/.gitkeep +0 -0
- data/lib/assets/javascripts/anytime.js +3716 -0
- data/lib/assets/stylesheets/anytime.css +777 -0
- data/lib/engine.rb +197 -0
- data/spec/app_frame_spec.rb +7 -0
- data/spec/spec_helper.rb +12 -0
- metadata +423 -0
@@ -0,0 +1,111 @@
|
|
1
|
+
module AppFrame
|
2
|
+
|
3
|
+
module ControllerMethods
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def controller
|
7
|
+
self
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def app_frame(options = {})
|
12
|
+
layout "#{AppFrame::theme}/#{options[:layout] || 'default'}"
|
13
|
+
unless options[:resource] == false
|
14
|
+
inherit_resources
|
15
|
+
include AppFrame::ResourcesHelper
|
16
|
+
include PaginationSupport
|
17
|
+
include HasManySupport
|
18
|
+
include SearchSupport
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module SearchSupport
|
24
|
+
extend ActiveSupport::Concern
|
25
|
+
|
26
|
+
included do
|
27
|
+
helper_method :searchable?
|
28
|
+
end
|
29
|
+
|
30
|
+
def searchable?
|
31
|
+
resource_class.respond_to?(:search)
|
32
|
+
end
|
33
|
+
|
34
|
+
def list_scope
|
35
|
+
@list_scope ||= (controller_namespaces.map(&:to_s).join("_") + "_list").to_sym
|
36
|
+
end
|
37
|
+
|
38
|
+
def end_of_association_chain
|
39
|
+
chain = super
|
40
|
+
|
41
|
+
return chain if chain.is_a?(ActiveRecord::Base)
|
42
|
+
|
43
|
+
chain = chain.search(params[:q]) if params[:q].present? && searchable?
|
44
|
+
|
45
|
+
chain = chain.admin_list if resource_class.respond_to?(list_scope)
|
46
|
+
|
47
|
+
chain
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
module HasManySupport
|
52
|
+
extend ActiveSupport::Concern
|
53
|
+
|
54
|
+
included do
|
55
|
+
helper_method :child_resources
|
56
|
+
end
|
57
|
+
|
58
|
+
module ClassMethods
|
59
|
+
def child_resources
|
60
|
+
@child_resources ||= []
|
61
|
+
end
|
62
|
+
|
63
|
+
def has_many(symbol, options = {})
|
64
|
+
config = {
|
65
|
+
:symbol => symbol,
|
66
|
+
:name => symbol.to_s.humanize,
|
67
|
+
:resource_class => symbol.to_s.classify.constantize,
|
68
|
+
:resource_name => symbol.to_s.classify
|
69
|
+
}.merge(options)
|
70
|
+
|
71
|
+
self.child_resources << config
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def child_resources
|
76
|
+
self.class.child_resources
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
module PaginationSupport
|
81
|
+
extend ActiveSupport::Concern
|
82
|
+
|
83
|
+
included do
|
84
|
+
helper_method :count, :page, :per_page
|
85
|
+
end
|
86
|
+
|
87
|
+
# paginate collection
|
88
|
+
def collection
|
89
|
+
get_collection_ivar || set_collection_ivar(end_of_association_chain ? end_of_association_chain.page(page).per(per_page) : nil)
|
90
|
+
end
|
91
|
+
|
92
|
+
def page
|
93
|
+
(params[:page] || 1).to_i
|
94
|
+
end
|
95
|
+
|
96
|
+
def per_page
|
97
|
+
20
|
98
|
+
end
|
99
|
+
|
100
|
+
def count
|
101
|
+
@count ||= if end_of_association_chain
|
102
|
+
end_of_association_chain.count
|
103
|
+
else
|
104
|
+
0
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module AppFrame
|
2
|
+
module ViewMethods
|
3
|
+
def self.included(klass)
|
4
|
+
klass.extend(ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
def editable_attributes_for(klass)
|
8
|
+
klass.column_names - ['id', 'created_at', 'updated_at', 'type']
|
9
|
+
end
|
10
|
+
|
11
|
+
def attributes_for(klass)
|
12
|
+
klass.column_names
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
File without changes
|
@@ -0,0 +1,3716 @@
|
|
1
|
+
/*****************************************************************************
|
2
|
+
* FILE: anytime.js - The Any+Time(TM) JavaScript Library (source)
|
3
|
+
*
|
4
|
+
* VERSION: 4.1112K
|
5
|
+
*
|
6
|
+
* Copyright 2008-2011 Andrew M. Andrews III (www.AMA3.com). Some Rights
|
7
|
+
* Reserved. This work licensed under the Creative Commons Attribution-
|
8
|
+
* Noncommercial-Share Alike 3.0 Unported License except in jurisdicitons
|
9
|
+
* for which the license has been ported by Creative Commons International,
|
10
|
+
* where the work is licensed under the applicable ported license instead.
|
11
|
+
* For a copy of the unported license, visit
|
12
|
+
* http://creativecommons.org/licenses/by-nc-sa/3.0/
|
13
|
+
* or send a letter to Creative Commons, 171 Second Street, Suite 300,
|
14
|
+
* San Francisco, California, 94105, USA. For ported versions of the
|
15
|
+
* license, visit http://creativecommons.org/international/
|
16
|
+
*
|
17
|
+
* Alternative licensing arrangements may be made by contacting the
|
18
|
+
* author at http://www.AMA3.com/contact/
|
19
|
+
*
|
20
|
+
* The Any+Time(TM) JavaScript Library provides the following ECMAScript
|
21
|
+
* functionality:
|
22
|
+
*
|
23
|
+
* AnyTime.Converter
|
24
|
+
* Converts Dates to/from Strings, allowing a wide range of formats
|
25
|
+
* closely matching those provided by the MySQL DATE_FORMAT() function,
|
26
|
+
* with some noteworthy enhancements.
|
27
|
+
*
|
28
|
+
* AnyTime.pad()
|
29
|
+
* Pads a value with a specific number of leading zeroes.
|
30
|
+
*
|
31
|
+
* AnyTime.noPicker()
|
32
|
+
* Destroys a calendar widget previously added by AnyTime.picker().
|
33
|
+
* Can also be invoked via jQuery using $(selector).AnyTime_noPicker()
|
34
|
+
*
|
35
|
+
* AnyTime.picker()
|
36
|
+
* Attaches a calendar widget to a text field for selecting date/time
|
37
|
+
* values with fewer mouse movements than most similar pickers. Any
|
38
|
+
* format supported by AnyTime.Converter can be used for the text field.
|
39
|
+
* If JavaScript is disabled, the text field remains editable without
|
40
|
+
* any of the picker features.
|
41
|
+
* Can also be invoked via jQuery using $(selector).AnyTime_picker()
|
42
|
+
*
|
43
|
+
* IMPORTANT NOTICE: This code depends upon the jQuery JavaScript Library
|
44
|
+
* (www.jquery.com), currently version 1.4.
|
45
|
+
*
|
46
|
+
* The Any+Time(TM) code and styles in anytime.css have been tested (but not
|
47
|
+
* extensively) on Windows Vista in Internet Explorer 8.0, Firefox 3.0, Opera
|
48
|
+
* 10.10 and Safari 4.0. Minor variations in IE6+7 are to be expected, due
|
49
|
+
* to their broken box model. Please report any other problems to the author
|
50
|
+
* (URL above).
|
51
|
+
*
|
52
|
+
* Any+Time is a trademark of Andrew M. Andrews III.
|
53
|
+
* Thanks to Chu for help with a setMonth() issue!
|
54
|
+
****************************************************************************/
|
55
|
+
|
56
|
+
var AnyTime =
|
57
|
+
{
|
58
|
+
//=============================================================================
|
59
|
+
// AnyTime.pad() pads a value with a specified number of zeroes and returns
|
60
|
+
// a string containing the padded value.
|
61
|
+
//=============================================================================
|
62
|
+
|
63
|
+
pad: function( val, len )
|
64
|
+
{
|
65
|
+
var str = String(Math.abs(val));
|
66
|
+
while ( str.length < len )
|
67
|
+
str = '0'+str;
|
68
|
+
if ( val < 0 )
|
69
|
+
str = '-'+str;
|
70
|
+
return str;
|
71
|
+
}
|
72
|
+
};
|
73
|
+
|
74
|
+
(function($)
|
75
|
+
{
|
76
|
+
// private members
|
77
|
+
|
78
|
+
var __oneDay = (24*60*60*1000);
|
79
|
+
var __daysIn = [ 31,28,31,30,31,30,31,31,30,31,30,31 ];
|
80
|
+
var __iframe = null;
|
81
|
+
var __initialized = false;
|
82
|
+
var __msie6 = ( navigator.userAgent.indexOf('MSIE 6') > 0 );
|
83
|
+
var __msie7 = ( navigator.userAgent.indexOf('MSIE 7') > 0 );
|
84
|
+
var __pickers = [];
|
85
|
+
|
86
|
+
// Add methods to jQuery to create and destroy pickers using
|
87
|
+
// the typical jQuery approach.
|
88
|
+
|
89
|
+
jQuery.prototype.AnyTime_picker = function( options )
|
90
|
+
{
|
91
|
+
return this.each( function(i) { AnyTime.picker( this.id, options ); } );
|
92
|
+
}
|
93
|
+
|
94
|
+
jQuery.prototype.AnyTime_noPicker = function()
|
95
|
+
{
|
96
|
+
return this.each( function(i) { AnyTime.noPicker( this.id ); } );
|
97
|
+
}
|
98
|
+
|
99
|
+
// Add methods to jQuery to change the earliest and latest times using
|
100
|
+
// the typical jQuery approach.
|
101
|
+
|
102
|
+
jQuery.prototype.AnyTime_setEarliest = function( options )
|
103
|
+
{
|
104
|
+
return this.each( function(i) { AnyTime.setEarliest( this.id, options ); } );
|
105
|
+
}
|
106
|
+
|
107
|
+
jQuery.prototype.AnyTime_setLatest = function( options )
|
108
|
+
{
|
109
|
+
return this.each( function(i) { AnyTime.setLatest( this.id, options ); } );
|
110
|
+
}
|
111
|
+
|
112
|
+
// Add special methods to jQuery to compute the height and width
|
113
|
+
// of picker components differently for Internet Explorer 6.x
|
114
|
+
// This prevents the pickers from being too tall and wide.
|
115
|
+
|
116
|
+
jQuery.prototype.AnyTime_height = function(inclusive)
|
117
|
+
{
|
118
|
+
return ( __msie6 ?
|
119
|
+
Number(this.css('height').replace(/[^0-9]/g,'')) :
|
120
|
+
this.outerHeight(inclusive) );
|
121
|
+
};
|
122
|
+
|
123
|
+
jQuery.prototype.AnyTime_width = function(inclusive)
|
124
|
+
{
|
125
|
+
return ( __msie6 ?
|
126
|
+
(1+Number(this.css('width').replace(/[^0-9]/g,''))) :
|
127
|
+
this.outerWidth(inclusive) );
|
128
|
+
};
|
129
|
+
|
130
|
+
|
131
|
+
// Add a method to jQuery to change the classes of an element to
|
132
|
+
// indicate whether it's value is current (used by AnyTime.picker),
|
133
|
+
// and another to trigger the click handler for the currently-
|
134
|
+
// selected button under an element.
|
135
|
+
|
136
|
+
jQuery.prototype.AnyTime_current = function(isCurrent,isLegal)
|
137
|
+
{
|
138
|
+
if ( isCurrent )
|
139
|
+
{
|
140
|
+
this.removeClass('AnyTime-out-btn ui-state-default ui-state-disabled ui-state-highlight');
|
141
|
+
this.addClass('AnyTime-cur-btn ui-state-default ui-state-highlight');
|
142
|
+
}
|
143
|
+
else
|
144
|
+
{
|
145
|
+
this.removeClass('AnyTime-cur-btn ui-state-highlight');
|
146
|
+
if ( ! isLegal )
|
147
|
+
this.addClass('AnyTime-out-btn ui-state-disabled');
|
148
|
+
else
|
149
|
+
this.removeClass('AnyTime-out-btn ui-state-disabled');
|
150
|
+
}
|
151
|
+
};
|
152
|
+
|
153
|
+
jQuery.prototype.AnyTime_clickCurrent = function()
|
154
|
+
{
|
155
|
+
this.find('.AnyTime-cur-btn').triggerHandler('click');
|
156
|
+
}
|
157
|
+
|
158
|
+
$(document).ready(
|
159
|
+
function()
|
160
|
+
{
|
161
|
+
// IE6 doesn't float popups over <select> elements unless an
|
162
|
+
// <iframe> is inserted between them! The <iframe> is added to
|
163
|
+
// the page *before* the popups are moved, so they will appear
|
164
|
+
// after the <iframe>.
|
165
|
+
|
166
|
+
if ( __msie6 )
|
167
|
+
{
|
168
|
+
__iframe = $('<iframe frameborder="0" scrolling="no"></iframe>');
|
169
|
+
__iframe.src = "javascript:'<html></html>';";
|
170
|
+
$(__iframe).css( {
|
171
|
+
display: 'block',
|
172
|
+
height: '1px',
|
173
|
+
left: '0',
|
174
|
+
top: '0',
|
175
|
+
width: '1px',
|
176
|
+
zIndex: 0
|
177
|
+
} );
|
178
|
+
$(document.body).append(__iframe);
|
179
|
+
}
|
180
|
+
|
181
|
+
// Move popup windows to the end of the page. This allows them to
|
182
|
+
// overcome XHTML restrictions on <table> placement enforced by MSIE.
|
183
|
+
|
184
|
+
for ( var id in __pickers )
|
185
|
+
if ( ! Array.prototype[id] ) // prototype.js compatibility issue
|
186
|
+
__pickers[id].onReady();
|
187
|
+
|
188
|
+
__initialized = true;
|
189
|
+
|
190
|
+
} ); // document.ready
|
191
|
+
|
192
|
+
//=============================================================================
|
193
|
+
// AnyTime.Converter
|
194
|
+
//
|
195
|
+
// This object converts between Date objects and Strings.
|
196
|
+
//
|
197
|
+
// To use AnyTime.Converter, simply create an instance for a format string,
|
198
|
+
// and then (repeatedly) invoke the format() and/or parse() methods to
|
199
|
+
// perform the conversions. For example:
|
200
|
+
//
|
201
|
+
// var converter = new AnyTime.Converter({format:'%Y-%m-%d'})
|
202
|
+
// var datetime = converter.parse('1967-07-30') // July 30, 1967 @ 00:00
|
203
|
+
// alert( converter.format(datetime) ); // outputs: 1967-07-30
|
204
|
+
//
|
205
|
+
// Constructor parameter:
|
206
|
+
//
|
207
|
+
// options - an object of optional parameters that override default behaviors.
|
208
|
+
// The supported options are:
|
209
|
+
//
|
210
|
+
// baseYear - the number to add to two-digit years if the %y format
|
211
|
+
// specifier is used. By default, AnyTime.Converter follows the
|
212
|
+
// MySQL assumption that two-digit years are in the range 1970 to 2069
|
213
|
+
// (see http://dev.mysql.com/doc/refman/5.1/en/y2k-issues.html).
|
214
|
+
// The most common alternatives for baseYear are 1900 and 2000.
|
215
|
+
//
|
216
|
+
// dayAbbreviations - an array of seven strings, indexed 0-6, to be used
|
217
|
+
// as ABBREVIATED day names. If not specified, the following are used:
|
218
|
+
// ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
|
219
|
+
// Note that if the firstDOW option is passed to AnyTime.picker() (see
|
220
|
+
// AnyTime.picker()), this array should nonetheless begin with the
|
221
|
+
// desired abbreviation for Sunday.
|
222
|
+
//
|
223
|
+
// dayNames - an array of seven strings, indexed 0-6, to be used as
|
224
|
+
// day names. If not specified, the following are used: ['Sunday',
|
225
|
+
// 'Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']
|
226
|
+
// Note that if the firstDOW option is passed to AnyTime.picker() (see
|
227
|
+
// AnyTime.picker()), this array should nonetheless begin with the
|
228
|
+
// desired name for Sunday.
|
229
|
+
//
|
230
|
+
// eraAbbreviations - an array of two strings, indexed 0-1, to be used
|
231
|
+
// as ABBREVIATED era names. Item #0 is the abbreviation for "Before
|
232
|
+
// Common Era" (years before 0001, sometimes represented as negative
|
233
|
+
// years or "B.C"), while item #1 is the abbreviation for "Common Era"
|
234
|
+
// (years from 0001 to present, usually represented as unsigned years
|
235
|
+
// or years "A.D."). If not specified, the following are used:
|
236
|
+
// ['BCE','CE']
|
237
|
+
//
|
238
|
+
// format - a string specifying the pattern of strings involved in the
|
239
|
+
// conversion. The parse() method can take a string in this format and
|
240
|
+
// convert it to a Date, and the format() method can take a Date object
|
241
|
+
// and convert it to a string matching the format.
|
242
|
+
//
|
243
|
+
// Fields in the format string must match those for the DATE_FORMAT()
|
244
|
+
// function in MySQL, as defined here:
|
245
|
+
// http://tinyurl.com/bwd45#function_date-format
|
246
|
+
//
|
247
|
+
// IMPORTANT: Some MySQL specifiers are not supported (especially
|
248
|
+
// those involving day-of-the-year, week-of-the-year) or approximated.
|
249
|
+
// See the code for exact behavior.
|
250
|
+
//
|
251
|
+
// In addition to the MySQL format specifiers, the following custom
|
252
|
+
// specifiers are also supported:
|
253
|
+
//
|
254
|
+
// %B - If the year is before 0001, then the "Before Common Era"
|
255
|
+
// abbreviation (usually BCE or the obsolete BC) will go here.
|
256
|
+
//
|
257
|
+
// %C - If the year is 0001 or later, then the "Common Era"
|
258
|
+
// abbreviation (usually CE or the obsolete AD) will go here.
|
259
|
+
//
|
260
|
+
// %E - If the year is before 0001, then the "Before Common Era"
|
261
|
+
// abbreviation (usually BCE or the obsolete BC) will go here.
|
262
|
+
// Otherwise, the "Common Era" abbreviation (usually CE or the
|
263
|
+
// obsolete AD) will go here.
|
264
|
+
//
|
265
|
+
// %Z - The current four-digit year, without any sign. This is
|
266
|
+
// commonly used with years that might be before (or after) 0001,
|
267
|
+
// when the %E (or %B and %C) specifier is used instead of a sign.
|
268
|
+
// For example, 45 BCE is represented "0045". By comparison, in
|
269
|
+
// the "%Y" format, 45 BCE is represented "-0045".
|
270
|
+
//
|
271
|
+
// %z - The current year, without any sign, using only the necessary
|
272
|
+
// number of digits. This if the year is commonly used with years
|
273
|
+
// that might be before (or after) 0001, when the %E (or %B and %C)
|
274
|
+
// specifier is used instead of a sign. For example, the year
|
275
|
+
// 45 BCE is represented as "45", and the year 312 CE as "312".
|
276
|
+
//
|
277
|
+
// %# - the timezone offset, with a sign, in minutes.
|
278
|
+
//
|
279
|
+
// %+ - the timezone offset, with a sign, in hours and minutes, in
|
280
|
+
// four-digit, 24-hour format with no delimiter (for example, +0530).
|
281
|
+
// To remember the difference between %+ and %-, it might be helpful
|
282
|
+
// to remember that %+ might have more characters than %-.
|
283
|
+
//
|
284
|
+
// %: - the timezone offset, with a sign, in hours and minutes, in
|
285
|
+
// four-digit, 24-hour format with a colon delimiter (for example,
|
286
|
+
// +05:30). This is similar to the %z format used by Java.
|
287
|
+
// To remember the difference between %: and %;, it might be helpful
|
288
|
+
// to remember that a colon (:) has a period (.) on the bottom and
|
289
|
+
// a semicolon (;) has a comma (,), and in English sentence structure,
|
290
|
+
// a period represents a more significant stop than a comma, and
|
291
|
+
// %: might be a longer string than %; (I know it's a stretch, but
|
292
|
+
// it's easier than looking it up every time)!
|
293
|
+
//
|
294
|
+
// %- - the timezone offset, with a sign, in hours and minutes, in
|
295
|
+
// three-or-four-digit, 24-hour format with no delimiter (for
|
296
|
+
// example, +530).
|
297
|
+
//
|
298
|
+
// %; - the timezone offset, with a sign, in hours and minutes, in
|
299
|
+
// three-or-four-digit, 24-hour format with a colon delimiter
|
300
|
+
// (for example, +5:30).
|
301
|
+
//
|
302
|
+
// %@ - the timezone offset label. By default, this will be the
|
303
|
+
// string "UTC" followed by the offset, with a sign, in hours and
|
304
|
+
// minutes, in four-digit, 24-hour format with a colon delimiter
|
305
|
+
// (for example, UTC+05:30). However, if Any+Time(TM) has been
|
306
|
+
// extended with a member named utcLabel (for example, by the
|
307
|
+
// anytimetz.js file), then it is assumed to be an array of arrays,
|
308
|
+
// where the primary array is indexed by time zone offsets, and
|
309
|
+
// each sub-array contains a potential label for that offset.
|
310
|
+
// When parsing with %@, the array is scanned for matches to the
|
311
|
+
// input string, and if a match is found, the corresponding UTC
|
312
|
+
// offset is used. When formatting, the array is scanned for a
|
313
|
+
// matching offset, and if one is found, the first member of the
|
314
|
+
// sub-array is used for output (unless overridden with
|
315
|
+
// utcFormatOffsetSubIndex or setUtcFormatOffsetSubIndex()).
|
316
|
+
// If the array does not exist, or does not contain a sub-array
|
317
|
+
// for the offset, then the default format is used.
|
318
|
+
//
|
319
|
+
// monthAbbreviations - an array of twelve strings, indexed 0-6, to be
|
320
|
+
// used as ABBREVIATED month names. If not specified, the following
|
321
|
+
// are used: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep',
|
322
|
+
// 'Oct','Nov','Dec']
|
323
|
+
//
|
324
|
+
// monthNames - an array of twelve strings, indexed 0-6, to be used as
|
325
|
+
// month names. If not specified, the following are used:
|
326
|
+
// ['January','February','March','April','May','June','July',
|
327
|
+
// 'August','September','October','November','December']
|
328
|
+
//
|
329
|
+
// utcFormatOffsetAlleged - the offset from UTC, in minutes, to claim that
|
330
|
+
// a Date object represents during formatting, even though it is formatted
|
331
|
+
// using local time. Unlike utcFormatOffsetImposed, which actually
|
332
|
+
// converts the Date object to the specified different time zone, this
|
333
|
+
// option merely reports the alleged offset when a timezone specifier
|
334
|
+
// (%#, %+, %-, %:, %; %@) is encountered in the format string.
|
335
|
+
// This primarily exists so AnyTime.picker can edit the time as specified
|
336
|
+
// (without conversion to local time) and then convert the edited time to
|
337
|
+
// a different time zone (as selected using the picker). Any initial
|
338
|
+
// value specified here can be changed by setUtcFormatOffsetAlleged().
|
339
|
+
// If a format offset is alleged, one cannot also be imposed (the imposed
|
340
|
+
// offset is ignored).
|
341
|
+
//
|
342
|
+
// utcFormatOffsetImposed - the offset from UTC, in minutes, to specify when
|
343
|
+
// formatting a Date object. By default, a Date is always formatted
|
344
|
+
// using the local time zone.
|
345
|
+
//
|
346
|
+
// utcFormatOffsetSubIndex - when extending AnyTime with a utcLabel array
|
347
|
+
// (for example, by the anytimetz.js file), the specified sub-index is
|
348
|
+
// used to choose the Time Zone label for the UTC offset when formatting
|
349
|
+
// a Date object. This primarily exists so AnyTime.picker can specify
|
350
|
+
// the label selected using the picker. Any initial value specified here
|
351
|
+
// can be changed by setUtcFormatOffsetSubIndex().
|
352
|
+
//
|
353
|
+
// utcParseOffsetAssumed - the offset from UTC, in minutes, to assume when
|
354
|
+
// parsing a String object. By default, a Date is always parsed using the
|
355
|
+
// local time zone, unless the format string includes a timezone
|
356
|
+
// specifier (%#, %+, %-, %:, %; or %@), in which case the timezone
|
357
|
+
// specified in the string is used. The Date object created by parsing
|
358
|
+
// always represents local time regardless of the input time zone.
|
359
|
+
//
|
360
|
+
// utcParseOffsetCapture - if true, any parsed string is always treated as
|
361
|
+
// though it represents local time, and any offset specified by the string
|
362
|
+
// (or utcParseOffsetAssume) is captured for return by the
|
363
|
+
// getUtcParseOffsetCaptured() method. If the %@ format specifier is
|
364
|
+
// used, the sub-index of any matched label is also captured for return
|
365
|
+
// by the getUtcParseOffsetSubIndex() method. This primarily exists so
|
366
|
+
// AnyTime.picker can edit the time as specified (without conversion to
|
367
|
+
// local time) and then convert the edited time to a different time zone
|
368
|
+
// (as selected using the picker).
|
369
|
+
//=============================================================================
|
370
|
+
|
371
|
+
AnyTime.Converter = function(options)
|
372
|
+
{
|
373
|
+
// private members
|
374
|
+
|
375
|
+
var _flen = 0;
|
376
|
+
var _longDay = 9;
|
377
|
+
var _longMon = 9;
|
378
|
+
var _shortDay = 6;
|
379
|
+
var _shortMon = 3;
|
380
|
+
var _offAl = Number.MIN_VALUE; // format time zone offset alleged
|
381
|
+
var _offCap = Number.MIN_VALUE; // parsed time zone offset captured
|
382
|
+
var _offF = Number.MIN_VALUE; // format time zone offset imposed
|
383
|
+
var _offFSI = (-1); // format time zone label subindex
|
384
|
+
var _offP = Number.MIN_VALUE; // parsed time zone offset assumed
|
385
|
+
var _offPSI = (-1); // parsed time zone label subindex captured
|
386
|
+
var _captureOffset = false;
|
387
|
+
|
388
|
+
// public members
|
389
|
+
|
390
|
+
this.fmt = '%Y-%m-%d %T';
|
391
|
+
this.dAbbr = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
|
392
|
+
this.dNames = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
|
393
|
+
this.eAbbr = ['BCE','CE'];
|
394
|
+
this.mAbbr = [ 'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec' ];
|
395
|
+
this.mNames = [ 'January','February','March','April','May','June','July','August','September','October','November','December' ];
|
396
|
+
this.baseYear = null;
|
397
|
+
|
398
|
+
//-------------------------------------------------------------------------
|
399
|
+
// AnyTime.Converter.dAt() returns true if the character in str at pos
|
400
|
+
// is a digit.
|
401
|
+
//-------------------------------------------------------------------------
|
402
|
+
|
403
|
+
this.dAt = function( str, pos )
|
404
|
+
{
|
405
|
+
return ( (str.charCodeAt(pos)>='0'.charCodeAt(0)) &&
|
406
|
+
(str.charCodeAt(pos)<='9'.charCodeAt(0)) );
|
407
|
+
};
|
408
|
+
|
409
|
+
//-------------------------------------------------------------------------
|
410
|
+
// AnyTime.Converter.format() returns a String containing the value
|
411
|
+
// of a specified Date object, using the format string passed to
|
412
|
+
// AnyTime.Converter().
|
413
|
+
//
|
414
|
+
// Method parameter:
|
415
|
+
//
|
416
|
+
// date - the Date object to be converted
|
417
|
+
//-------------------------------------------------------------------------
|
418
|
+
|
419
|
+
this.format = function( date )
|
420
|
+
{
|
421
|
+
var d = new Date(date.getTime());
|
422
|
+
if ( ( _offAl == Number.MIN_VALUE ) && ( _offF != Number.MIN_VALUE ) )
|
423
|
+
d.setTime( ( d.getTime() + (d.getTimezoneOffset()*60000) ) + (_offF*60000) );
|
424
|
+
|
425
|
+
var t;
|
426
|
+
var str = '';
|
427
|
+
for ( var f = 0 ; f < _flen ; f++ )
|
428
|
+
{
|
429
|
+
if ( this.fmt.charAt(f) != '%' )
|
430
|
+
str += this.fmt.charAt(f);
|
431
|
+
else
|
432
|
+
{
|
433
|
+
var ch = this.fmt.charAt(f+1)
|
434
|
+
switch ( ch )
|
435
|
+
{
|
436
|
+
case 'a': // Abbreviated weekday name (Sun..Sat)
|
437
|
+
str += this.dAbbr[ d.getDay() ];
|
438
|
+
break;
|
439
|
+
case 'B': // BCE string (eAbbr[0], usually BCE or BC, only if appropriate) (NON-MYSQL)
|
440
|
+
if ( d.getFullYear() < 0 )
|
441
|
+
str += this.eAbbr[0];
|
442
|
+
break;
|
443
|
+
case 'b': // Abbreviated month name (Jan..Dec)
|
444
|
+
str += this.mAbbr[ d.getMonth() ];
|
445
|
+
break;
|
446
|
+
case 'C': // CE string (eAbbr[1], usually CE or AD, only if appropriate) (NON-MYSQL)
|
447
|
+
if ( d.getFullYear() > 0 )
|
448
|
+
str += this.eAbbr[1];
|
449
|
+
break;
|
450
|
+
case 'c': // Month, numeric (0..12)
|
451
|
+
str += d.getMonth()+1;
|
452
|
+
break;
|
453
|
+
case 'd': // Day of the month, numeric (00..31)
|
454
|
+
t = d.getDate();
|
455
|
+
if ( t < 10 ) str += '0';
|
456
|
+
str += String(t);
|
457
|
+
break;
|
458
|
+
case 'D': // Day of the month with English suffix (0th, 1st,...)
|
459
|
+
t = String(d.getDate());
|
460
|
+
str += t;
|
461
|
+
if ( ( t.length == 2 ) && ( t.charAt(0) == '1' ) )
|
462
|
+
str += 'th';
|
463
|
+
else
|
464
|
+
{
|
465
|
+
switch ( t.charAt( t.length-1 ) )
|
466
|
+
{
|
467
|
+
case '1': str += 'st'; break;
|
468
|
+
case '2': str += 'nd'; break;
|
469
|
+
case '3': str += 'rd'; break;
|
470
|
+
default: str += 'th'; break;
|
471
|
+
}
|
472
|
+
}
|
473
|
+
break;
|
474
|
+
case 'E': // era string (from eAbbr[], BCE, CE, BC or AD) (NON-MYSQL)
|
475
|
+
str += this.eAbbr[ (d.getFullYear()<0) ? 0 : 1 ];
|
476
|
+
break;
|
477
|
+
case 'e': // Day of the month, numeric (0..31)
|
478
|
+
str += d.getDate();
|
479
|
+
break;
|
480
|
+
case 'H': // Hour (00..23)
|
481
|
+
t = d.getHours();
|
482
|
+
if ( t < 10 ) str += '0';
|
483
|
+
str += String(t);
|
484
|
+
break;
|
485
|
+
case 'h': // Hour (01..12)
|
486
|
+
case 'I': // Hour (01..12)
|
487
|
+
t = d.getHours() % 12;
|
488
|
+
if ( t == 0 )
|
489
|
+
str += '12';
|
490
|
+
else
|
491
|
+
{
|
492
|
+
if ( t < 10 ) str += '0';
|
493
|
+
str += String(t);
|
494
|
+
}
|
495
|
+
break;
|
496
|
+
case 'i': // Minutes, numeric (00..59)
|
497
|
+
t = d.getMinutes();
|
498
|
+
if ( t < 10 ) str += '0';
|
499
|
+
str += String(t);
|
500
|
+
break;
|
501
|
+
case 'k': // Hour (0..23)
|
502
|
+
str += d.getHours();
|
503
|
+
break;
|
504
|
+
case 'l': // Hour (1..12)
|
505
|
+
t = d.getHours() % 12;
|
506
|
+
if ( t == 0 )
|
507
|
+
str += '12';
|
508
|
+
else
|
509
|
+
str += String(t);
|
510
|
+
break;
|
511
|
+
case 'M': // Month name (January..December)
|
512
|
+
str += this.mNames[ d.getMonth() ];
|
513
|
+
break;
|
514
|
+
case 'm': // Month, numeric (00..12)
|
515
|
+
t = d.getMonth() + 1;
|
516
|
+
if ( t < 10 ) str += '0';
|
517
|
+
str += String(t);
|
518
|
+
break;
|
519
|
+
case 'p': // AM or PM
|
520
|
+
str += ( ( d.getHours() < 12 ) ? 'AM' : 'PM' );
|
521
|
+
break;
|
522
|
+
case 'r': // Time, 12-hour (hh:mm:ss followed by AM or PM)
|
523
|
+
t = d.getHours() % 12;
|
524
|
+
if ( t == 0 )
|
525
|
+
str += '12:';
|
526
|
+
else
|
527
|
+
{
|
528
|
+
if ( t < 10 ) str += '0';
|
529
|
+
str += String(t) + ':';
|
530
|
+
}
|
531
|
+
t = d.getMinutes();
|
532
|
+
if ( t < 10 ) str += '0';
|
533
|
+
str += String(t) + ':';
|
534
|
+
t = d.getSeconds();
|
535
|
+
if ( t < 10 ) str += '0';
|
536
|
+
str += String(t);
|
537
|
+
str += ( ( d.getHours() < 12 ) ? 'AM' : 'PM' );
|
538
|
+
break;
|
539
|
+
case 'S': // Seconds (00..59)
|
540
|
+
case 's': // Seconds (00..59)
|
541
|
+
t = d.getSeconds();
|
542
|
+
if ( t < 10 ) str += '0';
|
543
|
+
str += String(t);
|
544
|
+
break;
|
545
|
+
case 'T': // Time, 24-hour (hh:mm:ss)
|
546
|
+
t = d.getHours();
|
547
|
+
if ( t < 10 ) str += '0';
|
548
|
+
str += String(t) + ':';
|
549
|
+
t = d.getMinutes();
|
550
|
+
if ( t < 10 ) str += '0';
|
551
|
+
str += String(t) + ':';
|
552
|
+
t = d.getSeconds();
|
553
|
+
if ( t < 10 ) str += '0';
|
554
|
+
str += String(t);
|
555
|
+
break;
|
556
|
+
case 'W': // Weekday name (Sunday..Saturday)
|
557
|
+
str += this.dNames[ d.getDay() ];
|
558
|
+
break;
|
559
|
+
case 'w': // Day of the week (0=Sunday..6=Saturday)
|
560
|
+
str += d.getDay();
|
561
|
+
break;
|
562
|
+
case 'Y': // Year, numeric, four digits (negative if before 0001)
|
563
|
+
str += AnyTime.pad(d.getFullYear(),4);
|
564
|
+
break;
|
565
|
+
case 'y': // Year, numeric (two digits, negative if before 0001)
|
566
|
+
t = d.getFullYear() % 100;
|
567
|
+
str += AnyTime.pad(t,2);
|
568
|
+
break;
|
569
|
+
case 'Z': // Year, numeric, four digits, unsigned (NON-MYSQL)
|
570
|
+
str += AnyTime.pad(Math.abs(d.getFullYear()),4);
|
571
|
+
break;
|
572
|
+
case 'z': // Year, numeric, variable length, unsigned (NON-MYSQL)
|
573
|
+
str += Math.abs(d.getFullYear());
|
574
|
+
break;
|
575
|
+
case '%': // A literal '%' character
|
576
|
+
str += '%';
|
577
|
+
break;
|
578
|
+
case '#': // signed timezone offset in minutes
|
579
|
+
t = ( _offAl != Number.MIN_VALUE ) ? _offAl :
|
580
|
+
( _offF == Number.MIN_VALUE ) ? (0-d.getTimezoneOffset()) : _offF;
|
581
|
+
if ( t >= 0 )
|
582
|
+
str += '+';
|
583
|
+
str += t;
|
584
|
+
break;
|
585
|
+
case '@': // timezone offset label
|
586
|
+
t = ( _offAl != Number.MIN_VALUE ) ? _offAl :
|
587
|
+
( _offF == Number.MIN_VALUE ) ? (0-d.getTimezoneOffset()) : _offF;
|
588
|
+
if ( AnyTime.utcLabel && AnyTime.utcLabel[t] )
|
589
|
+
{
|
590
|
+
if ( ( _offFSI > 0 ) && ( _offFSI < AnyTime.utcLabel[t].length ) )
|
591
|
+
str += AnyTime.utcLabel[t][_offFSI];
|
592
|
+
else
|
593
|
+
str += AnyTime.utcLabel[t][0];
|
594
|
+
break;
|
595
|
+
}
|
596
|
+
str += 'UTC';
|
597
|
+
ch = ':'; // drop through for offset formatting
|
598
|
+
case '+': // signed, 4-digit timezone offset in hours and minutes
|
599
|
+
case '-': // signed, 3-or-4-digit timezone offset in hours and minutes
|
600
|
+
case ':': // signed 4-digit timezone offset with colon delimiter
|
601
|
+
case ';': // signed 3-or-4-digit timezone offset with colon delimiter
|
602
|
+
t = ( _offAl != Number.MIN_VALUE ) ? _offAl :
|
603
|
+
( _offF == Number.MIN_VALUE ) ? (0-d.getTimezoneOffset()) : _offF;
|
604
|
+
if ( t < 0 )
|
605
|
+
str += '-';
|
606
|
+
else
|
607
|
+
str += '+';
|
608
|
+
t = Math.abs(t);
|
609
|
+
str += ((ch=='+')||(ch==':')) ? AnyTime.pad(Math.floor(t/60),2) : Math.floor(t/60);
|
610
|
+
if ( (ch==':') || (ch==';') )
|
611
|
+
str += ':';
|
612
|
+
str += AnyTime.pad(t%60,2);
|
613
|
+
break;
|
614
|
+
case 'f': // Microseconds (000000..999999)
|
615
|
+
case 'j': // Day of year (001..366)
|
616
|
+
case 'U': // Week (00..53), where Sunday is the first day of the week
|
617
|
+
case 'u': // Week (00..53), where Monday is the first day of the week
|
618
|
+
case 'V': // Week (01..53), where Sunday is the first day of the week; used with %X
|
619
|
+
case 'v': // Week (01..53), where Monday is the first day of the week; used with %x
|
620
|
+
case 'X': // Year for the week where Sunday is the first day of the week, numeric, four digits; used with %V
|
621
|
+
case 'x': // Year for the week, where Monday is the first day of the week, numeric, four digits; used with %v
|
622
|
+
throw '%'+ch+' not implemented by AnyTime.Converter';
|
623
|
+
default: // for any character not listed above
|
624
|
+
str += this.fmt.substr(f,2);
|
625
|
+
} // switch ( this.fmt.charAt(f+1) )
|
626
|
+
f++;
|
627
|
+
} // else
|
628
|
+
} // for ( var f = 0 ; f < _flen ; f++ )
|
629
|
+
return str;
|
630
|
+
|
631
|
+
}; // AnyTime.Converter.format()
|
632
|
+
|
633
|
+
//-------------------------------------------------------------------------
|
634
|
+
// AnyTime.Converter.getUtcParseOffsetCaptured() returns the UTC offset
|
635
|
+
// last captured by a parsed string (or assumed by utcParseOffsetAssumed).
|
636
|
+
// It returns Number.MIN_VALUE if this object was not constructed with
|
637
|
+
// the utcParseOffsetCapture option set to true, or if an offset was not
|
638
|
+
// specified by the last parsed string or utcParseOffsetAssumed.
|
639
|
+
//-------------------------------------------------------------------------
|
640
|
+
|
641
|
+
this.getUtcParseOffsetCaptured = function()
|
642
|
+
{
|
643
|
+
return _offCap;
|
644
|
+
};
|
645
|
+
|
646
|
+
//-------------------------------------------------------------------------
|
647
|
+
// AnyTime.Converter.getUtcParseOffsetCaptured() returns the UTC offset
|
648
|
+
// last captured by a parsed string (or assumed by utcParseOffsetAssumed).
|
649
|
+
// It returns Number.MIN_VALUE if this object was not constructed with
|
650
|
+
// the utcParseOffsetCapture option set to true, or if an offset was not
|
651
|
+
// specified by the last parsed string or utcParseOffsetAssumed.
|
652
|
+
//-------------------------------------------------------------------------
|
653
|
+
|
654
|
+
this.getUtcParseOffsetSubIndex = function()
|
655
|
+
{
|
656
|
+
return _offPSI;
|
657
|
+
};
|
658
|
+
|
659
|
+
//-------------------------------------------------------------------------
|
660
|
+
// AnyTime.Converter.parse() returns a Date initialized from a specified
|
661
|
+
// string, using the format passed to AnyTime.Converter().
|
662
|
+
//
|
663
|
+
// Method parameter:
|
664
|
+
//
|
665
|
+
// str - the String object to be converted
|
666
|
+
//-------------------------------------------------------------------------
|
667
|
+
|
668
|
+
this.parse = function( str )
|
669
|
+
{
|
670
|
+
_offCap = _offP;
|
671
|
+
_offPSI = (-1);
|
672
|
+
var era = 1;
|
673
|
+
var time = new Date(4,0,1,0,0,0,0);//4=leap year bug
|
674
|
+
var slen = str.length;
|
675
|
+
var s = 0;
|
676
|
+
var tzSign = 1, tzOff = _offP;
|
677
|
+
var i, matched, sub, sublen, temp;
|
678
|
+
for ( var f = 0 ; f < _flen ; f++ )
|
679
|
+
{
|
680
|
+
if ( this.fmt.charAt(f) == '%' )
|
681
|
+
{
|
682
|
+
var ch = this.fmt.charAt(f+1);
|
683
|
+
switch ( ch )
|
684
|
+
{
|
685
|
+
case 'a': // Abbreviated weekday name (Sun..Sat)
|
686
|
+
matched = false;
|
687
|
+
for ( sublen = 0 ; s + sublen < slen ; sublen++ )
|
688
|
+
{
|
689
|
+
sub = str.substr(s,sublen);
|
690
|
+
for ( i = 0 ; i < 12 ; i++ )
|
691
|
+
if ( this.dAbbr[i] == sub )
|
692
|
+
{
|
693
|
+
matched = true;
|
694
|
+
s += sublen;
|
695
|
+
break;
|
696
|
+
}
|
697
|
+
if ( matched )
|
698
|
+
break;
|
699
|
+
} // for ( sublen ... )
|
700
|
+
if ( ! matched )
|
701
|
+
throw 'unknown weekday: '+str.substr(s);
|
702
|
+
break;
|
703
|
+
case 'B': // BCE string (eAbbr[0]), only if needed. (NON-MYSQL)
|
704
|
+
sublen = this.eAbbr[0].length;
|
705
|
+
if ( ( s + sublen <= slen ) && ( str.substr(s,sublen) == this.eAbbr[0] ) )
|
706
|
+
{
|
707
|
+
era = (-1);
|
708
|
+
s += sublen;
|
709
|
+
}
|
710
|
+
break;
|
711
|
+
case 'b': // Abbreviated month name (Jan..Dec)
|
712
|
+
matched = false;
|
713
|
+
for ( sublen = 0 ; s + sublen < slen ; sublen++ )
|
714
|
+
{
|
715
|
+
sub = str.substr(s,sublen);
|
716
|
+
for ( i = 0 ; i < 12 ; i++ )
|
717
|
+
if ( this.mAbbr[i] == sub )
|
718
|
+
{
|
719
|
+
time.setMonth( i );
|
720
|
+
matched = true;
|
721
|
+
s += sublen;
|
722
|
+
break;
|
723
|
+
}
|
724
|
+
if ( matched )
|
725
|
+
break;
|
726
|
+
} // for ( sublen ... )
|
727
|
+
if ( ! matched )
|
728
|
+
throw 'unknown month: '+str.substr(s);
|
729
|
+
break;
|
730
|
+
case 'C': // CE string (eAbbr[1]), only if needed. (NON-MYSQL)
|
731
|
+
sublen = this.eAbbr[1].length;
|
732
|
+
if ( ( s + sublen <= slen ) && ( str.substr(s,sublen) == this.eAbbr[1] ) )
|
733
|
+
s += sublen; // note: CE is the default era
|
734
|
+
break;
|
735
|
+
case 'c': // Month, numeric (0..12)
|
736
|
+
if ( ( s+1 < slen ) && this.dAt(str,s+1) )
|
737
|
+
{
|
738
|
+
time.setMonth( (Number(str.substr(s,2))-1)%12 );
|
739
|
+
s += 2;
|
740
|
+
}
|
741
|
+
else
|
742
|
+
{
|
743
|
+
time.setMonth( (Number(str.substr(s,1))-1)%12 );
|
744
|
+
s++;
|
745
|
+
}
|
746
|
+
break;
|
747
|
+
case 'D': // Day of the month with English suffix (0th,1st,...)
|
748
|
+
if ( ( s+1 < slen ) && this.dAt(str,s+1) )
|
749
|
+
{
|
750
|
+
time.setDate( Number(str.substr(s,2)) );
|
751
|
+
s += 4;
|
752
|
+
}
|
753
|
+
else
|
754
|
+
{
|
755
|
+
time.setDate( Number(str.substr(s,1)) );
|
756
|
+
s += 3;
|
757
|
+
}
|
758
|
+
break;
|
759
|
+
case 'd': // Day of the month, numeric (00..31)
|
760
|
+
time.setDate( Number(str.substr(s,2)) );
|
761
|
+
s += 2;
|
762
|
+
break;
|
763
|
+
case 'E': // era string (from eAbbr[]) (NON-MYSQL)
|
764
|
+
sublen = this.eAbbr[0].length;
|
765
|
+
if ( ( s + sublen <= slen ) && ( str.substr(s,sublen) == this.eAbbr[0] ) )
|
766
|
+
{
|
767
|
+
era = (-1);
|
768
|
+
s += sublen;
|
769
|
+
}
|
770
|
+
else if ( ( s + ( sublen = this.eAbbr[1].length ) <= slen ) && ( str.substr(s,sublen) == this.eAbbr[1] ) )
|
771
|
+
s += sublen; // note: CE is the default era
|
772
|
+
else
|
773
|
+
throw 'unknown era: '+str.substr(s);
|
774
|
+
break;
|
775
|
+
case 'e': // Day of the month, numeric (0..31)
|
776
|
+
if ( ( s+1 < slen ) && this.dAt(str,s+1) )
|
777
|
+
{
|
778
|
+
time.setDate( Number(str.substr(s,2)) );
|
779
|
+
s += 2;
|
780
|
+
}
|
781
|
+
else
|
782
|
+
{
|
783
|
+
time.setDate( Number(str.substr(s,1)) );
|
784
|
+
s++;
|
785
|
+
}
|
786
|
+
break;
|
787
|
+
case 'f': // Microseconds (000000..999999)
|
788
|
+
s += 6; // SKIPPED!
|
789
|
+
break;
|
790
|
+
case 'H': // Hour (00..23)
|
791
|
+
time.setHours( Number(str.substr(s,2)) );
|
792
|
+
s += 2;
|
793
|
+
break;
|
794
|
+
case 'h': // Hour (01..12)
|
795
|
+
case 'I': // Hour (01..12)
|
796
|
+
time.setHours( Number(str.substr(s,2)) );
|
797
|
+
s += 2;
|
798
|
+
break;
|
799
|
+
case 'i': // Minutes, numeric (00..59)
|
800
|
+
time.setMinutes( Number(str.substr(s,2)) );
|
801
|
+
s += 2;
|
802
|
+
break;
|
803
|
+
case 'k': // Hour (0..23)
|
804
|
+
if ( ( s+1 < slen ) && this.dAt(str,s+1) )
|
805
|
+
{
|
806
|
+
time.setHours( Number(str.substr(s,2)) );
|
807
|
+
s += 2;
|
808
|
+
}
|
809
|
+
else
|
810
|
+
{
|
811
|
+
time.setHours( Number(str.substr(s,1)) );
|
812
|
+
s++;
|
813
|
+
}
|
814
|
+
break;
|
815
|
+
case 'l': // Hour (1..12)
|
816
|
+
if ( ( s+1 < slen ) && this.dAt(str,s+1) )
|
817
|
+
{
|
818
|
+
time.setHours( Number(str.substr(s,2)) );
|
819
|
+
s += 2;
|
820
|
+
}
|
821
|
+
else
|
822
|
+
{
|
823
|
+
time.setHours( Number(str.substr(s,1)) );
|
824
|
+
s++;
|
825
|
+
}
|
826
|
+
break;
|
827
|
+
case 'M': // Month name (January..December)
|
828
|
+
matched = false;
|
829
|
+
for (sublen=_shortMon ; s + sublen <= slen ; sublen++ )
|
830
|
+
{
|
831
|
+
if ( sublen > _longMon )
|
832
|
+
break;
|
833
|
+
sub = str.substr(s,sublen);
|
834
|
+
for ( i = 0 ; i < 12 ; i++ )
|
835
|
+
{
|
836
|
+
if ( this.mNames[i] == sub )
|
837
|
+
{
|
838
|
+
time.setMonth( i );
|
839
|
+
matched = true;
|
840
|
+
s += sublen;
|
841
|
+
break;
|
842
|
+
}
|
843
|
+
}
|
844
|
+
if ( matched )
|
845
|
+
break;
|
846
|
+
}
|
847
|
+
break;
|
848
|
+
case 'm': // Month, numeric (00..12)
|
849
|
+
time.setMonth( (Number(str.substr(s,2))-1)%12 );
|
850
|
+
s += 2;
|
851
|
+
break;
|
852
|
+
case 'p': // AM or PM
|
853
|
+
if ( time.getHours() == 12 )
|
854
|
+
{
|
855
|
+
if ( str.charAt(s) == 'A' )
|
856
|
+
time.setHours(0);
|
857
|
+
}
|
858
|
+
else if ( str.charAt(s) == 'P' )
|
859
|
+
time.setHours( time.getHours() + 12 );
|
860
|
+
s += 2;
|
861
|
+
break;
|
862
|
+
case 'r': // Time, 12-hour (hh:mm:ss followed by AM or PM)
|
863
|
+
time.setHours(Number(str.substr(s,2)));
|
864
|
+
time.setMinutes(Number(str.substr(s+3,2)));
|
865
|
+
time.setSeconds(Number(str.substr(s+6,2)));
|
866
|
+
if ( time.getHours() == 12 )
|
867
|
+
{
|
868
|
+
if ( str.charAt(s) == 'A' )
|
869
|
+
time.setHours(0);
|
870
|
+
}
|
871
|
+
else if ( str.charAt(s) == 'P' )
|
872
|
+
time.setHours( time.getHours() + 12 );
|
873
|
+
s += 10;
|
874
|
+
break;
|
875
|
+
case 'S': // Seconds (00..59)
|
876
|
+
case 's': // Seconds (00..59)
|
877
|
+
time.setSeconds(Number(str.substr(s,2)));
|
878
|
+
s += 2;
|
879
|
+
break;
|
880
|
+
case 'T': // Time, 24-hour (hh:mm:ss)
|
881
|
+
time.setHours(Number(str.substr(s,2)));
|
882
|
+
time.setMinutes(Number(str.substr(s+3,2)));
|
883
|
+
time.setSeconds(Number(str.substr(s+6,2)));
|
884
|
+
s += 8;
|
885
|
+
break;
|
886
|
+
case 'W': // Weekday name (Sunday..Saturday)
|
887
|
+
matched = false;
|
888
|
+
for (sublen=_shortDay ; s + sublen <= slen ; sublen++ )
|
889
|
+
{
|
890
|
+
if ( sublen > _longDay )
|
891
|
+
break;
|
892
|
+
sub = str.substr(s,sublen);
|
893
|
+
for ( i = 0 ; i < 7 ; i++ )
|
894
|
+
{
|
895
|
+
if ( this.dNames[i] == sub )
|
896
|
+
{
|
897
|
+
matched = true;
|
898
|
+
s += sublen;
|
899
|
+
break;
|
900
|
+
}
|
901
|
+
}
|
902
|
+
if ( matched )
|
903
|
+
break;
|
904
|
+
}
|
905
|
+
break;
|
906
|
+
case 'w': // Day of the week (0=Sunday..6=Saturday) (ignored)
|
907
|
+
s += 1;
|
908
|
+
break;
|
909
|
+
case 'Y': // Year, numeric, four digits, negative if before 0001
|
910
|
+
i = 4;
|
911
|
+
if ( str.substr(s,1) == '-' )
|
912
|
+
i++;
|
913
|
+
time.setFullYear(Number(str.substr(s,i)));
|
914
|
+
s += i;
|
915
|
+
break;
|
916
|
+
case 'y': // Year, numeric (two digits), negative before baseYear
|
917
|
+
i = 2;
|
918
|
+
if ( str.substr(s,1) == '-' )
|
919
|
+
i++;
|
920
|
+
temp = Number(str.substr(s,i));
|
921
|
+
if ( typeof(this.baseYear) == 'number' )
|
922
|
+
temp += this.baseYear;
|
923
|
+
else if ( temp < 70 )
|
924
|
+
temp += 2000;
|
925
|
+
else
|
926
|
+
temp += 1900;
|
927
|
+
time.setFullYear(temp);
|
928
|
+
s += i;
|
929
|
+
break;
|
930
|
+
case 'Z': // Year, numeric, four digits, unsigned (NON-MYSQL)
|
931
|
+
time.setFullYear(Number(str.substr(s,4)));
|
932
|
+
s += 4;
|
933
|
+
break;
|
934
|
+
case 'z': // Year, numeric, variable length, unsigned (NON-MYSQL)
|
935
|
+
i = 0;
|
936
|
+
while ( ( s < slen ) && this.dAt(str,s) )
|
937
|
+
i = ( i * 10 ) + Number(str.charAt(s++));
|
938
|
+
time.setFullYear(i);
|
939
|
+
break;
|
940
|
+
case '#': // signed timezone offset in minutes.
|
941
|
+
if ( str.charAt(s++) == '-' )
|
942
|
+
tzSign = (-1);
|
943
|
+
for ( tzOff = 0 ; ( s < slen ) && (String(i=Number(str.charAt(s)))==str.charAt(s)) ; s++ )
|
944
|
+
tzOff = ( tzOff * 10 ) + i;
|
945
|
+
tzOff *= tzSign;
|
946
|
+
break;
|
947
|
+
case '@': // timezone label
|
948
|
+
_offPSI = (-1);
|
949
|
+
if ( AnyTime.utcLabel )
|
950
|
+
{
|
951
|
+
matched = false;
|
952
|
+
for ( tzOff in AnyTime.utcLabel )
|
953
|
+
if ( ! Array.prototype[tzOff] ) // prototype.js compatibility issue
|
954
|
+
{
|
955
|
+
for ( i = 0 ; i < AnyTime.utcLabel[tzOff].length ; i++ )
|
956
|
+
{
|
957
|
+
sub = AnyTime.utcLabel[tzOff][i];
|
958
|
+
sublen = sub.length;
|
959
|
+
if ( ( s+sublen <= slen ) && ( str.substr(s,sublen) == sub ) )
|
960
|
+
{
|
961
|
+
s+=sublen;
|
962
|
+
matched = true;
|
963
|
+
break;
|
964
|
+
}
|
965
|
+
}
|
966
|
+
if ( matched )
|
967
|
+
break;
|
968
|
+
}
|
969
|
+
if ( matched )
|
970
|
+
{
|
971
|
+
_offPSI = i;
|
972
|
+
tzOff = Number(tzOff);
|
973
|
+
break; // case
|
974
|
+
}
|
975
|
+
}
|
976
|
+
if ( ( s+9 < slen ) || ( str.substr(s,3) != "UTC" ) )
|
977
|
+
throw 'unknown time zone: '+str.substr(s);
|
978
|
+
s += 3;
|
979
|
+
ch = ':'; // drop through for offset parsing
|
980
|
+
case '-': // signed, 3-or-4-digit timezone offset in hours and minutes
|
981
|
+
case '+': // signed, 4-digit timezone offset in hours and minutes
|
982
|
+
case ':': // signed 4-digit timezone offset with colon delimiter
|
983
|
+
case ';': // signed 3-or-4-digit timezone offset with colon delimiter
|
984
|
+
if ( str.charAt(s++) == '-' )
|
985
|
+
tzSign = (-1);
|
986
|
+
tzOff = Number(str.charAt(s));
|
987
|
+
if ( (ch=='+')||(ch==':')||((s+3<slen)&&(String(Number(str.charAt(s+3)))!==str.charAt(s+3))) )
|
988
|
+
tzOff = (tzOff*10) + Number(str.charAt(++s));
|
989
|
+
tzOff *= 60;
|
990
|
+
if ( (ch==':') || (ch==';') )
|
991
|
+
s++; // skip ":" (assumed)
|
992
|
+
tzOff = ( tzOff + Number(str.substr(++s,2)) ) * tzSign;
|
993
|
+
s += 2;
|
994
|
+
break;
|
995
|
+
case 'j': // Day of year (001..366)
|
996
|
+
case 'U': // Week (00..53), where Sunday is the first day of the week
|
997
|
+
case 'u': // Week (00..53), where Monday is the first day of the week
|
998
|
+
case 'V': // Week (01..53), where Sunday is the first day of the week; used with %X
|
999
|
+
case 'v': // Week (01..53), where Monday is the first day of the week; used with %x
|
1000
|
+
case 'X': // Year for the week where Sunday is the first day of the week, numeric, four digits; used with %V
|
1001
|
+
case 'x': // Year for the week, where Monday is the first day of the week, numeric, four digits; used with %v
|
1002
|
+
throw '%'+this.fmt.charAt(f+1)+' not implemented by AnyTime.Converter';
|
1003
|
+
case '%': // A literal '%' character
|
1004
|
+
default: // for any character not listed above
|
1005
|
+
throw '%'+this.fmt.charAt(f+1)+' reserved for future use';
|
1006
|
+
break;
|
1007
|
+
}
|
1008
|
+
f++;
|
1009
|
+
} // if ( this.fmt.charAt(f) == '%' )
|
1010
|
+
else if ( this.fmt.charAt(f) != str.charAt(s) )
|
1011
|
+
throw str + ' is not in "' + this.fmt + '" format';
|
1012
|
+
else
|
1013
|
+
s++;
|
1014
|
+
} // for ( var f ... )
|
1015
|
+
if ( era < 0 )
|
1016
|
+
time.setFullYear( 0 - time.getFullYear() );
|
1017
|
+
if ( tzOff != Number.MIN_VALUE )
|
1018
|
+
{
|
1019
|
+
if ( _captureOffset )
|
1020
|
+
_offCap = tzOff;
|
1021
|
+
else
|
1022
|
+
time.setTime( ( time.getTime() - (tzOff*60000) ) - (time.getTimezoneOffset()*60000) );
|
1023
|
+
}
|
1024
|
+
|
1025
|
+
return time;
|
1026
|
+
|
1027
|
+
}; // AnyTime.Converter.parse()
|
1028
|
+
|
1029
|
+
//-------------------------------------------------------------------------
|
1030
|
+
// AnyTime.Converter.setUtcFormatOffsetAlleged() sets the offset from
|
1031
|
+
// UTC, in minutes, to claim that a Date object represents during
|
1032
|
+
// formatting, even though it is formatted using local time. This merely
|
1033
|
+
// reports the alleged offset when a timezone specifier (%#, %+, %-, %:,
|
1034
|
+
// %; or %@) is encountered in the format string--it does not otherwise
|
1035
|
+
// affect the date/time value. This primarily exists so AnyTime.picker
|
1036
|
+
// can edit the time as specified (without conversion to local time) and
|
1037
|
+
// then convert the edited time to a different time zone (as selected
|
1038
|
+
// using the picker). This method returns the previous value, if any,
|
1039
|
+
// set by the utcFormatOffsetAlleged option, or a previous call to
|
1040
|
+
// setUtcFormatOffsetAlleged(), or Number.MIN_VALUE if no offset was
|
1041
|
+
// previously-alleged. Call this method with Number.MIN_VALUE to cancel
|
1042
|
+
// any prior value. Note that if a format offset is alleged, any offset
|
1043
|
+
// specified by option utcFormatOffsetImposed is ignored.
|
1044
|
+
//-------------------------------------------------------------------------
|
1045
|
+
|
1046
|
+
this.setUtcFormatOffsetAlleged = function( offset )
|
1047
|
+
{
|
1048
|
+
var prev = _offAl;
|
1049
|
+
_offAl = offset;
|
1050
|
+
return prev;
|
1051
|
+
};
|
1052
|
+
|
1053
|
+
//-------------------------------------------------------------------------
|
1054
|
+
// AnyTime.Converter.setUtcFormatOffsetSubIndex() sets the sub-index
|
1055
|
+
// to choose from the AnyTime.utcLabel array of arrays when formatting
|
1056
|
+
// a Date using the %@ specifier. For more information, see option
|
1057
|
+
// AnyTime.Converter.utcFormatOffsetSubIndex. This primarily exists so
|
1058
|
+
// AnyTime.picker can specify the Time Zone label selected using the
|
1059
|
+
// picker). This method returns the previous value, if any, set by the
|
1060
|
+
// utcFormatOffsetSubIndex option, or a previous call to
|
1061
|
+
// setUtcFormatOffsetAlleged(), or (-1) if no sub-index was previously-
|
1062
|
+
// chosen. Call this method with (-1) to cancel any prior value.
|
1063
|
+
//-------------------------------------------------------------------------
|
1064
|
+
|
1065
|
+
this.setUtcFormatOffsetSubIndex = function( subIndex )
|
1066
|
+
{
|
1067
|
+
var prev = _offFSI;
|
1068
|
+
_offFSI = subIndex;
|
1069
|
+
return prev;
|
1070
|
+
};
|
1071
|
+
|
1072
|
+
//-------------------------------------------------------------------------
|
1073
|
+
// AnyTime.Converter construction code:
|
1074
|
+
//-------------------------------------------------------------------------
|
1075
|
+
|
1076
|
+
(function(_this)
|
1077
|
+
{
|
1078
|
+
var i, len;
|
1079
|
+
|
1080
|
+
options = jQuery.extend(true,{},options||{});
|
1081
|
+
|
1082
|
+
if ( options.baseYear )
|
1083
|
+
_this.baseYear = Number(options.baseYear);
|
1084
|
+
|
1085
|
+
if ( options.format )
|
1086
|
+
_this.fmt = options.format;
|
1087
|
+
|
1088
|
+
_flen = _this.fmt.length;
|
1089
|
+
|
1090
|
+
if ( options.dayAbbreviations )
|
1091
|
+
_this.dAbbr = $.makeArray( options.dayAbbreviations );
|
1092
|
+
|
1093
|
+
if ( options.dayNames )
|
1094
|
+
{
|
1095
|
+
_this.dNames = $.makeArray( options.dayNames );
|
1096
|
+
_longDay = 1;
|
1097
|
+
_shortDay = 1000;
|
1098
|
+
for ( i = 0 ; i < 7 ; i++ )
|
1099
|
+
{
|
1100
|
+
len = _this.dNames[i].length;
|
1101
|
+
if ( len > _longDay )
|
1102
|
+
_longDay = len;
|
1103
|
+
if ( len < _shortDay )
|
1104
|
+
_shortDay = len;
|
1105
|
+
}
|
1106
|
+
}
|
1107
|
+
|
1108
|
+
if ( options.eraAbbreviations )
|
1109
|
+
_this.eAbbr = $.makeArray(options.eraAbbreviations);
|
1110
|
+
|
1111
|
+
if ( options.monthAbbreviations )
|
1112
|
+
_this.mAbbr = $.makeArray(options.monthAbbreviations);
|
1113
|
+
|
1114
|
+
if ( options.monthNames )
|
1115
|
+
{
|
1116
|
+
_this.mNames = $.makeArray( options.monthNames );
|
1117
|
+
_longMon = 1;
|
1118
|
+
_shortMon = 1000;
|
1119
|
+
for ( i = 0 ; i < 12 ; i++ )
|
1120
|
+
{
|
1121
|
+
len = _this.mNames[i].length;
|
1122
|
+
if ( len > _longMon )
|
1123
|
+
_longMon = len;
|
1124
|
+
if ( len < _shortMon )
|
1125
|
+
_shortMon = len;
|
1126
|
+
}
|
1127
|
+
}
|
1128
|
+
|
1129
|
+
if ( typeof options.utcFormatOffsetImposed != "undefined" )
|
1130
|
+
_offF = options.utcFormatOffsetImposed;
|
1131
|
+
|
1132
|
+
if ( typeof options.utcParseOffsetAssumed != "undefined" )
|
1133
|
+
_offP = options.utcParseOffsetAssumed;
|
1134
|
+
|
1135
|
+
if ( options.utcParseOffsetCapture )
|
1136
|
+
_captureOffset = true;
|
1137
|
+
|
1138
|
+
})(this); // AnyTime.Converter construction
|
1139
|
+
|
1140
|
+
}; // AnyTime.Converter =
|
1141
|
+
|
1142
|
+
//=============================================================================
|
1143
|
+
// AnyTime.noPicker()
|
1144
|
+
//
|
1145
|
+
// Removes the date/time entry picker attached to a specified text field.
|
1146
|
+
//=============================================================================
|
1147
|
+
|
1148
|
+
AnyTime.noPicker = function( id )
|
1149
|
+
{
|
1150
|
+
if ( __pickers[id] )
|
1151
|
+
{
|
1152
|
+
__pickers[id].cleanup();
|
1153
|
+
delete __pickers[id];
|
1154
|
+
}
|
1155
|
+
};
|
1156
|
+
|
1157
|
+
//=============================================================================
|
1158
|
+
// AnyTime.picker()
|
1159
|
+
//
|
1160
|
+
// Creates a date/time entry picker attached to a specified text field.
|
1161
|
+
// Instead of entering a date and/or time into the text field, the user
|
1162
|
+
// selects legal combinations using the picker, and the field is auto-
|
1163
|
+
// matically populated. The picker can be incorporated into the page
|
1164
|
+
// "inline", or used as a "popup" that appears when the text field is
|
1165
|
+
// clicked and disappears when the picker is dismissed. Ajax can be used
|
1166
|
+
// to send the selected value to a server to approve or veto it.
|
1167
|
+
//
|
1168
|
+
// To create a picker, simply include the necessary files in an HTML page
|
1169
|
+
// and call the function for each date/time input field. The following
|
1170
|
+
// example creates a popup picker for field "foo" using the default
|
1171
|
+
// format, and a second date-only (no time) inline (always-visible)
|
1172
|
+
// Ajax-enabled picker for field "bar":
|
1173
|
+
//
|
1174
|
+
// <link rel="stylesheet" type="text/css" href="anytime.css" />
|
1175
|
+
// <script type="text/javascript" src="jquery.js"></script>
|
1176
|
+
// <script type="text/javascript" src="anytime.js"></script>
|
1177
|
+
// <input type="text" id="foo" tabindex="1" value="1967-07-30 23:45" />
|
1178
|
+
// <input type="text" id="bar" tabindex="2" value="01/06/90" />
|
1179
|
+
// <script type="text/javascript">
|
1180
|
+
// AnyTime.picker( "foo" );
|
1181
|
+
// AnyTime.picker( "bar", { placement:"inline", format: "%m/%d/%y",
|
1182
|
+
// ajaxOptions { url: "/some/server/page/" } } );
|
1183
|
+
// </script>
|
1184
|
+
//
|
1185
|
+
// The appearance of the picker can be extensively modified using CSS styles.
|
1186
|
+
// A default appearance can be achieved by the "anytime.css" stylesheet that
|
1187
|
+
// accompanies this script. The default style looks better in browsers other
|
1188
|
+
// than Internet Explorer (before IE8) because older versions of IE do not
|
1189
|
+
// properly implement the CSS box model standard; however, it is passable in
|
1190
|
+
// Internet Explorer as well.
|
1191
|
+
//
|
1192
|
+
// Method parameters:
|
1193
|
+
//
|
1194
|
+
// id - the "id" attribute of the textfield to associate with the
|
1195
|
+
// AnyTime.picker object. The AnyTime.picker will attach itself
|
1196
|
+
// to the textfield and manage its value.
|
1197
|
+
//
|
1198
|
+
// options - an object (associative array) of optional parameters that
|
1199
|
+
// override default behaviors. The supported options are:
|
1200
|
+
//
|
1201
|
+
// ajaxOptions - options passed to jQuery's $.ajax() method whenever
|
1202
|
+
// the user dismisses a popup picker or selects a value in an inline
|
1203
|
+
// picker. The input's name (or ID) and value are passed to the
|
1204
|
+
// server (appended to ajaxOptions.data, if present), and the
|
1205
|
+
// "success" handler sets the input's value to the responseText.
|
1206
|
+
// Therefore, the text returned by the server must be valid for the
|
1207
|
+
// input'sdate/time format, and the server can approve or veto the
|
1208
|
+
// value chosen by the user. For more information, see:
|
1209
|
+
// http://docs.jquery.com/Ajax.
|
1210
|
+
// If ajaxOptions.success is specified, it is used instead of the
|
1211
|
+
// default "success" behavior.
|
1212
|
+
//
|
1213
|
+
// askEra - if true, buttons to select the era are shown on the year
|
1214
|
+
// selector popup, even if format specifier does not include the
|
1215
|
+
// era. If false, buttons to select the era are NOT shown, even
|
1216
|
+
// if the format specifier includes ther era. Normally, era buttons
|
1217
|
+
// are only shown if the format string specifies the era.
|
1218
|
+
//
|
1219
|
+
// askSecond - if false, buttons for number-of-seconds are not shown
|
1220
|
+
// even if the format includes seconds. Normally, the buttons
|
1221
|
+
// are shown if the format string includes seconds.
|
1222
|
+
//
|
1223
|
+
// earliest - String or Date object representing the earliest date/time
|
1224
|
+
// that a user can select. For best results if the field is only
|
1225
|
+
// used to specify a date, be sure to set the time to 00:00:00.
|
1226
|
+
// If a String is used, it will be parsed according to the picker's
|
1227
|
+
// format (see AnyTime.Converter.format()).
|
1228
|
+
//
|
1229
|
+
// firstDOW - a value from 0 (Sunday) to 6 (Saturday) stating which
|
1230
|
+
// day should appear at the beginning of the week. The default is 0
|
1231
|
+
// (Sunday). The most common substitution is 1 (Monday). Note that
|
1232
|
+
// if custom arrays are specified for AnyTime.Converter's dayAbbreviations
|
1233
|
+
// and/or dayNames options, they should nonetheless begin with the
|
1234
|
+
// value for Sunday.
|
1235
|
+
//
|
1236
|
+
// hideInput - if true, the <input> is "hidden" (the picker appears in
|
1237
|
+
// its place). This actually sets the border, height, margin, padding
|
1238
|
+
// and width of the field as small as possivle, so it can still get focus.
|
1239
|
+
// If you try to hide the field using traditional techniques (such as
|
1240
|
+
// setting "display:none"), the picker will not behave correctly.
|
1241
|
+
//
|
1242
|
+
// labelDayOfMonth - the label for the day-of-month "buttons".
|
1243
|
+
// Can be any HTML! If not specified, "Day of Month" is assumed.
|
1244
|
+
//
|
1245
|
+
// labelDismiss - the label for the dismiss "button" (if placement is
|
1246
|
+
// "popup"). Can be any HTML! If not specified, "X" is assumed.
|
1247
|
+
//
|
1248
|
+
// labelHour - the label for the hour "buttons".
|
1249
|
+
// Can be any HTML! If not specified, "Hour" is assumed.
|
1250
|
+
//
|
1251
|
+
// labelMinute - the label for the minute "buttons".
|
1252
|
+
// Can be any HTML! If not specified, "Minute" is assumed.
|
1253
|
+
//
|
1254
|
+
// labelMonth - the label for the month "buttons".
|
1255
|
+
// Can be any HTML! If not specified, "Month" is assumed.
|
1256
|
+
//
|
1257
|
+
// labelTimeZone - the label for the UTC offset (timezone) "buttons".
|
1258
|
+
// Can be any HTML! If not specified, "Time Zone" is assumed.
|
1259
|
+
//
|
1260
|
+
// labelSecond - the label for the second "buttons".
|
1261
|
+
// Can be any HTML! If not specified, "Second" is assumed.
|
1262
|
+
// This option is ignored if askSecond is false!
|
1263
|
+
//
|
1264
|
+
// labelTitle - the label for the "title bar". Can be any HTML!
|
1265
|
+
// If not specified, then whichever of the following is most
|
1266
|
+
// appropriate is used: "Select a Date and Time", "Select a Date"
|
1267
|
+
// or "Select a Time", or no label if only one field is present.
|
1268
|
+
//
|
1269
|
+
// labelYear - the label for the year "buttons".
|
1270
|
+
// Can be any HTML! If not specified, "Year" is assumed.
|
1271
|
+
//
|
1272
|
+
// latest - String or Date object representing the latest date/time
|
1273
|
+
// that a user can select. For best results if the field is only
|
1274
|
+
// used to specify a date, be sure to set the time to 23:59:59.
|
1275
|
+
// If a String is used, it will be parsed according to the picker's
|
1276
|
+
// format (see AnyTime.Converter.format()).
|
1277
|
+
//
|
1278
|
+
// placement - One of the following strings:
|
1279
|
+
//
|
1280
|
+
// "popup" = the picker appears above its <input> when the input
|
1281
|
+
// receives focus, and disappears when it is dismissed. This is
|
1282
|
+
// the default behavior.
|
1283
|
+
//
|
1284
|
+
// "inline" = the picker is placed immediately after the <input>
|
1285
|
+
// and remains visible at all times. When choosing this placement,
|
1286
|
+
// it is best to make the <input> invisible and use only the
|
1287
|
+
// picker to select dates. The <input> value can still be used
|
1288
|
+
// during form submission as it will always reflect the current
|
1289
|
+
// picker state.
|
1290
|
+
//
|
1291
|
+
// WARNING: when using "inline" and XHTML and including a day-of-
|
1292
|
+
// the-month format field, the input may only appear where a <table>
|
1293
|
+
// element is permitted (for example, NOT within a <p> element).
|
1294
|
+
// This is because the picker uses a <table> element to arrange
|
1295
|
+
// the day-of-the-month (calendar) buttons. Failure to follow this
|
1296
|
+
// advice may result in an "unknown error" in Internet Explorer.
|
1297
|
+
//
|
1298
|
+
// The following additional options may be specified; see documentation
|
1299
|
+
// for AnyTime.Converter (above) for information about these options:
|
1300
|
+
//
|
1301
|
+
// baseYear
|
1302
|
+
// dayAbbreviations
|
1303
|
+
// dayNames
|
1304
|
+
// eraAbbreviations
|
1305
|
+
// format
|
1306
|
+
// monthAbbreviations
|
1307
|
+
// monthNames
|
1308
|
+
//
|
1309
|
+
// Other behavior, such as how to format the values on the display
|
1310
|
+
// and which "buttons" to include, is inferred from the format string.
|
1311
|
+
//=============================================================================
|
1312
|
+
|
1313
|
+
AnyTime.picker = function( id, options )
|
1314
|
+
{
|
1315
|
+
// Create a new private object instance to manage the picker,
|
1316
|
+
// if one does not already exist.
|
1317
|
+
|
1318
|
+
if ( __pickers[id] )
|
1319
|
+
throw 'Cannot create another AnyTime.picker for "'+id+'"';
|
1320
|
+
|
1321
|
+
var _this = null;
|
1322
|
+
|
1323
|
+
__pickers[id] =
|
1324
|
+
{
|
1325
|
+
// private members
|
1326
|
+
|
1327
|
+
twelveHr: false,
|
1328
|
+
ajaxOpts: null, // options for AJAX requests
|
1329
|
+
denyTab: true, // set to true to stop Opera from tabbing away
|
1330
|
+
askEra: false, // prompt the user for the era in yDiv?
|
1331
|
+
cloak: null, // cloak div
|
1332
|
+
conv: null, // AnyTime.Converter
|
1333
|
+
bMinW: 0, // min width of body div
|
1334
|
+
bMinH: 0, // min height of body div
|
1335
|
+
dMinW: 0, // min width of date div
|
1336
|
+
dMinH: 0, // min height of date div
|
1337
|
+
div: null, // picker div
|
1338
|
+
dB: null, // body div
|
1339
|
+
dD: null, // date div
|
1340
|
+
dY: null, // years div
|
1341
|
+
dMo: null, // months div
|
1342
|
+
dDoM: null, // date-of-month table
|
1343
|
+
hDoM: null, // date-of-month heading
|
1344
|
+
hMo: null, // month heading
|
1345
|
+
hTitle: null, // title heading
|
1346
|
+
hY: null, // year heading
|
1347
|
+
dT: null, // time div
|
1348
|
+
dH: null, // hours div
|
1349
|
+
dM: null, // minutes div
|
1350
|
+
dS: null, // seconds div
|
1351
|
+
dO: null, // offset (time zone) div
|
1352
|
+
earliest: null, // earliest selectable date/time
|
1353
|
+
fBtn: null, // button with current focus
|
1354
|
+
fDOW: 0, // index to use as first day-of-week
|
1355
|
+
hBlur: null, // input handler
|
1356
|
+
hClick: null, // input handler
|
1357
|
+
hFocus: null, // input handler
|
1358
|
+
hKeydown: null, // input handler
|
1359
|
+
hKeypress: null, // input handler
|
1360
|
+
id: null, // picker ID
|
1361
|
+
inp: null, // input text field
|
1362
|
+
latest: null, // latest selectable date/time
|
1363
|
+
lastAjax: null, // last value submitted using AJAX
|
1364
|
+
lostFocus: false, // when focus is lost, must redraw
|
1365
|
+
lX: 'X', // label for dismiss button
|
1366
|
+
lY: 'Year', // label for year
|
1367
|
+
lO: 'Time Zone', // label for UTC offset (time zone)
|
1368
|
+
oBody: null, // UTC offset selector popup
|
1369
|
+
oConv: null, // AnyTime.Converter for offset display
|
1370
|
+
oCur: null, // current-UTC-offset button
|
1371
|
+
oDiv: null, // UTC offset selector popup
|
1372
|
+
oLab: null, // UTC offset label
|
1373
|
+
oListMinW: 0, // min width of offset list element
|
1374
|
+
oMinW: 0, // min width of UTC offset element
|
1375
|
+
oSel: null, // select (plus/minus) UTC-offset button
|
1376
|
+
offMin: Number.MIN_VALUE, // current UTC offset in minutes
|
1377
|
+
offSI: -1, // current UTC label sub-index (if any)
|
1378
|
+
offStr: "", // current UTC offset (time zone) string
|
1379
|
+
pop: true, // picker is a popup?
|
1380
|
+
time: null, // current date/time
|
1381
|
+
tMinW: 0, // min width of time div
|
1382
|
+
tMinH: 0, // min height of time div
|
1383
|
+
url: null, // URL to submit value using AJAX
|
1384
|
+
wMinW: 0, // min width of picker
|
1385
|
+
wMinH: 0, // min height of picker
|
1386
|
+
yAhead: null, // years-ahead button
|
1387
|
+
y0XXX: null, // millenium-digit-zero button (for focus)
|
1388
|
+
yCur: null, // current-year button
|
1389
|
+
yDiv: null, // year selector popup
|
1390
|
+
yLab: null, // year label
|
1391
|
+
yNext: null, // next-year button
|
1392
|
+
yPast: null, // years-past button
|
1393
|
+
yPrior: null, // prior-year button
|
1394
|
+
|
1395
|
+
//---------------------------------------------------------------------
|
1396
|
+
// .initialize() initializes the picker instance.
|
1397
|
+
//---------------------------------------------------------------------
|
1398
|
+
|
1399
|
+
initialize: function( id )
|
1400
|
+
{
|
1401
|
+
_this = this;
|
1402
|
+
|
1403
|
+
this.id = 'AnyTime--'+id.replace(/[^-_.A-Za-z0-9]/g,'--AnyTime--');
|
1404
|
+
|
1405
|
+
options = jQuery.extend(true,{},options||{});
|
1406
|
+
options.utcParseOffsetCapture = true;
|
1407
|
+
this.conv = new AnyTime.Converter(options);
|
1408
|
+
|
1409
|
+
if ( options.placement )
|
1410
|
+
{
|
1411
|
+
if ( options.placement == 'inline' )
|
1412
|
+
this.pop = false;
|
1413
|
+
else if ( options.placement != 'popup' )
|
1414
|
+
throw 'unknown placement: ' + options.placement;
|
1415
|
+
}
|
1416
|
+
|
1417
|
+
if ( options.ajaxOptions )
|
1418
|
+
{
|
1419
|
+
this.ajaxOpts = jQuery.extend( {}, options.ajaxOptions );
|
1420
|
+
if ( ! this.ajaxOpts.success )
|
1421
|
+
this.ajaxOpts.success = function(data,status) { _this.inp.val(data); };
|
1422
|
+
}
|
1423
|
+
|
1424
|
+
if ( options.earliest )
|
1425
|
+
{
|
1426
|
+
if ( typeof options.earliest.getTime == 'function' )
|
1427
|
+
this.earliest = options.earliest.getTime();
|
1428
|
+
else
|
1429
|
+
this.earliest = this.conv.parse( options.earliest.toString() );
|
1430
|
+
}
|
1431
|
+
|
1432
|
+
if ( options.firstDOW )
|
1433
|
+
{
|
1434
|
+
if ( ( options.firstDOW < 0 ) || ( options.firstDOW > 6 ) )
|
1435
|
+
throw new Exception('illegal firstDOW: ' + options.firstDOW);
|
1436
|
+
this.fDOW = options.firstDOW;
|
1437
|
+
}
|
1438
|
+
|
1439
|
+
if ( options.latest )
|
1440
|
+
{
|
1441
|
+
if ( typeof options.latest.getTime == 'function' )
|
1442
|
+
this.latest = options.latest.getTime();
|
1443
|
+
else
|
1444
|
+
this.latest = this.conv.parse( options.latest.toString() );
|
1445
|
+
}
|
1446
|
+
|
1447
|
+
this.lX = options.labelDismiss || 'X';
|
1448
|
+
this.lY = options.labelYear || 'Year';
|
1449
|
+
this.lO = options.labelTimeZone || 'Time Zone';
|
1450
|
+
|
1451
|
+
// Infer what we can about what to display from the format.
|
1452
|
+
|
1453
|
+
var i;
|
1454
|
+
var t;
|
1455
|
+
var lab;
|
1456
|
+
var shownFields = 0;
|
1457
|
+
var format = this.conv.fmt;
|
1458
|
+
|
1459
|
+
if ( typeof options.askEra != 'undefined' )
|
1460
|
+
this.askEra = options.askEra;
|
1461
|
+
else
|
1462
|
+
this.askEra = (format.indexOf('%B')>=0) || (format.indexOf('%C')>=0) || (format.indexOf('%E')>=0);
|
1463
|
+
var askYear = (format.indexOf('%Y')>=0) || (format.indexOf('%y')>=0) || (format.indexOf('%Z')>=0) || (format.indexOf('%z')>=0);
|
1464
|
+
var askMonth = (format.indexOf('%b')>=0) || (format.indexOf('%c')>=0) || (format.indexOf('%M')>=0) || (format.indexOf('%m')>=0);
|
1465
|
+
var askDoM = (format.indexOf('%D')>=0) || (format.indexOf('%d')>=0) || (format.indexOf('%e')>=0);
|
1466
|
+
var askDate = askYear || askMonth || askDoM;
|
1467
|
+
this.twelveHr = (format.indexOf('%h')>=0) || (format.indexOf('%I')>=0) || (format.indexOf('%l')>=0) || (format.indexOf('%r')>=0);
|
1468
|
+
var askHour = this.twelveHr || (format.indexOf('%H')>=0) || (format.indexOf('%k')>=0) || (format.indexOf('%T')>=0);
|
1469
|
+
var askMinute = (format.indexOf('%i')>=0) || (format.indexOf('%r')>=0) || (format.indexOf('%T')>=0);
|
1470
|
+
var askSec = ( (format.indexOf('%r')>=0) || (format.indexOf('%S')>=0) || (format.indexOf('%s')>=0) || (format.indexOf('%T')>=0) );
|
1471
|
+
if ( askSec && ( typeof options.askSecond != 'undefined' ) )
|
1472
|
+
askSec = options.askSecond;
|
1473
|
+
var askOff = ( (format.indexOf('%#')>=0) || (format.indexOf('%+')>=0) || (format.indexOf('%-')>=0) || (format.indexOf('%:')>=0) || (format.indexOf('%;')>=0) || (format.indexOf('%<')>=0) || (format.indexOf('%>')>=0) || (format.indexOf('%@')>=0) );
|
1474
|
+
var askTime = askHour || askMinute || askSec || askOff;
|
1475
|
+
|
1476
|
+
if ( askOff )
|
1477
|
+
this.oConv = new AnyTime.Converter( { format: options.formatUtcOffset ||
|
1478
|
+
format.match(/\S*%[-+:;<>#@]\S*/g).join(' ') } );
|
1479
|
+
|
1480
|
+
// Create the picker HTML and add it to the page.
|
1481
|
+
// Popup pickers will be moved to the end of the body
|
1482
|
+
// once the entire page has loaded.
|
1483
|
+
|
1484
|
+
this.inp = $(document.getElementById(id)); // avoids ID-vs-pseudo-selector probs like id="foo:bar"
|
1485
|
+
this.div = $( '<div class="AnyTime-win AnyTime-pkr ui-widget ui-widget-content ui-corner-all" style="width:0;height:0" id="' + this.id + '" aria-live="off"/>' );
|
1486
|
+
this.inp.after(this.div);
|
1487
|
+
this.wMinW = this.div.outerWidth(!$.browser.safari);
|
1488
|
+
this.wMinH = this.div.AnyTime_height(true);
|
1489
|
+
this.hTitle = $( '<h5 class="AnyTime-hdr ui-widget-header ui-corner-top"/>' );
|
1490
|
+
this.div.append( this.hTitle );
|
1491
|
+
this.dB = $( '<div class="AnyTime-body" style="width:0;height:0"/>' );
|
1492
|
+
this.div.append( this.dB );
|
1493
|
+
this.bMinW = this.dB.outerWidth(true);
|
1494
|
+
this.bMinH = this.dB.AnyTime_height(true);
|
1495
|
+
|
1496
|
+
if ( options.hideInput )
|
1497
|
+
this.inp.css({border:0,height:'1px',margin:0,padding:0,width:'1px'});
|
1498
|
+
|
1499
|
+
// Add dismiss box to title (if popup)
|
1500
|
+
|
1501
|
+
t = null;
|
1502
|
+
var xDiv = null;
|
1503
|
+
if ( this.pop )
|
1504
|
+
{
|
1505
|
+
xDiv = $( '<div class="AnyTime-x-btn ui-state-default">'+this.lX+'</div>' );
|
1506
|
+
this.hTitle.append( xDiv );
|
1507
|
+
xDiv.click(function(e){_this.dismiss(e);});
|
1508
|
+
}
|
1509
|
+
|
1510
|
+
// date (calendar) portion
|
1511
|
+
|
1512
|
+
lab = '';
|
1513
|
+
if ( askDate )
|
1514
|
+
{
|
1515
|
+
this.dD = $( '<div class="AnyTime-date" style="width:0;height:0"/>' );
|
1516
|
+
this.dB.append( this.dD );
|
1517
|
+
this.dMinW = this.dD.outerWidth(true);
|
1518
|
+
this.dMinH = this.dD.AnyTime_height(true);
|
1519
|
+
|
1520
|
+
if ( askYear )
|
1521
|
+
{
|
1522
|
+
this.yLab = $('<h6 class="AnyTime-lbl AnyTime-lbl-yr">' + this.lY + '</h6>');
|
1523
|
+
this.dD.append( this.yLab );
|
1524
|
+
|
1525
|
+
this.dY = $( '<ul class="AnyTime-yrs ui-helper-reset" />' );
|
1526
|
+
this.dD.append( this.dY );
|
1527
|
+
|
1528
|
+
this.yPast = this.btn(this.dY,'<',this.newYear,['yrs-past'],'- '+this.lY);
|
1529
|
+
this.yPrior = this.btn(this.dY,'1',this.newYear,['yr-prior'],'-1 '+this.lY);
|
1530
|
+
this.yCur = this.btn(this.dY,'2',this.newYear,['yr-cur'],this.lY);
|
1531
|
+
this.yCur.removeClass('ui-state-default');
|
1532
|
+
this.yCur.addClass('AnyTime-cur-btn ui-state-default ui-state-highlight');
|
1533
|
+
|
1534
|
+
this.yNext = this.btn(this.dY,'3',this.newYear,['yr-next'],'+1 '+this.lY);
|
1535
|
+
this.yAhead = this.btn(this.dY,'>',this.newYear,['yrs-ahead'],'+ '+this.lY);
|
1536
|
+
|
1537
|
+
shownFields++;
|
1538
|
+
|
1539
|
+
} // if ( askYear )
|
1540
|
+
|
1541
|
+
if ( askMonth )
|
1542
|
+
{
|
1543
|
+
lab = options.labelMonth || 'Month';
|
1544
|
+
this.hMo = $( '<h6 class="AnyTime-lbl AnyTime-lbl-month">' + lab + '</h6>' );
|
1545
|
+
this.dD.append( this.hMo );
|
1546
|
+
this.dMo = $('<ul class="AnyTime-mons" />');
|
1547
|
+
this.dD.append(this.dMo);
|
1548
|
+
for ( i = 0 ; i < 12 ; i++ )
|
1549
|
+
{
|
1550
|
+
var mBtn = this.btn( this.dMo, this.conv.mAbbr[i],
|
1551
|
+
function( event )
|
1552
|
+
{
|
1553
|
+
var elem = $(event.target);
|
1554
|
+
if ( elem.hasClass("AnyTime-out-btn") )
|
1555
|
+
return;
|
1556
|
+
var mo = event.target.AnyTime_month;
|
1557
|
+
var t = new Date(this.time.getTime());
|
1558
|
+
if ( t.getDate() > __daysIn[mo] )
|
1559
|
+
t.setDate(__daysIn[mo])
|
1560
|
+
t.setMonth(mo);
|
1561
|
+
this.set(t);
|
1562
|
+
this.upd(elem);
|
1563
|
+
},
|
1564
|
+
['mon','mon'+String(i+1)], lab+' '+this.conv.mNames[i] );
|
1565
|
+
mBtn[0].AnyTime_month = i;
|
1566
|
+
}
|
1567
|
+
shownFields++;
|
1568
|
+
}
|
1569
|
+
|
1570
|
+
if ( askDoM )
|
1571
|
+
{
|
1572
|
+
lab = options.labelDayOfMonth || 'Day of Month';
|
1573
|
+
this.hDoM = $('<h6 class="AnyTime-lbl AnyTime-lbl-dom">' + lab + '</h6>' );
|
1574
|
+
this.dD.append( this.hDoM );
|
1575
|
+
this.dDoM = $( '<table border="0" cellpadding="0" cellspacing="0" class="AnyTime-dom-table"/>' );
|
1576
|
+
this.dD.append( this.dDoM );
|
1577
|
+
t = $( '<thead class="AnyTime-dom-head"/>' );
|
1578
|
+
this.dDoM.append(t);
|
1579
|
+
var tr = $( '<tr class="AnyTime-dow"/>' );
|
1580
|
+
t.append(tr);
|
1581
|
+
for ( i = 0 ; i < 7 ; i++ )
|
1582
|
+
tr.append( '<th class="AnyTime-dow AnyTime-dow'+String(i+1)+'">'+this.conv.dAbbr[(this.fDOW+i)%7]+'</th>' );
|
1583
|
+
|
1584
|
+
var tbody = $( '<tbody class="AnyTime-dom-body" />' );
|
1585
|
+
this.dDoM.append(tbody);
|
1586
|
+
for ( var r = 0 ; r < 6 ; r++ )
|
1587
|
+
{
|
1588
|
+
tr = $( '<tr class="AnyTime-wk AnyTime-wk'+String(r+1)+'"/>' );
|
1589
|
+
tbody.append(tr);
|
1590
|
+
for ( i = 0 ; i < 7 ; i++ )
|
1591
|
+
this.btn( tr, 'x',
|
1592
|
+
function( event )
|
1593
|
+
{
|
1594
|
+
var elem = $(event.target);
|
1595
|
+
if ( elem.hasClass("AnyTime-out-btn") )
|
1596
|
+
return;
|
1597
|
+
var dom = Number(elem.html());
|
1598
|
+
if ( dom )
|
1599
|
+
{
|
1600
|
+
var t = new Date(this.time.getTime());
|
1601
|
+
t.setDate(dom);
|
1602
|
+
this.set(t);
|
1603
|
+
this.upd(elem);
|
1604
|
+
}
|
1605
|
+
},
|
1606
|
+
['dom'], lab );
|
1607
|
+
}
|
1608
|
+
shownFields++;
|
1609
|
+
|
1610
|
+
} // if ( askDoM )
|
1611
|
+
|
1612
|
+
} // if ( askDate )
|
1613
|
+
|
1614
|
+
// time portion
|
1615
|
+
|
1616
|
+
if ( askTime )
|
1617
|
+
{
|
1618
|
+
var tensDiv, onesDiv;
|
1619
|
+
|
1620
|
+
this.dT = $('<div class="AnyTime-time" style="width:0;height:0" />');
|
1621
|
+
this.dB.append(this.dT);
|
1622
|
+
this.tMinW = this.dT.outerWidth(true);
|
1623
|
+
this.tMinH = this.dT.AnyTime_height(true);
|
1624
|
+
|
1625
|
+
if ( askHour )
|
1626
|
+
{
|
1627
|
+
this.dH = $('<div class="AnyTime-hrs"/>');
|
1628
|
+
this.dT.append(this.dH);
|
1629
|
+
|
1630
|
+
lab = options.labelHour || 'Hour';
|
1631
|
+
this.dH.append( $('<h6 class="AnyTime-lbl AnyTime-lbl-hr">'+lab+'</h6>') );
|
1632
|
+
var amDiv = $('<ul class="AnyTime-hrs-am"/>');
|
1633
|
+
this.dH.append( amDiv );
|
1634
|
+
var pmDiv = $('<ul class="AnyTime-hrs-pm"/>');
|
1635
|
+
this.dH.append( pmDiv );
|
1636
|
+
|
1637
|
+
for ( i = 0 ; i < 12 ; i++ )
|
1638
|
+
{
|
1639
|
+
if ( this.twelveHr )
|
1640
|
+
{
|
1641
|
+
if ( i == 0 )
|
1642
|
+
t = '12am';
|
1643
|
+
else
|
1644
|
+
t = String(i)+'am';
|
1645
|
+
}
|
1646
|
+
else
|
1647
|
+
t = AnyTime.pad(i,2);
|
1648
|
+
|
1649
|
+
this.btn( amDiv, t, this.newHour,['hr','hr'+String(i)],lab+' '+t);
|
1650
|
+
|
1651
|
+
if ( this.twelveHr )
|
1652
|
+
{
|
1653
|
+
if ( i == 0 )
|
1654
|
+
t = '12pm';
|
1655
|
+
else
|
1656
|
+
t = String(i)+'pm';
|
1657
|
+
}
|
1658
|
+
else
|
1659
|
+
t = i+12;
|
1660
|
+
|
1661
|
+
this.btn( pmDiv, t, this.newHour,['hr','hr'+String(i+12)],lab+' '+t);
|
1662
|
+
}
|
1663
|
+
|
1664
|
+
shownFields++;
|
1665
|
+
|
1666
|
+
} // if ( askHour )
|
1667
|
+
|
1668
|
+
if ( askMinute )
|
1669
|
+
{
|
1670
|
+
this.dM = $('<div class="AnyTime-mins"/>');
|
1671
|
+
this.dT.append(this.dM);
|
1672
|
+
|
1673
|
+
lab = options.labelMinute || 'Minute';
|
1674
|
+
this.dM.append( $('<h6 class="AnyTime-lbl AnyTime-lbl-min">'+lab+'</h6>') );
|
1675
|
+
tensDiv = $('<ul class="AnyTime-mins-tens"/>');
|
1676
|
+
this.dM.append(tensDiv);
|
1677
|
+
|
1678
|
+
for ( i = 0 ; i < 6 ; i++ )
|
1679
|
+
this.btn( tensDiv, i,
|
1680
|
+
function( event )
|
1681
|
+
{
|
1682
|
+
var elem = $(event.target);
|
1683
|
+
if ( elem.hasClass("AnyTime-out-btn") )
|
1684
|
+
return;
|
1685
|
+
var t = new Date(this.time.getTime());
|
1686
|
+
t.setMinutes( (Number(elem.text())*10) + (this.time.getMinutes()%10) );
|
1687
|
+
this.set(t);
|
1688
|
+
this.upd(elem);
|
1689
|
+
},
|
1690
|
+
['min-ten','min'+i+'0'], lab+' '+i+'0' );
|
1691
|
+
for ( ; i < 12 ; i++ )
|
1692
|
+
this.btn( tensDiv, ' ', $.noop, ['min-ten','min'+i+'0'], lab+' '+i+'0' ).addClass('AnyTime-min-ten-btn-empty ui-state-default ui-state-disabled');
|
1693
|
+
|
1694
|
+
onesDiv = $('<ul class="AnyTime-mins-ones"/>');
|
1695
|
+
this.dM.append(onesDiv);
|
1696
|
+
for ( i = 0 ; i < 10 ; i++ )
|
1697
|
+
this.btn( onesDiv, i,
|
1698
|
+
function( event )
|
1699
|
+
{
|
1700
|
+
var elem = $(event.target);
|
1701
|
+
if ( elem.hasClass("AnyTime-out-btn") )
|
1702
|
+
return;
|
1703
|
+
var t = new Date(this.time.getTime());
|
1704
|
+
t.setMinutes( (Math.floor(this.time.getMinutes()/10)*10)+Number(elem.text()) );
|
1705
|
+
this.set(t);
|
1706
|
+
this.upd(elem);
|
1707
|
+
},
|
1708
|
+
['min-one','min'+i], lab+' '+i );
|
1709
|
+
for ( ; i < 12 ; i++ )
|
1710
|
+
this.btn( onesDiv, ' ', $.noop, ['min-one','min'+i+'0'], lab+' '+i ).addClass('AnyTime-min-one-btn-empty ui-state-default ui-state-disabled');
|
1711
|
+
|
1712
|
+
shownFields++;
|
1713
|
+
|
1714
|
+
} // if ( askMinute )
|
1715
|
+
|
1716
|
+
if ( askSec )
|
1717
|
+
{
|
1718
|
+
this.dS = $('<div class="AnyTime-secs"/>');
|
1719
|
+
this.dT.append(this.dS);
|
1720
|
+
lab = options.labelSecond || 'Second';
|
1721
|
+
this.dS.append( $('<h6 class="AnyTime-lbl AnyTime-lbl-sec">'+lab+'</h6>') );
|
1722
|
+
tensDiv = $('<ul class="AnyTime-secs-tens"/>');
|
1723
|
+
this.dS.append(tensDiv);
|
1724
|
+
|
1725
|
+
for ( i = 0 ; i < 6 ; i++ )
|
1726
|
+
this.btn( tensDiv, i,
|
1727
|
+
function( event )
|
1728
|
+
{
|
1729
|
+
var elem = $(event.target);
|
1730
|
+
if ( elem.hasClass("AnyTime-out-btn") )
|
1731
|
+
return;
|
1732
|
+
var t = new Date(this.time.getTime());
|
1733
|
+
t.setSeconds( (Number(elem.text())*10) + (this.time.getSeconds()%10) );
|
1734
|
+
this.set(t);
|
1735
|
+
this.upd(elem);
|
1736
|
+
},
|
1737
|
+
['sec-ten','sec'+i+'0'], lab+' '+i+'0' );
|
1738
|
+
for ( ; i < 12 ; i++ )
|
1739
|
+
this.btn( tensDiv, ' ', $.noop, ['sec-ten','sec'+i+'0'], lab+' '+i+'0' ).addClass('AnyTime-sec-ten-btn-empty ui-state-default ui-state-disabled');
|
1740
|
+
|
1741
|
+
onesDiv = $('<ul class="AnyTime-secs-ones"/>');
|
1742
|
+
this.dS.append(onesDiv);
|
1743
|
+
for ( i = 0 ; i < 10 ; i++ )
|
1744
|
+
this.btn( onesDiv, i,
|
1745
|
+
function( event )
|
1746
|
+
{
|
1747
|
+
var elem = $(event.target);
|
1748
|
+
if ( elem.hasClass("AnyTime-out-btn") )
|
1749
|
+
return;
|
1750
|
+
var t = new Date(this.time.getTime());
|
1751
|
+
t.setSeconds( (Math.floor(this.time.getSeconds()/10)*10) + Number(elem.text()) );
|
1752
|
+
this.set(t);
|
1753
|
+
this.upd(elem);
|
1754
|
+
},
|
1755
|
+
['sec-one','sec'+i], lab+' '+i );
|
1756
|
+
for ( ; i < 12 ; i++ )
|
1757
|
+
this.btn( onesDiv, ' ', $.noop, ['sec-one','sec'+i+'0'], lab+' '+i ).addClass('AnyTime-sec-one-btn-empty ui-state-default ui-state-disabled');
|
1758
|
+
|
1759
|
+
shownFields++;
|
1760
|
+
|
1761
|
+
} // if ( askSec )
|
1762
|
+
|
1763
|
+
if ( askOff )
|
1764
|
+
{
|
1765
|
+
this.dO = $('<div class="AnyTime-offs" />');
|
1766
|
+
this.dT.append(this.dO);
|
1767
|
+
this.oMinW = this.dO.outerWidth(true);
|
1768
|
+
|
1769
|
+
this.oLab = $('<h6 class="AnyTime-lbl AnyTime-lbl-off">' + this.lO + '</h6>');
|
1770
|
+
this.dO.append( this.oLab );
|
1771
|
+
|
1772
|
+
var offDiv = $('<ul class="AnyTime-off-list ui-helper-reset" />');
|
1773
|
+
this.dO.append(offDiv);
|
1774
|
+
|
1775
|
+
this.oCur = this.btn(offDiv,'',this.newOffset,['off','off-cur'],lab);
|
1776
|
+
this.oCur.removeClass('ui-state-default');
|
1777
|
+
this.oCur.addClass('AnyTime-cur-btn ui-state-default ui-state-highlight');
|
1778
|
+
this.oCur.css({overflow:"hidden"});
|
1779
|
+
|
1780
|
+
this.oSel = this.btn(offDiv,'±',this.newOffset,['off','off-select'],'+/- '+this.lO);
|
1781
|
+
this.oListMinW = this.oCur.outerWidth(true)+this.oSel.outerWidth(true);
|
1782
|
+
|
1783
|
+
shownFields++;
|
1784
|
+
}
|
1785
|
+
|
1786
|
+
} // if ( askTime )
|
1787
|
+
|
1788
|
+
// Set the title. If a title option has been specified, use it.
|
1789
|
+
// Otherwise, determine a worthy title based on which (and how many)
|
1790
|
+
// format fields have been specified.
|
1791
|
+
|
1792
|
+
if ( options.labelTitle )
|
1793
|
+
this.hTitle.append( options.labelTitle );
|
1794
|
+
else if ( shownFields > 1 )
|
1795
|
+
this.hTitle.append( 'Select a '+(askDate?(askTime?'Date and Time':'Date'):'Time') );
|
1796
|
+
else
|
1797
|
+
this.hTitle.append( 'Select' );
|
1798
|
+
|
1799
|
+
|
1800
|
+
// Initialize the picker's date/time value.
|
1801
|
+
|
1802
|
+
try
|
1803
|
+
{
|
1804
|
+
this.time = this.conv.parse(this.inp.val());
|
1805
|
+
this.offMin = this.conv.getUtcParseOffsetCaptured();
|
1806
|
+
this.offSI = this.conv.getUtcParseOffsetSubIndex();
|
1807
|
+
}
|
1808
|
+
catch ( e )
|
1809
|
+
{
|
1810
|
+
this.time = new Date();
|
1811
|
+
}
|
1812
|
+
this.lastAjax = this.time;
|
1813
|
+
|
1814
|
+
|
1815
|
+
// If this is a popup picker, hide it until needed.
|
1816
|
+
|
1817
|
+
if ( this.pop )
|
1818
|
+
{
|
1819
|
+
this.div.hide();
|
1820
|
+
if ( __iframe )
|
1821
|
+
__iframe.hide();
|
1822
|
+
this.div.css('position','absolute');
|
1823
|
+
}
|
1824
|
+
|
1825
|
+
// Setup event listeners for the input and resize listeners for
|
1826
|
+
// the picker. Add the picker to the instances list (which is used
|
1827
|
+
// to hide pickers if the user clicks off of them).
|
1828
|
+
|
1829
|
+
this.inp.blur( this.hBlur =
|
1830
|
+
function(e)
|
1831
|
+
{
|
1832
|
+
_this.inpBlur(e);
|
1833
|
+
} );
|
1834
|
+
|
1835
|
+
this.inp.click( this.hClick =
|
1836
|
+
function(e)
|
1837
|
+
{
|
1838
|
+
_this.showPkr(e);
|
1839
|
+
} );
|
1840
|
+
|
1841
|
+
this.inp.focus( this.hFocus =
|
1842
|
+
function(e)
|
1843
|
+
{
|
1844
|
+
if ( _this.lostFocus )
|
1845
|
+
_this.showPkr(e);
|
1846
|
+
_this.lostFocus = false;
|
1847
|
+
} );
|
1848
|
+
|
1849
|
+
this.inp.keydown( this.hKeydown =
|
1850
|
+
function(e)
|
1851
|
+
{
|
1852
|
+
_this.key(e);
|
1853
|
+
} );
|
1854
|
+
|
1855
|
+
this.inp.keypress( this.hKeypress =
|
1856
|
+
function(e)
|
1857
|
+
{
|
1858
|
+
if ( $.browser.opera && _this.denyTab )
|
1859
|
+
e.preventDefault();
|
1860
|
+
} );
|
1861
|
+
|
1862
|
+
this.div.click(
|
1863
|
+
function(e)
|
1864
|
+
{
|
1865
|
+
_this.lostFocus = false;
|
1866
|
+
_this.inp.focus();
|
1867
|
+
} );
|
1868
|
+
|
1869
|
+
$(window).resize(
|
1870
|
+
function(e)
|
1871
|
+
{
|
1872
|
+
_this.pos(e);
|
1873
|
+
} );
|
1874
|
+
|
1875
|
+
if ( __initialized )
|
1876
|
+
this.onReady();
|
1877
|
+
|
1878
|
+
}, // initialize()
|
1879
|
+
|
1880
|
+
|
1881
|
+
//---------------------------------------------------------------------
|
1882
|
+
// .ajax() notifies the server of a value change using Ajax.
|
1883
|
+
//---------------------------------------------------------------------
|
1884
|
+
|
1885
|
+
ajax: function()
|
1886
|
+
{
|
1887
|
+
if ( this.ajaxOpts && ( this.time.getTime() != this.lastAjax.getTime() ) )
|
1888
|
+
{
|
1889
|
+
try
|
1890
|
+
{
|
1891
|
+
var opts = jQuery.extend( {}, this.ajaxOpts );
|
1892
|
+
if ( typeof opts.data == 'object' )
|
1893
|
+
opts.data[this.inp[0].name||this.inp[0].id] = this.inp.val();
|
1894
|
+
else
|
1895
|
+
{
|
1896
|
+
var opt = (this.inp[0].name||this.inp[0].id) + '=' + encodeURI(this.inp.val());
|
1897
|
+
if ( opts.data )
|
1898
|
+
opts.data += '&' + opt;
|
1899
|
+
else
|
1900
|
+
opts.data = opt;
|
1901
|
+
}
|
1902
|
+
$.ajax( opts );
|
1903
|
+
this.lastAjax = this.time;
|
1904
|
+
}
|
1905
|
+
catch( e )
|
1906
|
+
{
|
1907
|
+
}
|
1908
|
+
}
|
1909
|
+
return;
|
1910
|
+
|
1911
|
+
}, // .ajax()
|
1912
|
+
|
1913
|
+
//---------------------------------------------------------------------
|
1914
|
+
// .askOffset() is called by this.newOffset() when the UTC offset or
|
1915
|
+
// +- selection button is clicked.
|
1916
|
+
//---------------------------------------------------------------------
|
1917
|
+
|
1918
|
+
askOffset: function( event )
|
1919
|
+
{
|
1920
|
+
if ( ! this.oDiv )
|
1921
|
+
{
|
1922
|
+
this.makeCloak();
|
1923
|
+
|
1924
|
+
this.oDiv = $('<div class="AnyTime-win AnyTime-off-selector ui-widget ui-widget-content ui-corner-all" style="position:absolute" />');
|
1925
|
+
this.div.append(this.oDiv);
|
1926
|
+
|
1927
|
+
// the order here (HDR,BODY,XDIV,TITLE) is important for width calcluation:
|
1928
|
+
var title = $('<h5 class="AnyTime-hdr AnyTime-hdr-off-selector ui-widget-header ui-corner-top" />');
|
1929
|
+
this.oDiv.append( title );
|
1930
|
+
this.oBody = $('<div class="AnyTime-body AnyTime-body-off-selector" style="overflow:auto;white-space:nowrap" />');
|
1931
|
+
this.oDiv.append( this.oBody );
|
1932
|
+
var oBHS = this.oBody.AnyTime_height(true); // body spacing
|
1933
|
+
var oBWS = this.oBody.AnyTime_width(true);
|
1934
|
+
var oTWS = title.AnyTime_width(true);
|
1935
|
+
|
1936
|
+
var xDiv = $('<div class="AnyTime-x-btn ui-state-default">'+this.lX+'</div>');
|
1937
|
+
title.append(xDiv);
|
1938
|
+
xDiv.click(function(e){_this.dismissODiv(e);});
|
1939
|
+
title.append( this.lO );
|
1940
|
+
if ( __msie6 || __msie7 ) // IE bugs!
|
1941
|
+
title.width(String(this.lO.length*0.8)+"em");
|
1942
|
+
var oBW = title.AnyTime_width(true) - oBWS; // initial body width
|
1943
|
+
|
1944
|
+
var cont = $('<ul class="AnyTime-off-off" />' );
|
1945
|
+
var last = null;
|
1946
|
+
this.oBody.append(cont);
|
1947
|
+
var useSubIndex = (this.oConv.fmt.indexOf('%@')>=0);
|
1948
|
+
var btnW = 0; // determine uniform button width
|
1949
|
+
if ( AnyTime.utcLabel )
|
1950
|
+
for ( var o = -720 ; o < 720 ; o++ )
|
1951
|
+
if ( AnyTime.utcLabel[o] )
|
1952
|
+
{
|
1953
|
+
this.oConv.setUtcFormatOffsetAlleged(o);
|
1954
|
+
for ( var i = 0; i < AnyTime.utcLabel[o].length; i++ )
|
1955
|
+
{
|
1956
|
+
this.oConv.setUtcFormatOffsetSubIndex(i);
|
1957
|
+
last = this.btn( cont, this.oConv.format(this.time), this.newOPos, ['off-off'], o );
|
1958
|
+
last[0].AnyTime_offMin = o;
|
1959
|
+
last[0].AnyTime_offSI = i;
|
1960
|
+
var w = last.width();
|
1961
|
+
if ( w > btnW )
|
1962
|
+
btnW = w;
|
1963
|
+
if ( ! useSubIndex )
|
1964
|
+
break; // for
|
1965
|
+
}
|
1966
|
+
}
|
1967
|
+
|
1968
|
+
if ( last )
|
1969
|
+
last.addClass('AnyTime-off-off-last-btn');
|
1970
|
+
|
1971
|
+
// compute optimal width
|
1972
|
+
|
1973
|
+
this.oBody.find('.AnyTime-off-off-btn').width(btnW); // set uniform button width
|
1974
|
+
if ( last )
|
1975
|
+
{
|
1976
|
+
var lW = last.AnyTime_width(true);
|
1977
|
+
if ( lW > oBW )
|
1978
|
+
oBW = lW+1; // expand body to hold buttons
|
1979
|
+
}
|
1980
|
+
this.oBody.width(oBW);
|
1981
|
+
oBW = this.oBody.AnyTime_width(true);
|
1982
|
+
this.oDiv.width( oBW );
|
1983
|
+
if ( __msie6 || __msie7 ) // IE bugs!
|
1984
|
+
title.width( oBW - oTWS );
|
1985
|
+
|
1986
|
+
// compute optimal height
|
1987
|
+
|
1988
|
+
var oH = this.oDiv.AnyTime_height(true);
|
1989
|
+
var oHmax = this.div.height() * 0.75;
|
1990
|
+
if ( oH > oHmax )
|
1991
|
+
{
|
1992
|
+
oH = oHmax;
|
1993
|
+
this.oBody.height(oH-(title.AnyTime_height(true)+oBHS));
|
1994
|
+
this.oBody.width(this.oBody.width()+20); // add nominal px for scrollbar
|
1995
|
+
this.oDiv.width(this.oDiv.width()+20);
|
1996
|
+
if ( __msie6 || __msie7 ) // IE bugs!
|
1997
|
+
title.width( this.oBody.AnyTime_width(true) - oTWS );
|
1998
|
+
}
|
1999
|
+
if ( ! __msie7 ) // IE7 bug!
|
2000
|
+
this.oDiv.height(String(oH)+'px');
|
2001
|
+
|
2002
|
+
} // if ( ! this.oDiv )
|
2003
|
+
else
|
2004
|
+
{
|
2005
|
+
this.cloak.show();
|
2006
|
+
this.oDiv.show();
|
2007
|
+
}
|
2008
|
+
this.pos(event);
|
2009
|
+
this.updODiv(null);
|
2010
|
+
|
2011
|
+
var f = this.oDiv.find('.AnyTime-off-off-btn.AnyTime-cur-btn:first');
|
2012
|
+
if ( ! f.length )
|
2013
|
+
f = this.oDiv.find('.AnyTime-off-off-btn:first');
|
2014
|
+
this.setFocus( f );
|
2015
|
+
|
2016
|
+
}, // .askOffset()
|
2017
|
+
|
2018
|
+
//---------------------------------------------------------------------
|
2019
|
+
// .askYear() is called by this.newYear() when the yPast or yAhead
|
2020
|
+
// button is clicked.
|
2021
|
+
//---------------------------------------------------------------------
|
2022
|
+
|
2023
|
+
askYear: function( event )
|
2024
|
+
{
|
2025
|
+
if ( ! this.yDiv )
|
2026
|
+
{
|
2027
|
+
this.makeCloak();
|
2028
|
+
|
2029
|
+
this.yDiv = $('<div class="AnyTime-win AnyTime-yr-selector ui-widget ui-widget-content ui-corner-all" style="position:absolute" />');
|
2030
|
+
this.div.append(this.yDiv);
|
2031
|
+
|
2032
|
+
var title = $('<h5 class="AnyTime-hdr AnyTime-hdr-yr-selector ui-widget-header ui-corner-top" />');
|
2033
|
+
this.yDiv.append( title );
|
2034
|
+
|
2035
|
+
var xDiv = $('<div class="AnyTime-x-btn ui-state-default">'+this.lX+'</div>');
|
2036
|
+
title.append(xDiv);
|
2037
|
+
xDiv.click(function(e){_this.dismissYDiv(e);});
|
2038
|
+
|
2039
|
+
title.append( this.lY );
|
2040
|
+
|
2041
|
+
var yBody = $('<div class="AnyTime-body AnyTime-body-yr-selector" />');
|
2042
|
+
var yW = yBody.AnyTime_width(true);
|
2043
|
+
var yH = 0;
|
2044
|
+
this.yDiv.append( yBody );
|
2045
|
+
|
2046
|
+
cont = $('<ul class="AnyTime-yr-mil" />' );
|
2047
|
+
yBody.append(cont);
|
2048
|
+
this.y0XXX = this.btn( cont, 0, this.newYPos,['mil','mil0'],this.lY+' '+0+'000');
|
2049
|
+
for ( i = 1; i < 10 ; i++ )
|
2050
|
+
this.btn( cont, i, this.newYPos,['mil','mil'+i],this.lY+' '+i+'000');
|
2051
|
+
yW += cont.AnyTime_width(true);
|
2052
|
+
if ( yH < cont.AnyTime_height(true) )
|
2053
|
+
yH = cont.AnyTime_height(true);
|
2054
|
+
|
2055
|
+
cont = $('<ul class="AnyTime-yr-cent" />' );
|
2056
|
+
yBody.append(cont);
|
2057
|
+
for ( i = 0 ; i < 10 ; i++ )
|
2058
|
+
this.btn( cont, i, this.newYPos,['cent','cent'+i],this.lY+' '+i+'00');
|
2059
|
+
yW += cont.AnyTime_width(true);
|
2060
|
+
if ( yH < cont.AnyTime_height(true) )
|
2061
|
+
yH = cont.AnyTime_height(true);
|
2062
|
+
|
2063
|
+
cont = $('<ul class="AnyTime-yr-dec" />');
|
2064
|
+
yBody.append(cont);
|
2065
|
+
for ( i = 0 ; i < 10 ; i++ )
|
2066
|
+
this.btn( cont, i, this.newYPos,['dec','dec'+i],this.lY+' '+i+'0');
|
2067
|
+
yW += cont.AnyTime_width(true);
|
2068
|
+
if ( yH < cont.AnyTime_height(true) )
|
2069
|
+
yH = cont.AnyTime_height(true);
|
2070
|
+
|
2071
|
+
cont = $('<ul class="AnyTime-yr-yr" />');
|
2072
|
+
yBody.append(cont);
|
2073
|
+
for ( i = 0 ; i < 10 ; i++ )
|
2074
|
+
this.btn( cont, i, this.newYPos,['yr','yr'+i],this.lY+' '+i );
|
2075
|
+
yW += cont.AnyTime_width(true);
|
2076
|
+
if ( yH < cont.AnyTime_height(true) )
|
2077
|
+
yH = cont.AnyTime_height(true);
|
2078
|
+
|
2079
|
+
if ( this.askEra )
|
2080
|
+
{
|
2081
|
+
cont = $('<ul class="AnyTime-yr-era" />' );
|
2082
|
+
yBody.append(cont);
|
2083
|
+
|
2084
|
+
this.btn( cont, this.conv.eAbbr[0],
|
2085
|
+
function( event )
|
2086
|
+
{
|
2087
|
+
var t = new Date(this.time.getTime());
|
2088
|
+
var year = t.getFullYear();
|
2089
|
+
if ( year > 0 )
|
2090
|
+
t.setFullYear(0-year);
|
2091
|
+
this.set(t);
|
2092
|
+
this.updYDiv($(event.target));
|
2093
|
+
},
|
2094
|
+
['era','bce'], this.conv.eAbbr[0] );
|
2095
|
+
|
2096
|
+
this.btn( cont, this.conv.eAbbr[1],
|
2097
|
+
function( event )
|
2098
|
+
{
|
2099
|
+
var t = new Date(this.time.getTime());
|
2100
|
+
var year = t.getFullYear();
|
2101
|
+
if ( year < 0 )
|
2102
|
+
t.setFullYear(0-year);
|
2103
|
+
this.set(t);
|
2104
|
+
this.updYDiv($(event.target));
|
2105
|
+
},
|
2106
|
+
['era','ce'], this.conv.eAbbr[1] );
|
2107
|
+
|
2108
|
+
yW += cont.AnyTime_width(true);
|
2109
|
+
if ( yH < cont.AnyTime_height(true) )
|
2110
|
+
yH = cont.AnyTime_height(true);
|
2111
|
+
|
2112
|
+
} // if ( this.askEra )
|
2113
|
+
|
2114
|
+
if ( $.browser.msie ) // IE8+ThemeUI bug!
|
2115
|
+
yW += 1;
|
2116
|
+
else if ( $.browser.safari ) // Safari small-text bug!
|
2117
|
+
yW += 2;
|
2118
|
+
yH += yBody.AnyTime_height(true);
|
2119
|
+
yBody.css('width',String(yW)+'px');
|
2120
|
+
if ( ! __msie7 ) // IE7 bug!
|
2121
|
+
yBody.css('height',String(yH)+'px');
|
2122
|
+
if ( __msie6 || __msie7 ) // IE bugs!
|
2123
|
+
title.width(yBody.outerWidth(true));
|
2124
|
+
yH += title.AnyTime_height(true);
|
2125
|
+
if ( title.AnyTime_width(true) > yW )
|
2126
|
+
yW = title.AnyTime_width(true);
|
2127
|
+
this.yDiv.css('width',String(yW)+'px');
|
2128
|
+
if ( ! __msie7 ) // IE7 bug!
|
2129
|
+
this.yDiv.css('height',String(yH)+'px');
|
2130
|
+
|
2131
|
+
} // if ( ! this.yDiv )
|
2132
|
+
else
|
2133
|
+
{
|
2134
|
+
this.cloak.show();
|
2135
|
+
this.yDiv.show();
|
2136
|
+
}
|
2137
|
+
this.pos(event);
|
2138
|
+
this.updYDiv(null);
|
2139
|
+
this.setFocus( this.yDiv.find('.AnyTime-yr-btn.AnyTime-cur-btn:first') );
|
2140
|
+
|
2141
|
+
}, // .askYear()
|
2142
|
+
|
2143
|
+
//---------------------------------------------------------------------
|
2144
|
+
// .inpBlur() is called when a picker's input loses focus to dismiss
|
2145
|
+
// the popup. A 1/3 second delay is necessary to restore focus if
|
2146
|
+
// the div is clicked (shorter delays don't always work!) To prevent
|
2147
|
+
// problems cause by scrollbar focus (except in FF), focus is
|
2148
|
+
// force-restored if the offset div is visible.
|
2149
|
+
//---------------------------------------------------------------------
|
2150
|
+
|
2151
|
+
inpBlur: function(event)
|
2152
|
+
{
|
2153
|
+
if ( this.oDiv && this.oDiv.is(":visible") )
|
2154
|
+
{
|
2155
|
+
_this.inp.focus();
|
2156
|
+
return;
|
2157
|
+
}
|
2158
|
+
this.lostFocus = true;
|
2159
|
+
setTimeout(
|
2160
|
+
function()
|
2161
|
+
{
|
2162
|
+
if ( _this.lostFocus )
|
2163
|
+
{
|
2164
|
+
_this.div.find('.AnyTime-focus-btn').removeClass('AnyTime-focus-btn ui-state-focus');
|
2165
|
+
if ( _this.pop )
|
2166
|
+
_this.dismiss(event);
|
2167
|
+
else
|
2168
|
+
_this.ajax();
|
2169
|
+
}
|
2170
|
+
}, 334 );
|
2171
|
+
},
|
2172
|
+
|
2173
|
+
//---------------------------------------------------------------------
|
2174
|
+
// .btn() is called by AnyTime.picker() to create a <div> element
|
2175
|
+
// containing an <a> element. The elements are given appropriate
|
2176
|
+
// classes based on the specified "classes" (an array of strings).
|
2177
|
+
// The specified "text" and "title" are used for the <a> element.
|
2178
|
+
// The "handler" is bound to click events for the <div>, which will
|
2179
|
+
// catch bubbling clicks from the <a> as well. The button is
|
2180
|
+
// appended to the specified parent (jQuery), and the <div> jQuery
|
2181
|
+
// is returned.
|
2182
|
+
//---------------------------------------------------------------------
|
2183
|
+
|
2184
|
+
btn: function( parent, text, handler, classes, title )
|
2185
|
+
{
|
2186
|
+
var tagName = ( (parent[0].nodeName.toLowerCase()=='ul')?'li':'td');
|
2187
|
+
var div$ = '<' + tagName +
|
2188
|
+
' class="AnyTime-btn';
|
2189
|
+
for ( var i = 0 ; i < classes.length ; i++ )
|
2190
|
+
div$ += ' AnyTime-' + classes[i] + '-btn';
|
2191
|
+
var div = $( div$ + ' ui-state-default">' + text + '</' + tagName + '>' );
|
2192
|
+
parent.append(div);
|
2193
|
+
div.AnyTime_title = title;
|
2194
|
+
|
2195
|
+
div.click(
|
2196
|
+
function(e)
|
2197
|
+
{
|
2198
|
+
// bind the handler to the picker so "this" is correct
|
2199
|
+
_this.tempFunc = handler;
|
2200
|
+
_this.tempFunc(e);
|
2201
|
+
});
|
2202
|
+
div.dblclick(
|
2203
|
+
function(e)
|
2204
|
+
{
|
2205
|
+
var elem = $(this);
|
2206
|
+
if ( elem.is('.AnyTime-off-off-btn') )
|
2207
|
+
_this.dismissODiv(e);
|
2208
|
+
else if ( elem.is('.AnyTime-mil-btn') || elem.is('.AnyTime-cent-btn') || elem.is('.AnyTime-dec-btn') || elem.is('.AnyTime-yr-btn') || elem.is('.AnyTime-era-btn') )
|
2209
|
+
_this.dismissYDiv(e);
|
2210
|
+
else if ( _this.pop )
|
2211
|
+
_this.dismiss(e);
|
2212
|
+
});
|
2213
|
+
return div;
|
2214
|
+
|
2215
|
+
}, // .btn()
|
2216
|
+
|
2217
|
+
//---------------------------------------------------------------------
|
2218
|
+
// .cleanup() destroys the DOM events and elements associated with
|
2219
|
+
// the picker so it can be deleted.
|
2220
|
+
//---------------------------------------------------------------------
|
2221
|
+
|
2222
|
+
cleanup: function(event)
|
2223
|
+
{
|
2224
|
+
this.inp.unbind('blur',this.hBlur);
|
2225
|
+
this.inp.unbind('click',this.hClick);
|
2226
|
+
this.inp.unbind('focus',this.hFocus);
|
2227
|
+
this.inp.unbind('keydown',this.hKeydown);
|
2228
|
+
this.inp.unbind('keypress',this.hKeypress);
|
2229
|
+
this.div.remove();
|
2230
|
+
},
|
2231
|
+
|
2232
|
+
//---------------------------------------------------------------------
|
2233
|
+
// .dismiss() dismisses a popup picker.
|
2234
|
+
//---------------------------------------------------------------------
|
2235
|
+
|
2236
|
+
dismiss: function(event)
|
2237
|
+
{
|
2238
|
+
this.ajax();
|
2239
|
+
if ( __iframe )
|
2240
|
+
__iframe.hide();
|
2241
|
+
if ( this.yDiv )
|
2242
|
+
this.dismissYDiv();
|
2243
|
+
if ( this.oDiv )
|
2244
|
+
this.dismissODiv();
|
2245
|
+
this.div.hide();
|
2246
|
+
this.lostFocus = true;
|
2247
|
+
},
|
2248
|
+
|
2249
|
+
//---------------------------------------------------------------------
|
2250
|
+
// .dismissODiv() dismisses the UTC offset selector popover.
|
2251
|
+
//---------------------------------------------------------------------
|
2252
|
+
|
2253
|
+
dismissODiv: function(event)
|
2254
|
+
{
|
2255
|
+
this.oDiv.hide();
|
2256
|
+
this.cloak.hide();
|
2257
|
+
this.setFocus(this.oCur);
|
2258
|
+
},
|
2259
|
+
|
2260
|
+
//---------------------------------------------------------------------
|
2261
|
+
// .dismissYDiv() dismisses the date selector popover.
|
2262
|
+
//---------------------------------------------------------------------
|
2263
|
+
|
2264
|
+
dismissYDiv: function(event)
|
2265
|
+
{
|
2266
|
+
this.yDiv.hide();
|
2267
|
+
this.cloak.hide();
|
2268
|
+
this.setFocus(this.yCur);
|
2269
|
+
},
|
2270
|
+
|
2271
|
+
//---------------------------------------------------------------------
|
2272
|
+
// .setFocus() makes a specified psuedo-button appear to get focus.
|
2273
|
+
//---------------------------------------------------------------------
|
2274
|
+
|
2275
|
+
setFocus: function(btn)
|
2276
|
+
{
|
2277
|
+
if ( ! btn.hasClass('AnyTime-focus-btn') )
|
2278
|
+
{
|
2279
|
+
this.div.find('.AnyTime-focus-btn').removeClass('AnyTime-focus-btn ui-state-focus');
|
2280
|
+
this.fBtn = btn;
|
2281
|
+
btn.removeClass('ui-state-default ui-state-highlight');
|
2282
|
+
btn.addClass('AnyTime-focus-btn ui-state-default ui-state-highlight ui-state-focus');
|
2283
|
+
}
|
2284
|
+
if ( btn.hasClass('AnyTime-off-off-btn') )
|
2285
|
+
{
|
2286
|
+
var oBT = this.oBody.offset().top;
|
2287
|
+
var btnT = btn.offset().top;
|
2288
|
+
var btnH = btn.AnyTime_height(true);
|
2289
|
+
if ( btnT - btnH < oBT ) // move a page up
|
2290
|
+
this.oBody.scrollTop( btnT + this.oBody.scrollTop() - ( this.oBody.innerHeight() + oBT ) + ( btnH * 2 ) );
|
2291
|
+
else if ( btnT + btnH > oBT + this.oBody.innerHeight() ) // move a page down
|
2292
|
+
this.oBody.scrollTop( ( btnT + this.oBody.scrollTop() ) - ( oBT + btnH ) );
|
2293
|
+
}
|
2294
|
+
},
|
2295
|
+
|
2296
|
+
//---------------------------------------------------------------------
|
2297
|
+
// .key() is invoked when a user presses a key while the picker's
|
2298
|
+
// input has focus. A psuedo-button is considered "in focus" and an
|
2299
|
+
// appropriate action is performed according to the WAI-ARIA Authoring
|
2300
|
+
// Practices 1.0 for datepicker from
|
2301
|
+
// www.w3.org/TR/2009/WD-wai-aria-practices-20091215/#datepicker:
|
2302
|
+
//
|
2303
|
+
// * LeftArrow moves focus left, continued to previous week.
|
2304
|
+
// * RightArrow moves focus right, continued to next week.
|
2305
|
+
// * UpArrow moves focus to the same weekday in the previous week.
|
2306
|
+
// * DownArrow moves focus to same weekday in the next week.
|
2307
|
+
// * PageUp moves focus to same day in the previous month.
|
2308
|
+
// * PageDown moves focus to same day in the next month.
|
2309
|
+
// * Shift+Page Up moves focus to same day in the previous year.
|
2310
|
+
// * Shift+Page Down moves focus to same day in the next year.
|
2311
|
+
// * Home moves focus to the first day of the month.
|
2312
|
+
// * End moves focus to the last day of the month.
|
2313
|
+
// * Ctrl+Home moves focus to the first day of the year.
|
2314
|
+
// * Ctrl+End moves focus to the last day of the year.
|
2315
|
+
// * Esc closes a DatePicker that is opened as a Popup.
|
2316
|
+
//
|
2317
|
+
// The following actions (for multiple-date selection) are NOT
|
2318
|
+
// supported:
|
2319
|
+
// * Shift+Arrow performs continous selection.
|
2320
|
+
// * Ctrl+Space multiple selection of certain days.
|
2321
|
+
//
|
2322
|
+
// The authoring practices do not specify behavior for a time picker,
|
2323
|
+
// or for month-and-year pickers that do not have a day-of-the-month,
|
2324
|
+
// but AnyTime.picker uses the following behavior to be as consistent
|
2325
|
+
// as possible with the defined datepicker functionality:
|
2326
|
+
// * LeftArrow moves focus left or up to previous value or field.
|
2327
|
+
// * RightArrow moves focus right or down to next value or field.
|
2328
|
+
// * UpArrow moves focus up or left to previous value or field.
|
2329
|
+
// * DownArrow moves focus down or right to next value or field
|
2330
|
+
// * PageUp moves focus to the current value in the previous units
|
2331
|
+
// (for example, from ten-minutes to hours or one-minutes to
|
2332
|
+
// ten-minutes or months to years).
|
2333
|
+
// * PageDown moves focus to the current value in the next units
|
2334
|
+
// (for example, from hours to ten-minutes or ten-minutes to
|
2335
|
+
// one-minutes or years to months).
|
2336
|
+
// * Home moves the focus to the first unit button.
|
2337
|
+
// * End moves the focus to the last unit button.
|
2338
|
+
//
|
2339
|
+
// In addition, Tab and Shift+Tab move between units (including to/
|
2340
|
+
// from the Day-of-Month table) and also in/out of the picker.
|
2341
|
+
//
|
2342
|
+
// Because AnyTime.picker sets a value as soon as the button receives
|
2343
|
+
// focus, SPACE and ENTER are not needed (the WAI-ARIA guidelines use
|
2344
|
+
// them to select a value.
|
2345
|
+
//---------------------------------------------------------------------
|
2346
|
+
|
2347
|
+
key: function(event)
|
2348
|
+
{
|
2349
|
+
var mo;
|
2350
|
+
var t = null;
|
2351
|
+
var elem = this.div.find('.AnyTime-focus-btn');
|
2352
|
+
var key = event.keyCode || event.which;
|
2353
|
+
this.denyTab = true;
|
2354
|
+
|
2355
|
+
if ( key == 16 ) // Shift
|
2356
|
+
{
|
2357
|
+
}
|
2358
|
+
else if ( ( key == 10 ) || ( key == 13 ) || ( key == 27 ) ) // Enter & Esc
|
2359
|
+
{
|
2360
|
+
if ( this.oDiv && this.oDiv.is(':visible') )
|
2361
|
+
this.dismissODiv(event);
|
2362
|
+
else if ( this.yDiv && this.yDiv.is(':visible') )
|
2363
|
+
this.dismissYDiv(event);
|
2364
|
+
else if ( this.pop )
|
2365
|
+
this.dismiss(event);
|
2366
|
+
}
|
2367
|
+
else if ( ( key == 33 ) || ( ( key == 9 ) && event.shiftKey ) ) // PageUp & Shift+Tab
|
2368
|
+
{
|
2369
|
+
if ( this.fBtn.hasClass('AnyTime-off-off-btn') )
|
2370
|
+
{
|
2371
|
+
if ( key == 9 )
|
2372
|
+
this.dismissODiv(event);
|
2373
|
+
}
|
2374
|
+
else if ( this.fBtn.hasClass('AnyTime-mil-btn') )
|
2375
|
+
{
|
2376
|
+
if ( key == 9 )
|
2377
|
+
this.dismissYDiv(event);
|
2378
|
+
}
|
2379
|
+
else if ( this.fBtn.hasClass('AnyTime-cent-btn') )
|
2380
|
+
this.yDiv.find('.AnyTime-mil-btn.AnyTime-cur-btn').triggerHandler('click');
|
2381
|
+
else if ( this.fBtn.hasClass('AnyTime-dec-btn') )
|
2382
|
+
this.yDiv.find('.AnyTime-cent-btn.AnyTime-cur-btn').triggerHandler('click');
|
2383
|
+
else if ( this.fBtn.hasClass('AnyTime-yr-btn') )
|
2384
|
+
this.yDiv.find('.AnyTime-dec-btn.AnyTime-cur-btn').triggerHandler('click');
|
2385
|
+
else if ( this.fBtn.hasClass('AnyTime-era-btn') )
|
2386
|
+
this.yDiv.find('.AnyTime-yr-btn.AnyTime-cur-btn').triggerHandler('click');
|
2387
|
+
else if ( this.fBtn.parents('.AnyTime-yrs').length )
|
2388
|
+
{
|
2389
|
+
if ( key == 9 )
|
2390
|
+
{
|
2391
|
+
this.denyTab = false;
|
2392
|
+
return;
|
2393
|
+
}
|
2394
|
+
}
|
2395
|
+
else if ( this.fBtn.hasClass('AnyTime-mon-btn') )
|
2396
|
+
{
|
2397
|
+
if ( this.dY )
|
2398
|
+
this.yCur.triggerHandler('click');
|
2399
|
+
else if ( key == 9 )
|
2400
|
+
{
|
2401
|
+
this.denyTab = false;
|
2402
|
+
return;
|
2403
|
+
}
|
2404
|
+
}
|
2405
|
+
else if ( this.fBtn.hasClass('AnyTime-dom-btn') )
|
2406
|
+
{
|
2407
|
+
if ( ( key == 9 ) && event.shiftKey ) // Shift+Tab
|
2408
|
+
{
|
2409
|
+
this.denyTab = false;
|
2410
|
+
return;
|
2411
|
+
}
|
2412
|
+
else // PageUp
|
2413
|
+
{
|
2414
|
+
t = new Date(this.time.getTime());
|
2415
|
+
if ( event.shiftKey )
|
2416
|
+
t.setFullYear(t.getFullYear()-1);
|
2417
|
+
else
|
2418
|
+
{
|
2419
|
+
mo = t.getMonth()-1;
|
2420
|
+
if ( t.getDate() > __daysIn[mo] )
|
2421
|
+
t.setDate(__daysIn[mo])
|
2422
|
+
t.setMonth(mo);
|
2423
|
+
}
|
2424
|
+
this.keyDateChange(t);
|
2425
|
+
}
|
2426
|
+
}
|
2427
|
+
else if ( this.fBtn.hasClass('AnyTime-hr-btn') )
|
2428
|
+
{
|
2429
|
+
t = this.dDoM || this.dMo;
|
2430
|
+
if ( t )
|
2431
|
+
t.AnyTime_clickCurrent();
|
2432
|
+
else if ( this.dY )
|
2433
|
+
this.yCur.triggerHandler('click');
|
2434
|
+
else if ( key == 9 )
|
2435
|
+
{
|
2436
|
+
this.denyTab = false;
|
2437
|
+
return;
|
2438
|
+
}
|
2439
|
+
}
|
2440
|
+
else if ( this.fBtn.hasClass('AnyTime-min-ten-btn') )
|
2441
|
+
{
|
2442
|
+
t = this.dH || this.dDoM || this.dMo;
|
2443
|
+
if ( t )
|
2444
|
+
t.AnyTime_clickCurrent();
|
2445
|
+
else if ( this.dY )
|
2446
|
+
this.yCur.triggerHandler('click');
|
2447
|
+
else if ( key == 9 )
|
2448
|
+
{
|
2449
|
+
this.denyTab = false;
|
2450
|
+
return;
|
2451
|
+
}
|
2452
|
+
}
|
2453
|
+
else if ( this.fBtn.hasClass('AnyTime-min-one-btn') )
|
2454
|
+
this.dM.AnyTime_clickCurrent();
|
2455
|
+
else if ( this.fBtn.hasClass('AnyTime-sec-ten-btn') )
|
2456
|
+
{
|
2457
|
+
if ( this.dM )
|
2458
|
+
t = this.dM.find('.AnyTime-mins-ones');
|
2459
|
+
else
|
2460
|
+
t = this.dH || this.dDoM || this.dMo;
|
2461
|
+
if ( t )
|
2462
|
+
t.AnyTime_clickCurrent();
|
2463
|
+
else if ( this.dY )
|
2464
|
+
this.yCur.triggerHandler('click');
|
2465
|
+
else if ( key == 9 )
|
2466
|
+
{
|
2467
|
+
this.denyTab = false;
|
2468
|
+
return;
|
2469
|
+
}
|
2470
|
+
}
|
2471
|
+
else if ( this.fBtn.hasClass('AnyTime-sec-one-btn') )
|
2472
|
+
this.dS.AnyTime_clickCurrent();
|
2473
|
+
else if ( this.fBtn.hasClass('AnyTime-off-btn') )
|
2474
|
+
{
|
2475
|
+
if ( this.dS )
|
2476
|
+
t = this.dS.find('.AnyTime-secs-ones');
|
2477
|
+
else if ( this.dM )
|
2478
|
+
t = this.dM.find('.AnyTime-mins-ones');
|
2479
|
+
else
|
2480
|
+
t = this.dH || this.dDoM || this.dMo;
|
2481
|
+
if ( t )
|
2482
|
+
t.AnyTime_clickCurrent();
|
2483
|
+
else if ( this.dY )
|
2484
|
+
this.yCur.triggerHandler('click');
|
2485
|
+
else if ( key == 9 )
|
2486
|
+
{
|
2487
|
+
this.denyTab = false;
|
2488
|
+
return;
|
2489
|
+
}
|
2490
|
+
}
|
2491
|
+
}
|
2492
|
+
else if ( ( key == 34 ) || ( key == 9 ) ) // PageDown or Tab
|
2493
|
+
{
|
2494
|
+
if ( this.fBtn.hasClass('AnyTime-mil-btn') )
|
2495
|
+
this.yDiv.find('.AnyTime-cent-btn.AnyTime-cur-btn').triggerHandler('click');
|
2496
|
+
else if ( this.fBtn.hasClass('AnyTime-cent-btn') )
|
2497
|
+
this.yDiv.find('.AnyTime-dec-btn.AnyTime-cur-btn').triggerHandler('click');
|
2498
|
+
else if ( this.fBtn.hasClass('AnyTime-dec-btn') )
|
2499
|
+
this.yDiv.find('.AnyTime-yr-btn.AnyTime-cur-btn').triggerHandler('click');
|
2500
|
+
else if ( this.fBtn.hasClass('AnyTime-yr-btn') )
|
2501
|
+
{
|
2502
|
+
t = this.yDiv.find('.AnyTime-era-btn.AnyTime-cur-btn');
|
2503
|
+
if ( t.length )
|
2504
|
+
t.triggerHandler('click');
|
2505
|
+
else if ( key == 9 )
|
2506
|
+
this.dismissYDiv(event);
|
2507
|
+
}
|
2508
|
+
else if ( this.fBtn.hasClass('AnyTime-era-btn') )
|
2509
|
+
{
|
2510
|
+
if ( key == 9 )
|
2511
|
+
this.dismissYDiv(event);
|
2512
|
+
}
|
2513
|
+
else if ( this.fBtn.hasClass('AnyTime-off-off-btn') )
|
2514
|
+
{
|
2515
|
+
if ( key == 9 )
|
2516
|
+
this.dismissODiv(event);
|
2517
|
+
}
|
2518
|
+
else if ( this.fBtn.parents('.AnyTime-yrs').length )
|
2519
|
+
{
|
2520
|
+
t = this.dDoM || this.dMo || this.dH || this.dM || this.dS || this.dO;
|
2521
|
+
if ( t )
|
2522
|
+
t.AnyTime_clickCurrent();
|
2523
|
+
else if ( key == 9 )
|
2524
|
+
{
|
2525
|
+
this.denyTab = false;
|
2526
|
+
return;
|
2527
|
+
}
|
2528
|
+
}
|
2529
|
+
else if ( this.fBtn.hasClass('AnyTime-mon-btn') )
|
2530
|
+
{
|
2531
|
+
t = this.dDoM || this.dH || this.dM || this.dS || this.dO;
|
2532
|
+
if ( t )
|
2533
|
+
t.AnyTime_clickCurrent();
|
2534
|
+
else if ( key == 9 )
|
2535
|
+
{
|
2536
|
+
this.denyTab = false;
|
2537
|
+
return;
|
2538
|
+
}
|
2539
|
+
}
|
2540
|
+
else if ( this.fBtn.hasClass('AnyTime-dom-btn') )
|
2541
|
+
{
|
2542
|
+
if ( key == 9 ) // Tab
|
2543
|
+
{
|
2544
|
+
t = this.dH || this.dM || this.dS || this.dO;
|
2545
|
+
if ( t )
|
2546
|
+
t.AnyTime_clickCurrent();
|
2547
|
+
else
|
2548
|
+
{
|
2549
|
+
this.denyTab = false;
|
2550
|
+
return;
|
2551
|
+
}
|
2552
|
+
}
|
2553
|
+
else // PageDown
|
2554
|
+
{
|
2555
|
+
t = new Date(this.time.getTime());
|
2556
|
+
if ( event.shiftKey )
|
2557
|
+
t.setFullYear(t.getFullYear()+1);
|
2558
|
+
else
|
2559
|
+
{
|
2560
|
+
mo = t.getMonth()+1;
|
2561
|
+
if ( t.getDate() > __daysIn[mo] )
|
2562
|
+
t.setDate(__daysIn[mo])
|
2563
|
+
t.setMonth(mo);
|
2564
|
+
}
|
2565
|
+
this.keyDateChange(t);
|
2566
|
+
}
|
2567
|
+
}
|
2568
|
+
else if ( this.fBtn.hasClass('AnyTime-hr-btn') )
|
2569
|
+
{
|
2570
|
+
t = this.dM || this.dS || this.dO;
|
2571
|
+
if ( t )
|
2572
|
+
t.AnyTime_clickCurrent();
|
2573
|
+
else if ( key == 9 )
|
2574
|
+
{
|
2575
|
+
this.denyTab = false;
|
2576
|
+
return;
|
2577
|
+
}
|
2578
|
+
}
|
2579
|
+
else if ( this.fBtn.hasClass('AnyTime-min-ten-btn') )
|
2580
|
+
this.dM.find('.AnyTime-mins-ones .AnyTime-cur-btn').triggerHandler('click');
|
2581
|
+
else if ( this.fBtn.hasClass('AnyTime-min-one-btn') )
|
2582
|
+
{
|
2583
|
+
t = this.dS || this.dO;
|
2584
|
+
if ( t )
|
2585
|
+
t.AnyTime_clickCurrent();
|
2586
|
+
else if ( key == 9 )
|
2587
|
+
{
|
2588
|
+
this.denyTab = false;
|
2589
|
+
return;
|
2590
|
+
}
|
2591
|
+
}
|
2592
|
+
else if ( this.fBtn.hasClass('AnyTime-sec-ten-btn') )
|
2593
|
+
this.dS.find('.AnyTime-secs-ones .AnyTime-cur-btn').triggerHandler('click');
|
2594
|
+
else if ( this.fBtn.hasClass('AnyTime-sec-one-btn') )
|
2595
|
+
{
|
2596
|
+
if ( this.dO )
|
2597
|
+
this.dO.AnyTime_clickCurrent();
|
2598
|
+
else if ( key == 9 )
|
2599
|
+
{
|
2600
|
+
this.denyTab = false;
|
2601
|
+
return;
|
2602
|
+
}
|
2603
|
+
}
|
2604
|
+
else if ( this.fBtn.hasClass('AnyTime-off-btn') )
|
2605
|
+
{
|
2606
|
+
if ( key == 9 )
|
2607
|
+
{
|
2608
|
+
this.denyTab = false;
|
2609
|
+
return;
|
2610
|
+
}
|
2611
|
+
}
|
2612
|
+
}
|
2613
|
+
else if ( key == 35 ) // END
|
2614
|
+
{
|
2615
|
+
if ( this.fBtn.hasClass('AnyTime-mil-btn') || this.fBtn.hasClass('AnyTime-cent-btn') ||
|
2616
|
+
this.fBtn.hasClass('AnyTime-dec-btn') || this.fBtn.hasClass('AnyTime-yr-btn') ||
|
2617
|
+
this.fBtn.hasClass('AnyTime-era-btn') )
|
2618
|
+
{
|
2619
|
+
t = this.yDiv.find('.AnyTime-ce-btn');
|
2620
|
+
if ( ! t.length )
|
2621
|
+
t = this.yDiv.find('.AnyTime-yr9-btn');
|
2622
|
+
t.triggerHandler('click');
|
2623
|
+
}
|
2624
|
+
else if ( this.fBtn.hasClass('AnyTime-dom-btn') )
|
2625
|
+
{
|
2626
|
+
t = new Date(this.time.getTime());
|
2627
|
+
t.setDate(1);
|
2628
|
+
t.setMonth(t.getMonth()+1);
|
2629
|
+
t.setDate(t.getDate()-1);
|
2630
|
+
if ( event.ctrlKey )
|
2631
|
+
t.setMonth(11);
|
2632
|
+
this.keyDateChange(t);
|
2633
|
+
}
|
2634
|
+
else if ( this.dS )
|
2635
|
+
this.dS.find('.AnyTime-sec9-btn').triggerHandler('click');
|
2636
|
+
else if ( this.dM )
|
2637
|
+
this.dM.find('.AnyTime-min9-btn').triggerHandler('click');
|
2638
|
+
else if ( this.dH )
|
2639
|
+
this.dH.find('.AnyTime-hr23-btn').triggerHandler('click');
|
2640
|
+
else if ( this.dDoM )
|
2641
|
+
this.dDoM.find('.AnyTime-dom-btn-filled:last').triggerHandler('click');
|
2642
|
+
else if ( this.dMo )
|
2643
|
+
this.dMo.find('.AnyTime-mon12-btn').triggerHandler('click');
|
2644
|
+
else if ( this.dY )
|
2645
|
+
this.yAhead.triggerHandler('click');
|
2646
|
+
}
|
2647
|
+
else if ( key == 36 ) // HOME
|
2648
|
+
{
|
2649
|
+
if ( this.fBtn.hasClass('AnyTime-mil-btn') || this.fBtn.hasClass('AnyTime-cent-btn') ||
|
2650
|
+
this.fBtn.hasClass('AnyTime-dec-btn') || this.fBtn.hasClass('AnyTime-yr-btn') ||
|
2651
|
+
this.fBtn.hasClass('AnyTime-era-btn') )
|
2652
|
+
{
|
2653
|
+
this.yDiv.find('.AnyTime-mil0-btn').triggerHandler('click');
|
2654
|
+
}
|
2655
|
+
else if ( this.fBtn.hasClass('AnyTime-dom-btn') )
|
2656
|
+
{
|
2657
|
+
t = new Date(this.time.getTime());
|
2658
|
+
t.setDate(1);
|
2659
|
+
if ( event.ctrlKey )
|
2660
|
+
t.setMonth(0);
|
2661
|
+
this.keyDateChange(t);
|
2662
|
+
}
|
2663
|
+
else if ( this.dY )
|
2664
|
+
this.yCur.triggerHandler('click');
|
2665
|
+
else if ( this.dMo )
|
2666
|
+
this.dMo.find('.AnyTime-mon1-btn').triggerHandler('click');
|
2667
|
+
else if ( this.dDoM )
|
2668
|
+
this.dDoM.find('.AnyTime-dom-btn-filled:first').triggerHandler('click');
|
2669
|
+
else if ( this.dH )
|
2670
|
+
this.dH.find('.AnyTime-hr0-btn').triggerHandler('click');
|
2671
|
+
else if ( this.dM )
|
2672
|
+
this.dM.find('.AnyTime-min00-btn').triggerHandler('click');
|
2673
|
+
else if ( this.dS )
|
2674
|
+
this.dS.find('.AnyTime-sec00-btn').triggerHandler('click');
|
2675
|
+
}
|
2676
|
+
else if ( key == 37 ) // left arrow
|
2677
|
+
{
|
2678
|
+
if ( this.fBtn.hasClass('AnyTime-dom-btn') )
|
2679
|
+
this.keyDateChange(new Date(this.time.getTime()-__oneDay));
|
2680
|
+
else
|
2681
|
+
this.keyBack();
|
2682
|
+
}
|
2683
|
+
else if ( key == 38 ) // up arrow
|
2684
|
+
{
|
2685
|
+
if ( this.fBtn.hasClass('AnyTime-dom-btn') )
|
2686
|
+
this.keyDateChange(new Date(this.time.getTime()-(7*__oneDay)));
|
2687
|
+
else
|
2688
|
+
this.keyBack();
|
2689
|
+
}
|
2690
|
+
else if ( key == 39 ) // right arrow
|
2691
|
+
{
|
2692
|
+
if ( this.fBtn.hasClass('AnyTime-dom-btn') )
|
2693
|
+
this.keyDateChange(new Date(this.time.getTime()+__oneDay));
|
2694
|
+
else
|
2695
|
+
this.keyAhead();
|
2696
|
+
}
|
2697
|
+
else if ( key == 40 ) // down arrow
|
2698
|
+
{
|
2699
|
+
if ( this.fBtn.hasClass('AnyTime-dom-btn') )
|
2700
|
+
this.keyDateChange(new Date(this.time.getTime()+(7*__oneDay)));
|
2701
|
+
else
|
2702
|
+
this.keyAhead();
|
2703
|
+
}
|
2704
|
+
else if ( ( ( key == 86 ) || ( key == 118 ) ) && event.ctrlKey )
|
2705
|
+
{
|
2706
|
+
this.inp.val("").change();
|
2707
|
+
var _this = this;
|
2708
|
+
setTimeout( function() { _this.showPkr(null); }, 100 );
|
2709
|
+
return;
|
2710
|
+
}
|
2711
|
+
else
|
2712
|
+
this.showPkr(null);
|
2713
|
+
|
2714
|
+
event.preventDefault();
|
2715
|
+
|
2716
|
+
}, // .key()
|
2717
|
+
|
2718
|
+
//---------------------------------------------------------------------
|
2719
|
+
// .keyAhead() is called by #key when a user presses the right or
|
2720
|
+
// down arrow. It moves to the next appropriate button.
|
2721
|
+
//---------------------------------------------------------------------
|
2722
|
+
|
2723
|
+
keyAhead: function()
|
2724
|
+
{
|
2725
|
+
if ( this.fBtn.hasClass('AnyTime-mil9-btn') )
|
2726
|
+
this.yDiv.find('.AnyTime-cent0-btn').triggerHandler('click');
|
2727
|
+
else if ( this.fBtn.hasClass('AnyTime-cent9-btn') )
|
2728
|
+
this.yDiv.find('.AnyTime-dec0-btn').triggerHandler('click');
|
2729
|
+
else if ( this.fBtn.hasClass('AnyTime-dec9-btn') )
|
2730
|
+
this.yDiv.find('.AnyTime-yr0-btn').triggerHandler('click');
|
2731
|
+
else if ( this.fBtn.hasClass('AnyTime-yr9-btn') )
|
2732
|
+
this.yDiv.find('.AnyTime-bce-btn').triggerHandler('click');
|
2733
|
+
else if ( this.fBtn.hasClass('AnyTime-sec9-btn') )
|
2734
|
+
{}
|
2735
|
+
else if ( this.fBtn.hasClass('AnyTime-sec50-btn') )
|
2736
|
+
this.dS.find('.AnyTime-sec0-btn').triggerHandler('click');
|
2737
|
+
else if ( this.fBtn.hasClass('AnyTime-min9-btn') )
|
2738
|
+
{
|
2739
|
+
if ( this.dS )
|
2740
|
+
this.dS.find('.AnyTime-sec00-btn').triggerHandler('click');
|
2741
|
+
}
|
2742
|
+
else if ( this.fBtn.hasClass('AnyTime-min50-btn') )
|
2743
|
+
this.dM.find('.AnyTime-min0-btn').triggerHandler('click');
|
2744
|
+
else if ( this.fBtn.hasClass('AnyTime-hr23-btn') )
|
2745
|
+
{
|
2746
|
+
if ( this.dM )
|
2747
|
+
this.dM.find('.AnyTime-min00-btn').triggerHandler('click');
|
2748
|
+
else if ( this.dS )
|
2749
|
+
this.dS.find('.AnyTime-sec00-btn').triggerHandler('click');
|
2750
|
+
}
|
2751
|
+
else if ( this.fBtn.hasClass('AnyTime-hr11-btn') )
|
2752
|
+
this.dH.find('.AnyTime-hr12-btn').triggerHandler('click');
|
2753
|
+
else if ( this.fBtn.hasClass('AnyTime-mon12-btn') )
|
2754
|
+
{
|
2755
|
+
if ( this.dDoM )
|
2756
|
+
this.dDoM.AnyTime_clickCurrent();
|
2757
|
+
else if ( this.dH )
|
2758
|
+
this.dH.find('.AnyTime-hr0-btn').triggerHandler('click');
|
2759
|
+
else if ( this.dM )
|
2760
|
+
this.dM.find('.AnyTime-min00-btn').triggerHandler('click');
|
2761
|
+
else if ( this.dS )
|
2762
|
+
this.dS.find('.AnyTime-sec00-btn').triggerHandler('click');
|
2763
|
+
}
|
2764
|
+
else if ( this.fBtn.hasClass('AnyTime-yrs-ahead-btn') )
|
2765
|
+
{
|
2766
|
+
if ( this.dMo )
|
2767
|
+
this.dMo.find('.AnyTime-mon1-btn').triggerHandler('click');
|
2768
|
+
else if ( this.dH )
|
2769
|
+
this.dH.find('.AnyTime-hr0-btn').triggerHandler('click');
|
2770
|
+
else if ( this.dM )
|
2771
|
+
this.dM.find('.AnyTime-min00-btn').triggerHandler('click');
|
2772
|
+
else if ( this.dS )
|
2773
|
+
this.dS.find('.AnyTime-sec00-btn').triggerHandler('click');
|
2774
|
+
}
|
2775
|
+
else if ( this.fBtn.hasClass('AnyTime-yr-cur-btn') )
|
2776
|
+
this.yNext.triggerHandler('click');
|
2777
|
+
else
|
2778
|
+
this.fBtn.next().triggerHandler('click');
|
2779
|
+
|
2780
|
+
}, // .keyAhead()
|
2781
|
+
|
2782
|
+
|
2783
|
+
//---------------------------------------------------------------------
|
2784
|
+
// .keyBack() is called by #key when a user presses the left or
|
2785
|
+
// up arrow. It moves to the previous appropriate button.
|
2786
|
+
//---------------------------------------------------------------------
|
2787
|
+
|
2788
|
+
keyBack: function()
|
2789
|
+
{
|
2790
|
+
if ( this.fBtn.hasClass('AnyTime-cent0-btn') )
|
2791
|
+
this.yDiv.find('.AnyTime-mil9-btn').triggerHandler('click');
|
2792
|
+
else if ( this.fBtn.hasClass('AnyTime-dec0-btn') )
|
2793
|
+
this.yDiv.find('.AnyTime-cent9-btn').triggerHandler('click');
|
2794
|
+
else if ( this.fBtn.hasClass('AnyTime-yr0-btn') )
|
2795
|
+
this.yDiv.find('.AnyTime-dec9-btn').triggerHandler('click');
|
2796
|
+
else if ( this.fBtn.hasClass('AnyTime-bce-btn') )
|
2797
|
+
this.yDiv.find('.AnyTime-yr9-btn').triggerHandler('click');
|
2798
|
+
else if ( this.fBtn.hasClass('AnyTime-yr-cur-btn') )
|
2799
|
+
this.yPrior.triggerHandler('click');
|
2800
|
+
else if ( this.fBtn.hasClass('AnyTime-mon1-btn') )
|
2801
|
+
{
|
2802
|
+
if ( this.dY )
|
2803
|
+
this.yCur.triggerHandler('click');
|
2804
|
+
}
|
2805
|
+
else if ( this.fBtn.hasClass('AnyTime-hr0-btn') )
|
2806
|
+
{
|
2807
|
+
if ( this.dDoM )
|
2808
|
+
this.dDoM.AnyTime_clickCurrent();
|
2809
|
+
else if ( this.dMo )
|
2810
|
+
this.dMo.find('.AnyTime-mon12-btn').triggerHandler('click');
|
2811
|
+
else if ( this.dY )
|
2812
|
+
this.yNext.triggerHandler('click');
|
2813
|
+
}
|
2814
|
+
else if ( this.fBtn.hasClass('AnyTime-hr12-btn') )
|
2815
|
+
this.dH.find('.AnyTime-hr11-btn').triggerHandler('click');
|
2816
|
+
else if ( this.fBtn.hasClass('AnyTime-min00-btn') )
|
2817
|
+
{
|
2818
|
+
if ( this.dH )
|
2819
|
+
this.dH.find('.AnyTime-hr23-btn').triggerHandler('click');
|
2820
|
+
else if ( this.dDoM )
|
2821
|
+
this.dDoM.AnyTime_clickCurrent();
|
2822
|
+
else if ( this.dMo )
|
2823
|
+
this.dMo.find('.AnyTime-mon12-btn').triggerHandler('click');
|
2824
|
+
else if ( this.dY )
|
2825
|
+
this.yNext.triggerHandler('click');
|
2826
|
+
}
|
2827
|
+
else if ( this.fBtn.hasClass('AnyTime-min0-btn') )
|
2828
|
+
this.dM.find('.AnyTime-min50-btn').triggerHandler('click');
|
2829
|
+
else if ( this.fBtn.hasClass('AnyTime-sec00-btn') )
|
2830
|
+
{
|
2831
|
+
if ( this.dM )
|
2832
|
+
this.dM.find('.AnyTime-min9-btn').triggerHandler('click');
|
2833
|
+
else if ( this.dH )
|
2834
|
+
this.dH.find('.AnyTime-hr23-btn').triggerHandler('click');
|
2835
|
+
else if ( this.dDoM )
|
2836
|
+
this.dDoM.AnyTime_clickCurrent();
|
2837
|
+
else if ( this.dMo )
|
2838
|
+
this.dMo.find('.AnyTime-mon12-btn').triggerHandler('click');
|
2839
|
+
else if ( this.dY )
|
2840
|
+
this.yNext.triggerHandler('click');
|
2841
|
+
}
|
2842
|
+
else if ( this.fBtn.hasClass('AnyTime-sec0-btn') )
|
2843
|
+
this.dS.find('.AnyTime-sec50-btn').triggerHandler('click');
|
2844
|
+
else
|
2845
|
+
this.fBtn.prev().triggerHandler('click');
|
2846
|
+
|
2847
|
+
}, // .keyBack()
|
2848
|
+
|
2849
|
+
//---------------------------------------------------------------------
|
2850
|
+
// .keyDateChange() is called by #key when an direction key
|
2851
|
+
// (arrows/page/etc) is pressed while the Day-of-Month calendar has
|
2852
|
+
// focus. The current day is adjusted accordingly.
|
2853
|
+
//---------------------------------------------------------------------
|
2854
|
+
|
2855
|
+
keyDateChange: function( newDate )
|
2856
|
+
{
|
2857
|
+
if ( this.fBtn.hasClass('AnyTime-dom-btn') )
|
2858
|
+
{
|
2859
|
+
this.set(newDate);
|
2860
|
+
this.upd(null);
|
2861
|
+
this.setFocus( this.dDoM.find('.AnyTime-cur-btn') );
|
2862
|
+
}
|
2863
|
+
},
|
2864
|
+
|
2865
|
+
//---------------------------------------------------------------------
|
2866
|
+
// .makeCloak() is called by .askOffset() and .askYear() to create
|
2867
|
+
// a cloak div.
|
2868
|
+
//---------------------------------------------------------------------
|
2869
|
+
|
2870
|
+
makeCloak: function()
|
2871
|
+
{
|
2872
|
+
if ( ! this.cloak )
|
2873
|
+
{
|
2874
|
+
this.cloak = $('<div class="AnyTime-cloak" style="position:absolute" />');
|
2875
|
+
this.div.append( this.cloak );
|
2876
|
+
this.cloak.click(
|
2877
|
+
function(e)
|
2878
|
+
{
|
2879
|
+
if ( _this.oDiv && _this.oDiv.is(":visible") )
|
2880
|
+
_this.dismissODiv(e);
|
2881
|
+
else
|
2882
|
+
_this.dismissYDiv(e);
|
2883
|
+
});
|
2884
|
+
}
|
2885
|
+
else
|
2886
|
+
this.cloak.show();
|
2887
|
+
},
|
2888
|
+
|
2889
|
+
//---------------------------------------------------------------------
|
2890
|
+
// .newHour() is called when a user clicks an hour value.
|
2891
|
+
// It changes the date and updates the text field.
|
2892
|
+
//---------------------------------------------------------------------
|
2893
|
+
|
2894
|
+
newHour: function( event )
|
2895
|
+
{
|
2896
|
+
var h;
|
2897
|
+
var t;
|
2898
|
+
var elem = $(event.target);
|
2899
|
+
if ( elem.hasClass("AnyTime-out-btn") )
|
2900
|
+
return;
|
2901
|
+
if ( ! this.twelveHr )
|
2902
|
+
h = Number(elem.text());
|
2903
|
+
else
|
2904
|
+
{
|
2905
|
+
var str = elem.text();
|
2906
|
+
t = str.indexOf('a');
|
2907
|
+
if ( t < 0 )
|
2908
|
+
{
|
2909
|
+
t = Number(str.substr(0,str.indexOf('p')));
|
2910
|
+
h = ( (t==12) ? 12 : (t+12) );
|
2911
|
+
}
|
2912
|
+
else
|
2913
|
+
{
|
2914
|
+
t = Number(str.substr(0,t));
|
2915
|
+
h = ( (t==12) ? 0 : t );
|
2916
|
+
}
|
2917
|
+
}
|
2918
|
+
t = new Date(this.time.getTime());
|
2919
|
+
t.setHours(h);
|
2920
|
+
this.set(t);
|
2921
|
+
this.upd(elem);
|
2922
|
+
|
2923
|
+
}, // .newHour()
|
2924
|
+
|
2925
|
+
//---------------------------------------------------------------------
|
2926
|
+
// .newOffset() is called when a user clicks the UTC offset (timezone)
|
2927
|
+
// (or +/- button) to shift the year. It changes the date and updates
|
2928
|
+
// the text field.
|
2929
|
+
//---------------------------------------------------------------------
|
2930
|
+
|
2931
|
+
newOffset: function( event )
|
2932
|
+
{
|
2933
|
+
if ( event.target == this.oSel[0] )
|
2934
|
+
this.askOffset(event);
|
2935
|
+
else
|
2936
|
+
{
|
2937
|
+
this.upd(this.oCur);
|
2938
|
+
}
|
2939
|
+
},
|
2940
|
+
|
2941
|
+
//---------------------------------------------------------------------
|
2942
|
+
// .newOPos() is called internally whenever a user clicks an offset
|
2943
|
+
// selection value. It changes the date and updates the text field.
|
2944
|
+
//---------------------------------------------------------------------
|
2945
|
+
|
2946
|
+
newOPos: function( event )
|
2947
|
+
{
|
2948
|
+
var elem = $(event.target);
|
2949
|
+
this.offMin = elem[0].AnyTime_offMin;
|
2950
|
+
this.offSI = elem[0].AnyTime_offSI;
|
2951
|
+
var t = new Date(this.time.getTime());
|
2952
|
+
this.set(t);
|
2953
|
+
this.updODiv(elem);
|
2954
|
+
|
2955
|
+
}, // .newOPos()
|
2956
|
+
|
2957
|
+
//---------------------------------------------------------------------
|
2958
|
+
// .newYear() is called when a user clicks a year (or one of the
|
2959
|
+
// "arrows") to shift the year. It changes the date and updates the
|
2960
|
+
// text field.
|
2961
|
+
//---------------------------------------------------------------------
|
2962
|
+
|
2963
|
+
newYear: function( event )
|
2964
|
+
{
|
2965
|
+
var elem = $(event.target);
|
2966
|
+
if ( elem.hasClass("AnyTime-out-btn") )
|
2967
|
+
return;
|
2968
|
+
var txt = elem.text();
|
2969
|
+
if ( ( txt == '<' ) || ( txt == '<' ) )
|
2970
|
+
this.askYear(event);
|
2971
|
+
else if ( ( txt == '>' ) || ( txt == '>' ) )
|
2972
|
+
this.askYear(event);
|
2973
|
+
else
|
2974
|
+
{
|
2975
|
+
var t = new Date(this.time.getTime());
|
2976
|
+
t.setFullYear(Number(txt));
|
2977
|
+
this.set(t);
|
2978
|
+
this.upd(this.yCur);
|
2979
|
+
}
|
2980
|
+
},
|
2981
|
+
|
2982
|
+
//---------------------------------------------------------------------
|
2983
|
+
// .newYPos() is called internally whenever a user clicks a year
|
2984
|
+
// selection value. It changes the date and updates the text field.
|
2985
|
+
//---------------------------------------------------------------------
|
2986
|
+
|
2987
|
+
newYPos: function( event )
|
2988
|
+
{
|
2989
|
+
var elem = $(event.target);
|
2990
|
+
if ( elem.hasClass("AnyTime-out-btn") )
|
2991
|
+
return;
|
2992
|
+
|
2993
|
+
var era = 1;
|
2994
|
+
var year = this.time.getFullYear();
|
2995
|
+
if ( year < 0 )
|
2996
|
+
{
|
2997
|
+
era = (-1);
|
2998
|
+
year = 0 - year;
|
2999
|
+
}
|
3000
|
+
year = AnyTime.pad( year, 4 );
|
3001
|
+
if ( elem.hasClass('AnyTime-mil-btn') )
|
3002
|
+
year = elem.html() + year.substring(1,4);
|
3003
|
+
else if ( elem.hasClass('AnyTime-cent-btn') )
|
3004
|
+
year = year.substring(0,1) + elem.html() + year.substring(2,4);
|
3005
|
+
else if ( elem.hasClass('AnyTime-dec-btn') )
|
3006
|
+
year = year.substring(0,2) + elem.html() + year.substring(3,4);
|
3007
|
+
else
|
3008
|
+
year = year.substring(0,3) + elem.html();
|
3009
|
+
if ( year == '0000' )
|
3010
|
+
year = 1;
|
3011
|
+
var t = new Date(this.time.getTime());
|
3012
|
+
t.setFullYear( era * year );
|
3013
|
+
this.set(t);
|
3014
|
+
this.updYDiv(elem);
|
3015
|
+
|
3016
|
+
}, // .newYPos()
|
3017
|
+
|
3018
|
+
//---------------------------------------------------------------------
|
3019
|
+
// .onReady() initializes the picker after the page has loaded and,
|
3020
|
+
// if IE6, after the iframe has been created.
|
3021
|
+
//---------------------------------------------------------------------
|
3022
|
+
|
3023
|
+
onReady: function()
|
3024
|
+
{
|
3025
|
+
this.lostFocus = true;
|
3026
|
+
if ( ! this.pop )
|
3027
|
+
this.upd(null);
|
3028
|
+
else
|
3029
|
+
{
|
3030
|
+
if ( this.div.parent() != document.body )
|
3031
|
+
this.div.appendTo( document.body );
|
3032
|
+
}
|
3033
|
+
},
|
3034
|
+
|
3035
|
+
//---------------------------------------------------------------------
|
3036
|
+
// .pos() positions the picker, such as when it is displayed or
|
3037
|
+
// when the window is resized.
|
3038
|
+
//---------------------------------------------------------------------
|
3039
|
+
|
3040
|
+
pos: function(event) // note: event is ignored but this is a handler
|
3041
|
+
{
|
3042
|
+
if ( this.pop )
|
3043
|
+
{
|
3044
|
+
var off = this.inp.offset();
|
3045
|
+
var bodyWidth = $(document.body).outerWidth(true);
|
3046
|
+
var pickerWidth = this.div.outerWidth(true);
|
3047
|
+
var left = off.left;
|
3048
|
+
if ( left + pickerWidth > bodyWidth - 20 )
|
3049
|
+
left = bodyWidth - ( pickerWidth + 20 );
|
3050
|
+
var top = off.top - this.div.outerHeight(true);
|
3051
|
+
if ( top < 0 )
|
3052
|
+
top = off.top + this.inp.outerHeight(true);
|
3053
|
+
this.div.css( { top: String(top)+'px', left: String(left<0?0:left)+'px' } );
|
3054
|
+
}
|
3055
|
+
|
3056
|
+
var wOff = this.div.offset();
|
3057
|
+
|
3058
|
+
if ( this.oDiv && this.oDiv.is(":visible") )
|
3059
|
+
{
|
3060
|
+
var oOff = this.oLab.offset();
|
3061
|
+
if ( this.div.css('position') == 'absolute' )
|
3062
|
+
{
|
3063
|
+
oOff.top -= wOff.top;
|
3064
|
+
oOff.left = oOff.left - wOff.left;
|
3065
|
+
wOff = { top: 0, left: 0 };
|
3066
|
+
}
|
3067
|
+
var oW = this.oDiv.AnyTime_width(true);
|
3068
|
+
var wW = this.div.AnyTime_width(true);
|
3069
|
+
if ( oOff.left + oW > wOff.left + wW )
|
3070
|
+
{
|
3071
|
+
oOff.left = (wOff.left+wW)-oW;
|
3072
|
+
if ( oOff.left < 2 )
|
3073
|
+
oOff.left = 2;
|
3074
|
+
}
|
3075
|
+
|
3076
|
+
var oH = this.oDiv.AnyTime_height(true);
|
3077
|
+
var wH = this.div.AnyTime_height(true);
|
3078
|
+
oOff.top += this.oLab.AnyTime_height(true);
|
3079
|
+
if ( oOff.top + oH > wOff.top + wH )
|
3080
|
+
oOff.top = oOff.top - oH;
|
3081
|
+
if ( oOff.top < wOff.top )
|
3082
|
+
oOff.top = wOff.top;
|
3083
|
+
|
3084
|
+
this.oDiv.css( { top: oOff.top+'px', left: oOff.left+'px' } ) ;
|
3085
|
+
}
|
3086
|
+
|
3087
|
+
else if ( this.yDiv && this.yDiv.is(":visible") )
|
3088
|
+
{
|
3089
|
+
var yOff = this.yLab.offset();
|
3090
|
+
if ( this.div.css('position') == 'absolute' )
|
3091
|
+
{
|
3092
|
+
yOff.top -= wOff.top;
|
3093
|
+
yOff.left = yOff.left - wOff.left;
|
3094
|
+
wOff = { top: 0, left: 0 };
|
3095
|
+
}
|
3096
|
+
yOff.left += ( (this.yLab.outerWidth(true)-this.yDiv.outerWidth(true)) / 2 );
|
3097
|
+
this.yDiv.css( { top: yOff.top+'px', left: yOff.left+'px' } ) ;
|
3098
|
+
}
|
3099
|
+
|
3100
|
+
if ( this.cloak )
|
3101
|
+
this.cloak.css( {
|
3102
|
+
top: wOff.top+'px',
|
3103
|
+
left: wOff.left+'px',
|
3104
|
+
height: String(this.div.outerHeight(true)-2)+'px',
|
3105
|
+
width: String(this.div.outerWidth(!$.browser.safari)-2)+'px'
|
3106
|
+
} );
|
3107
|
+
|
3108
|
+
}, // .pos()
|
3109
|
+
|
3110
|
+
//---------------------------------------------------------------------
|
3111
|
+
// .set() changes the current time. It returns true if the new
|
3112
|
+
// time is within the allowed range (if any).
|
3113
|
+
//---------------------------------------------------------------------
|
3114
|
+
|
3115
|
+
set: function(newTime)
|
3116
|
+
{
|
3117
|
+
var t = newTime.getTime();
|
3118
|
+
if ( this.earliest && ( t < this.earliest ) )
|
3119
|
+
this.time = new Date(this.earliest);
|
3120
|
+
else if ( this.latest && ( t > this.latest ) )
|
3121
|
+
this.time = new Date(this.latest);
|
3122
|
+
else
|
3123
|
+
this.time = newTime;
|
3124
|
+
},
|
3125
|
+
|
3126
|
+
//---------------------------------------------------------------------
|
3127
|
+
// .setEarliest() changes the earliest time.
|
3128
|
+
//---------------------------------------------------------------------
|
3129
|
+
|
3130
|
+
setEarliest: function(newTime)
|
3131
|
+
{
|
3132
|
+
this.earliest = newTime;
|
3133
|
+
this.set(this.time);
|
3134
|
+
},
|
3135
|
+
|
3136
|
+
//---------------------------------------------------------------------
|
3137
|
+
// .setLatest() changes the latest time.
|
3138
|
+
//---------------------------------------------------------------------
|
3139
|
+
|
3140
|
+
setLatest: function(newTime)
|
3141
|
+
{
|
3142
|
+
this.latest = newTime;
|
3143
|
+
this.set(this.time);
|
3144
|
+
},
|
3145
|
+
|
3146
|
+
//---------------------------------------------------------------------
|
3147
|
+
// .showPkr() displays the picker and sets the focus psuedo-
|
3148
|
+
// element. The current value in the input field is used to initialize
|
3149
|
+
// the picker.
|
3150
|
+
//---------------------------------------------------------------------
|
3151
|
+
|
3152
|
+
showPkr: function(event)
|
3153
|
+
{
|
3154
|
+
try
|
3155
|
+
{
|
3156
|
+
this.time = this.conv.parse(this.inp.val());
|
3157
|
+
this.offMin = this.conv.getUtcParseOffsetCaptured();
|
3158
|
+
this.offSI = this.conv.getUtcParseOffsetSubIndex();
|
3159
|
+
}
|
3160
|
+
catch ( e )
|
3161
|
+
{
|
3162
|
+
this.time = new Date();
|
3163
|
+
}
|
3164
|
+
this.set(this.time);
|
3165
|
+
this.upd(null);
|
3166
|
+
|
3167
|
+
fBtn = null;
|
3168
|
+
var cb = '.AnyTime-cur-btn:first';
|
3169
|
+
if ( this.dDoM )
|
3170
|
+
fBtn = this.dDoM.find(cb);
|
3171
|
+
else if ( this.yCur )
|
3172
|
+
fBtn = this.yCur;
|
3173
|
+
else if ( this.dMo )
|
3174
|
+
fBtn = this.dMo.find(cb);
|
3175
|
+
else if ( this.dH )
|
3176
|
+
fBtn = this.dH.find(cb);
|
3177
|
+
else if ( this.dM )
|
3178
|
+
fBtn = this.dM.find(cb);
|
3179
|
+
else if ( this.dS )
|
3180
|
+
fBtn = this.dS.find(cb);
|
3181
|
+
|
3182
|
+
this.setFocus(fBtn);
|
3183
|
+
this.pos(event);
|
3184
|
+
|
3185
|
+
// IE6 doesn't float popups over <select> elements unless an
|
3186
|
+
// <iframe> is inserted between them! So after the picker is
|
3187
|
+
// made visible, move the <iframe> behind it.
|
3188
|
+
|
3189
|
+
if ( this.pop && __iframe )
|
3190
|
+
setTimeout(
|
3191
|
+
function()
|
3192
|
+
{
|
3193
|
+
var pos = _this.div.offset();
|
3194
|
+
__iframe.css( {
|
3195
|
+
height: String(_this.div.outerHeight(true)) + 'px',
|
3196
|
+
left: String(pos.left) + 'px',
|
3197
|
+
position: 'absolute',
|
3198
|
+
top: String(pos.top) + 'px',
|
3199
|
+
width: String(_this.div.outerWidth(true)) + 'px'
|
3200
|
+
} );
|
3201
|
+
__iframe.show();
|
3202
|
+
}, 300 );
|
3203
|
+
|
3204
|
+
}, // .showPkr()
|
3205
|
+
|
3206
|
+
//---------------------------------------------------------------------
|
3207
|
+
// .upd() updates the picker's appearance. It is called after
|
3208
|
+
// most events to make the picker reflect the currently-selected
|
3209
|
+
// values. fBtn is the psuedo-button to be given focus.
|
3210
|
+
//---------------------------------------------------------------------
|
3211
|
+
|
3212
|
+
upd: function(fBtn)
|
3213
|
+
{
|
3214
|
+
var cmpLo = new Date(this.time.getTime());
|
3215
|
+
cmpLo.setMonth(0,1);
|
3216
|
+
cmpLo.setHours(0,0,0,0);
|
3217
|
+
var cmpHi = new Date(this.time.getTime());
|
3218
|
+
cmpHi.setMonth(11,31);
|
3219
|
+
cmpHi.setHours(23,59,59,999);
|
3220
|
+
|
3221
|
+
// Update year.
|
3222
|
+
|
3223
|
+
var current = this.time.getFullYear();
|
3224
|
+
if ( this.earliest && this.yPast )
|
3225
|
+
{
|
3226
|
+
cmpHi.setYear(current-2);
|
3227
|
+
if ( cmpHi.getTime() < this.earliest )
|
3228
|
+
this.yPast.addClass('AnyTime-out-btn ui-state-disabled');
|
3229
|
+
else
|
3230
|
+
this.yPast.removeClass('AnyTime-out-btn ui-state-disabled');
|
3231
|
+
}
|
3232
|
+
if ( this.yPrior )
|
3233
|
+
{
|
3234
|
+
this.yPrior.text(AnyTime.pad((current==1)?(-1):(current-1),4));
|
3235
|
+
if ( this.earliest )
|
3236
|
+
{
|
3237
|
+
cmpHi.setYear(current-1);
|
3238
|
+
if ( cmpHi.getTime() < this.earliest )
|
3239
|
+
this.yPrior.addClass('AnyTime-out-btn ui-state-disabled');
|
3240
|
+
else
|
3241
|
+
this.yPrior.removeClass('AnyTime-out-btn ui-state-disabled');
|
3242
|
+
}
|
3243
|
+
}
|
3244
|
+
if ( this.yCur )
|
3245
|
+
this.yCur.text(AnyTime.pad(current,4));
|
3246
|
+
if ( this.yNext )
|
3247
|
+
{
|
3248
|
+
this.yNext.text(AnyTime.pad((current==-1)?1:(current+1),4));
|
3249
|
+
if ( this.latest )
|
3250
|
+
{
|
3251
|
+
cmpLo.setYear(current+1);
|
3252
|
+
if ( cmpLo.getTime() > this.latest )
|
3253
|
+
this.yNext.addClass('AnyTime-out-btn ui-state-disabled');
|
3254
|
+
else
|
3255
|
+
this.yNext.removeClass('AnyTime-out-btn ui-state-disabled');
|
3256
|
+
}
|
3257
|
+
}
|
3258
|
+
if ( this.latest && this.yAhead )
|
3259
|
+
{
|
3260
|
+
cmpLo.setYear(current+2);
|
3261
|
+
if ( cmpLo.getTime() > this.latest )
|
3262
|
+
this.yAhead.addClass('AnyTime-out-btn ui-state-disabled');
|
3263
|
+
else
|
3264
|
+
this.yAhead.removeClass('AnyTime-out-btn ui-state-disabled');
|
3265
|
+
}
|
3266
|
+
|
3267
|
+
// Update month.
|
3268
|
+
|
3269
|
+
cmpLo.setFullYear( this.time.getFullYear() );
|
3270
|
+
cmpHi.setFullYear( this.time.getFullYear() );
|
3271
|
+
var i = 0;
|
3272
|
+
current = this.time.getMonth();
|
3273
|
+
$('#'+this.id+' .AnyTime-mon-btn').each(
|
3274
|
+
function()
|
3275
|
+
{
|
3276
|
+
cmpLo.setMonth(i);
|
3277
|
+
cmpHi.setDate(1);
|
3278
|
+
cmpHi.setMonth(i+1);
|
3279
|
+
cmpHi.setDate(0);
|
3280
|
+
$(this).AnyTime_current( i == current,
|
3281
|
+
((!_this.earliest)||(cmpHi.getTime()>=_this.earliest)) &&
|
3282
|
+
((!_this.latest)||(cmpLo.getTime()<=_this.latest)) );
|
3283
|
+
i++;
|
3284
|
+
} );
|
3285
|
+
|
3286
|
+
// Update days.
|
3287
|
+
|
3288
|
+
cmpLo.setFullYear( this.time.getFullYear() );
|
3289
|
+
cmpHi.setFullYear( this.time.getFullYear() );
|
3290
|
+
cmpLo.setMonth( this.time.getMonth() );
|
3291
|
+
cmpHi.setMonth( this.time.getMonth(), 1 );
|
3292
|
+
current = this.time.getDate();
|
3293
|
+
var currentMonth = this.time.getMonth();
|
3294
|
+
var dow1 = cmpLo.getDay();
|
3295
|
+
if ( this.fDOW > dow1 )
|
3296
|
+
dow1 += 7;
|
3297
|
+
var wom = 0, dow=0;
|
3298
|
+
$('#'+this.id+' .AnyTime-wk').each(
|
3299
|
+
function()
|
3300
|
+
{
|
3301
|
+
dow = _this.fDOW;
|
3302
|
+
$(this).children().each(
|
3303
|
+
function()
|
3304
|
+
{
|
3305
|
+
if ( dow - _this.fDOW < 7 )
|
3306
|
+
{
|
3307
|
+
var td = $(this);
|
3308
|
+
if ( ((wom==0)&&(dow<dow1)) || (cmpLo.getMonth()!=currentMonth) )
|
3309
|
+
{
|
3310
|
+
td.html(' ');
|
3311
|
+
td.removeClass('AnyTime-dom-btn-filled AnyTime-cur-btn ui-state-default ui-state-highlight');
|
3312
|
+
td.addClass('AnyTime-dom-btn-empty');
|
3313
|
+
if ( wom ) // not first week
|
3314
|
+
{
|
3315
|
+
if ( ( cmpLo.getDate() == 1 ) && ( dow != 0 ) )
|
3316
|
+
td.addClass('AnyTime-dom-btn-empty-after-filled');
|
3317
|
+
else
|
3318
|
+
td.removeClass('AnyTime-dom-btn-empty-after-filled');
|
3319
|
+
if ( cmpLo.getDate() <= 7 )
|
3320
|
+
td.addClass('AnyTime-dom-btn-empty-below-filled');
|
3321
|
+
else
|
3322
|
+
td.removeClass('AnyTime-dom-btn-empty-below-filled');
|
3323
|
+
cmpLo.setDate(cmpLo.getDate()+1);
|
3324
|
+
cmpHi.setDate(cmpHi.getDate()+1);
|
3325
|
+
}
|
3326
|
+
else // first week
|
3327
|
+
{
|
3328
|
+
td.addClass('AnyTime-dom-btn-empty-above-filled');
|
3329
|
+
if ( dow == dow1 - 1 )
|
3330
|
+
td.addClass('AnyTime-dom-btn-empty-before-filled');
|
3331
|
+
else
|
3332
|
+
td.removeClass('AnyTime-dom-btn-empty-before-filled');
|
3333
|
+
}
|
3334
|
+
td.addClass('ui-state-default ui-state-disabled');
|
3335
|
+
}
|
3336
|
+
else
|
3337
|
+
{
|
3338
|
+
i = cmpLo.getDate();
|
3339
|
+
td.text(i);
|
3340
|
+
td.removeClass('AnyTime-dom-btn-empty AnyTime-dom-btn-empty-above-filled AnyTime-dom-btn-empty-before-filled '+
|
3341
|
+
'AnyTime-dom-btn-empty-after-filled AnyTime-dom-btn-empty-below-filled ' +
|
3342
|
+
'ui-state-default ui-state-disabled');
|
3343
|
+
td.addClass('AnyTime-dom-btn-filled ui-state-default');
|
3344
|
+
td.AnyTime_current( i == current,
|
3345
|
+
((!_this.earliest)||(cmpHi.getTime()>=_this.earliest)) &&
|
3346
|
+
((!_this.latest)||(cmpLo.getTime()<=_this.latest)) );
|
3347
|
+
cmpLo.setDate(i+1);
|
3348
|
+
cmpHi.setDate(i+1);
|
3349
|
+
}
|
3350
|
+
}
|
3351
|
+
dow++;
|
3352
|
+
} );
|
3353
|
+
wom++;
|
3354
|
+
} );
|
3355
|
+
|
3356
|
+
// Update hour.
|
3357
|
+
|
3358
|
+
cmpLo.setFullYear( this.time.getFullYear() );
|
3359
|
+
cmpHi.setFullYear( this.time.getFullYear() );
|
3360
|
+
cmpLo.setMonth( this.time.getMonth(), this.time.getDate() );
|
3361
|
+
cmpHi.setMonth( this.time.getMonth(), this.time.getDate() );
|
3362
|
+
var not12 = ! this.twelveHr;
|
3363
|
+
var hr = this.time.getHours();
|
3364
|
+
$('#'+this.id+' .AnyTime-hr-btn').each(
|
3365
|
+
function()
|
3366
|
+
{
|
3367
|
+
var html = this.innerHTML;
|
3368
|
+
var i;
|
3369
|
+
if ( not12 )
|
3370
|
+
i = Number(html);
|
3371
|
+
else
|
3372
|
+
{
|
3373
|
+
i = Number(html.substring(0,html.length-2) );
|
3374
|
+
if ( html.charAt(html.length-2) == 'a' )
|
3375
|
+
{
|
3376
|
+
if ( i == 12 )
|
3377
|
+
i = 0;
|
3378
|
+
}
|
3379
|
+
else if ( i < 12 )
|
3380
|
+
i += 12;
|
3381
|
+
}
|
3382
|
+
cmpLo.setHours(i);
|
3383
|
+
cmpHi.setHours(i);
|
3384
|
+
$(this).AnyTime_current( hr == i,
|
3385
|
+
((!_this.earliest)||(cmpHi.getTime()>=_this.earliest)) &&
|
3386
|
+
((!_this.latest)||(cmpLo.getTime()<=_this.latest)) );
|
3387
|
+
if ( i < 23 )
|
3388
|
+
cmpLo.setHours( cmpLo.getHours()+1 );
|
3389
|
+
} );
|
3390
|
+
|
3391
|
+
// Update minute.
|
3392
|
+
|
3393
|
+
cmpLo.setHours( this.time.getHours() );
|
3394
|
+
cmpHi.setHours( this.time.getHours() );
|
3395
|
+
var units = this.time.getMinutes();
|
3396
|
+
var tens = String(Math.floor(units/10));
|
3397
|
+
var ones = String(units % 10);
|
3398
|
+
$('#'+this.id+' .AnyTime-min-ten-btn:not(.AnyTime-min-ten-btn-empty)').each(
|
3399
|
+
function()
|
3400
|
+
{
|
3401
|
+
$(this).AnyTime_current( this.innerHTML == tens,
|
3402
|
+
((!_this.earliest)||(cmpHi.getTime()>=_this.earliest)) &&
|
3403
|
+
((!_this.latest)||(cmpLo.getTime()<=_this.latest)) );
|
3404
|
+
if ( cmpLo.getMinutes() < 50 )
|
3405
|
+
{
|
3406
|
+
cmpLo.setMinutes( cmpLo.getMinutes()+10 );
|
3407
|
+
cmpHi.setMinutes( cmpHi.getMinutes()+10 );
|
3408
|
+
}
|
3409
|
+
} );
|
3410
|
+
cmpLo.setMinutes( Math.floor(this.time.getMinutes()/10)*10 );
|
3411
|
+
cmpHi.setMinutes( Math.floor(this.time.getMinutes()/10)*10 );
|
3412
|
+
$('#'+this.id+' .AnyTime-min-one-btn:not(.AnyTime-min-one-btn-empty)').each(
|
3413
|
+
function()
|
3414
|
+
{
|
3415
|
+
$(this).AnyTime_current( this.innerHTML == ones,
|
3416
|
+
((!_this.earliest)||(cmpHi.getTime()>=_this.earliest)) &&
|
3417
|
+
((!_this.latest)||(cmpLo.getTime()<=_this.latest)) );
|
3418
|
+
cmpLo.setMinutes( cmpLo.getMinutes()+1 );
|
3419
|
+
cmpHi.setMinutes( cmpHi.getMinutes()+1 );
|
3420
|
+
} );
|
3421
|
+
|
3422
|
+
// Update second.
|
3423
|
+
|
3424
|
+
cmpLo.setMinutes( this.time.getMinutes() );
|
3425
|
+
cmpHi.setMinutes( this.time.getMinutes() );
|
3426
|
+
units = this.time.getSeconds();
|
3427
|
+
tens = String(Math.floor(units/10));
|
3428
|
+
ones = String(units % 10);
|
3429
|
+
$('#'+this.id+' .AnyTime-sec-ten-btn:not(.AnyTime-sec-ten-btn-empty)').each(
|
3430
|
+
function()
|
3431
|
+
{
|
3432
|
+
$(this).AnyTime_current( this.innerHTML == tens,
|
3433
|
+
((!_this.earliest)||(cmpHi.getTime()>=_this.earliest)) &&
|
3434
|
+
((!_this.latest)||(cmpLo.getTime()<=_this.latest)) );
|
3435
|
+
if ( cmpLo.getSeconds() < 50 )
|
3436
|
+
{
|
3437
|
+
cmpLo.setSeconds( cmpLo.getSeconds()+10 );
|
3438
|
+
cmpHi.setSeconds( cmpHi.getSeconds()+10 );
|
3439
|
+
}
|
3440
|
+
} );
|
3441
|
+
cmpLo.setSeconds( Math.floor(this.time.getSeconds()/10)*10 );
|
3442
|
+
cmpHi.setSeconds( Math.floor(this.time.getSeconds()/10)*10 );
|
3443
|
+
$('#'+this.id+' .AnyTime-sec-one-btn:not(.AnyTime-sec-one-btn-empty)').each(
|
3444
|
+
function()
|
3445
|
+
{
|
3446
|
+
$(this).AnyTime_current( this.innerHTML == ones,
|
3447
|
+
((!_this.earliest)||(cmpHi.getTime()>=_this.earliest)) &&
|
3448
|
+
((!_this.latest)||(cmpLo.getTime()<=_this.latest)) );
|
3449
|
+
cmpLo.setSeconds( cmpLo.getSeconds()+1 );
|
3450
|
+
cmpHi.setSeconds( cmpHi.getSeconds()+1 );
|
3451
|
+
} );
|
3452
|
+
|
3453
|
+
// Update offset (time zone).
|
3454
|
+
|
3455
|
+
if ( this.oConv )
|
3456
|
+
{
|
3457
|
+
this.oConv.setUtcFormatOffsetAlleged(this.offMin);
|
3458
|
+
this.oConv.setUtcFormatOffsetSubIndex(this.offSI);
|
3459
|
+
var tzs = this.oConv.format(this.time);
|
3460
|
+
this.oCur.html( tzs );
|
3461
|
+
}
|
3462
|
+
|
3463
|
+
// Set the focus element, then size the picker according to its
|
3464
|
+
// components, show the changes, and invoke Ajax if desired.
|
3465
|
+
|
3466
|
+
if ( fBtn )
|
3467
|
+
this.setFocus(fBtn);
|
3468
|
+
|
3469
|
+
this.conv.setUtcFormatOffsetAlleged(this.offMin);
|
3470
|
+
this.conv.setUtcFormatOffsetSubIndex(this.offSI);
|
3471
|
+
this.inp.val(this.conv.format(this.time)).change();
|
3472
|
+
this.div.show();
|
3473
|
+
|
3474
|
+
var d, totH = 0, totW = 0, dYW = 0, dMoW = 0, dDoMW = 0;
|
3475
|
+
if ( this.dY )
|
3476
|
+
{
|
3477
|
+
totW = dYW = this.dY.outerWidth(true);
|
3478
|
+
totH = this.yLab.AnyTime_height(true) + this.dY.AnyTime_height(true);
|
3479
|
+
}
|
3480
|
+
if ( this.dMo )
|
3481
|
+
{
|
3482
|
+
dMoW = this.dMo.outerWidth(true);
|
3483
|
+
if ( dMoW > totW )
|
3484
|
+
totW = dMoW;
|
3485
|
+
totH += this.hMo.AnyTime_height(true) + this.dMo.AnyTime_height(true);
|
3486
|
+
}
|
3487
|
+
if ( this.dDoM )
|
3488
|
+
{
|
3489
|
+
dDoMW = this.dDoM.outerWidth(true);
|
3490
|
+
if ( dDoMW > totW )
|
3491
|
+
totW = dDoMW;
|
3492
|
+
if ( __msie6 || __msie7 )
|
3493
|
+
{
|
3494
|
+
if ( dMoW > dDoMW )
|
3495
|
+
this.dDoM.css('width',String(dMoW)+'px');
|
3496
|
+
else if ( dYW > dDoMW )
|
3497
|
+
this.dDoM.css('width',String(dYW)+'px');
|
3498
|
+
}
|
3499
|
+
totH += this.hDoM.AnyTime_height(true) + this.dDoM.AnyTime_height(true);
|
3500
|
+
}
|
3501
|
+
if ( this.dD )
|
3502
|
+
{
|
3503
|
+
this.dD.css( { width:String(totW)+'px', height:String(totH)+'px' } );
|
3504
|
+
totW += this.dMinW;
|
3505
|
+
totH += this.dMinH;
|
3506
|
+
}
|
3507
|
+
|
3508
|
+
var w = 0, h = 0, timeH = 0, timeW = 0;
|
3509
|
+
if ( this.dH )
|
3510
|
+
{
|
3511
|
+
w = this.dH.outerWidth(true);
|
3512
|
+
timeW += w + 1;
|
3513
|
+
h = this.dH.AnyTime_height(true);
|
3514
|
+
if ( h > timeH )
|
3515
|
+
timeH = h;
|
3516
|
+
}
|
3517
|
+
if ( this.dM )
|
3518
|
+
{
|
3519
|
+
w = this.dM.outerWidth(true);
|
3520
|
+
timeW += w + 1;
|
3521
|
+
h = this.dM.AnyTime_height(true);
|
3522
|
+
if ( h > timeH )
|
3523
|
+
timeH = h;
|
3524
|
+
}
|
3525
|
+
if ( this.dS )
|
3526
|
+
{
|
3527
|
+
w = this.dS.outerWidth(true);
|
3528
|
+
timeW += w + 1;
|
3529
|
+
h = this.dS.AnyTime_height(true);
|
3530
|
+
if ( h > timeH )
|
3531
|
+
timeH = h;
|
3532
|
+
}
|
3533
|
+
if ( this.dO )
|
3534
|
+
{
|
3535
|
+
w = this.oMinW;
|
3536
|
+
if ( timeW < w+1 )
|
3537
|
+
timeW = w+1;
|
3538
|
+
timeH += this.dO.AnyTime_height(true);
|
3539
|
+
}
|
3540
|
+
if ( this.dT )
|
3541
|
+
{
|
3542
|
+
this.dT.css( { width:String(timeW)+'px', height:String(timeH)+'px' } );
|
3543
|
+
timeW += this.tMinW + 1;
|
3544
|
+
timeH += this.tMinH;
|
3545
|
+
totW += timeW;
|
3546
|
+
if ( timeH > totH )
|
3547
|
+
totH = timeH;
|
3548
|
+
if ( this.dO ) // stretch offset button if possible
|
3549
|
+
{
|
3550
|
+
var dOW = this.dT.width()-(this.oMinW+1);
|
3551
|
+
this.dO.css({width:String(dOW)+"px"});
|
3552
|
+
this.oCur.css({width:String(dOW-(this.oListMinW+4))+"px"});
|
3553
|
+
}
|
3554
|
+
}
|
3555
|
+
|
3556
|
+
this.dB.css({height:String(totH)+'px',width:String(totW)+'px'});
|
3557
|
+
|
3558
|
+
totH += this.bMinH;
|
3559
|
+
totW += this.bMinW;
|
3560
|
+
totH += this.hTitle.AnyTime_height(true) + this.wMinH;
|
3561
|
+
totW += this.wMinW;
|
3562
|
+
if ( this.hTitle.outerWidth(true) > totW )
|
3563
|
+
totW = this.hTitle.outerWidth(true); // IE quirk
|
3564
|
+
this.div.css({height:String(totH)+'px',width:String(totW)+'px'});
|
3565
|
+
|
3566
|
+
if ( ! this.pop )
|
3567
|
+
this.ajax();
|
3568
|
+
|
3569
|
+
}, // .upd()
|
3570
|
+
|
3571
|
+
//---------------------------------------------------------------------
|
3572
|
+
// .updODiv() updates the UTC offset selector's appearance. It is
|
3573
|
+
// called after most events to make the picker reflect the currently-
|
3574
|
+
// selected values. fBtn is the psuedo-button to be given focus.
|
3575
|
+
//---------------------------------------------------------------------
|
3576
|
+
|
3577
|
+
updODiv: function(fBtn)
|
3578
|
+
{
|
3579
|
+
var cur, matched = false, def = null;
|
3580
|
+
this.oDiv.find('.AnyTime-off-off-btn').each(
|
3581
|
+
function()
|
3582
|
+
{
|
3583
|
+
if ( this.AnyTime_offMin == _this.offMin )
|
3584
|
+
{
|
3585
|
+
if ( this.AnyTime_offSI == _this.offSI )
|
3586
|
+
$(this).AnyTime_current(matched=true,true);
|
3587
|
+
else
|
3588
|
+
{
|
3589
|
+
$(this).AnyTime_current(false,true);
|
3590
|
+
if ( def == null )
|
3591
|
+
def = $(this);
|
3592
|
+
}
|
3593
|
+
}
|
3594
|
+
else
|
3595
|
+
$(this).AnyTime_current(false,true);
|
3596
|
+
} );
|
3597
|
+
if ( ( ! matched ) && ( def != null ) )
|
3598
|
+
def.AnyTime_current(true,true);
|
3599
|
+
|
3600
|
+
// Show change
|
3601
|
+
|
3602
|
+
this.conv.setUtcFormatOffsetAlleged(this.offMin);
|
3603
|
+
this.conv.setUtcFormatOffsetSubIndex(this.offSI);
|
3604
|
+
this.inp.val(this.conv.format(this.time)).change();
|
3605
|
+
this.upd(fBtn);
|
3606
|
+
|
3607
|
+
}, // .updODiv()
|
3608
|
+
|
3609
|
+
//---------------------------------------------------------------------
|
3610
|
+
// .updYDiv() updates the year selector's appearance. It is
|
3611
|
+
// called after most events to make the picker reflect the currently-
|
3612
|
+
// selected values. fBtn is the psuedo-button to be given focus.
|
3613
|
+
//---------------------------------------------------------------------
|
3614
|
+
|
3615
|
+
updYDiv: function(fBtn)
|
3616
|
+
{
|
3617
|
+
var i, legal;
|
3618
|
+
var era = 1;
|
3619
|
+
var yearValue = this.time.getFullYear();
|
3620
|
+
if ( yearValue < 0 )
|
3621
|
+
{
|
3622
|
+
era = (-1);
|
3623
|
+
yearValue = 0 - yearValue;
|
3624
|
+
}
|
3625
|
+
yearValue = AnyTime.pad( yearValue, 4 );
|
3626
|
+
var eY = _this.earliest && new Date(_this.earliest).getFullYear();
|
3627
|
+
var lY = _this.latest && new Date(_this.latest).getFullYear();
|
3628
|
+
|
3629
|
+
i = 0;
|
3630
|
+
this.yDiv.find('.AnyTime-mil-btn').each(
|
3631
|
+
function()
|
3632
|
+
{
|
3633
|
+
legal = ( ((!_this.earliest)||(era*(i+(era<0?0:999))>=eY)) && ((!_this.latest)||(era*(i+(era>0?0:999))<=lY)) );
|
3634
|
+
$(this).AnyTime_current( this.innerHTML == yearValue.substring(0,1), legal );
|
3635
|
+
i += 1000;
|
3636
|
+
} );
|
3637
|
+
|
3638
|
+
i = (Math.floor(yearValue/1000)*1000);
|
3639
|
+
this.yDiv.find('.AnyTime-cent-btn').each(
|
3640
|
+
function()
|
3641
|
+
{
|
3642
|
+
legal = ( ((!_this.earliest)||(era*(i+(era<0?0:99))>=eY)) && ((!_this.latest)||(era*(i+(era>0?0:99))<=lY)) );
|
3643
|
+
$(this).AnyTime_current( this.innerHTML == yearValue.substring(1,2), legal );
|
3644
|
+
i += 100;
|
3645
|
+
} );
|
3646
|
+
|
3647
|
+
i = (Math.floor(yearValue/100)*100);
|
3648
|
+
this.yDiv.find('.AnyTime-dec-btn').each(
|
3649
|
+
function()
|
3650
|
+
{
|
3651
|
+
legal = ( ((!_this.earliest)||(era*(i+(era<0?0:9))>=eY)) && ((!_this.latest)||(era*(i+(era>0?0:9))<=lY)) );
|
3652
|
+
$(this).AnyTime_current( this.innerHTML == yearValue.substring(2,3), legal );
|
3653
|
+
i += 10;
|
3654
|
+
} );
|
3655
|
+
|
3656
|
+
i = (Math.floor(yearValue/10)*10);
|
3657
|
+
this.yDiv.find('.AnyTime-yr-btn').each(
|
3658
|
+
function()
|
3659
|
+
{
|
3660
|
+
legal = ( ((!_this.earliest)||(era*i>=eY)) && ((!_this.latest)||(era*i<=lY)) );
|
3661
|
+
$(this).AnyTime_current( this.innerHTML == yearValue.substring(3), legal );
|
3662
|
+
i += 1;
|
3663
|
+
} );
|
3664
|
+
|
3665
|
+
this.yDiv.find('.AnyTime-bce-btn').each(
|
3666
|
+
function()
|
3667
|
+
{
|
3668
|
+
$(this).AnyTime_current( era < 0, (!_this.earliest) || ( _this.earliest < 0 ) );
|
3669
|
+
} );
|
3670
|
+
this.yDiv.find('.AnyTime-ce-btn').each(
|
3671
|
+
function()
|
3672
|
+
{
|
3673
|
+
$(this).AnyTime_current( era > 0, (!_this.latest) || ( _this.latest > 0 ) );
|
3674
|
+
} );
|
3675
|
+
|
3676
|
+
// Show change
|
3677
|
+
|
3678
|
+
this.conv.setUtcFormatOffsetAlleged(this.offMin);
|
3679
|
+
this.conv.setUtcFormatOffsetSubIndex(this.offSI);
|
3680
|
+
this.inp.val(this.conv.format(this.time)).change();
|
3681
|
+
this.upd(fBtn);
|
3682
|
+
|
3683
|
+
} // .updYDiv()
|
3684
|
+
|
3685
|
+
}; // __pickers[id] = ...
|
3686
|
+
__pickers[id].initialize(id);
|
3687
|
+
|
3688
|
+
} // AnyTime.picker =
|
3689
|
+
|
3690
|
+
//=============================================================================
|
3691
|
+
// AnyTime.setEarliest()
|
3692
|
+
//
|
3693
|
+
// Updates the earliest date/time for the picker attached to a specified
|
3694
|
+
// text field.
|
3695
|
+
//=============================================================================
|
3696
|
+
|
3697
|
+
AnyTime.setEarliest = function( id, newTime )
|
3698
|
+
{
|
3699
|
+
__pickers[id].setEarliest(newTime)
|
3700
|
+
};
|
3701
|
+
|
3702
|
+
|
3703
|
+
//=============================================================================
|
3704
|
+
// AnyTime.setLatest()
|
3705
|
+
//
|
3706
|
+
// Updates the latest date/time for the picker attached to a specified
|
3707
|
+
// text field.
|
3708
|
+
//=============================================================================
|
3709
|
+
|
3710
|
+
AnyTime.setLatest = function( id, newTime )
|
3711
|
+
{
|
3712
|
+
__pickers[id].setLatest(newTime)
|
3713
|
+
};
|
3714
|
+
|
3715
|
+
|
3716
|
+
})(jQuery); // function($)...
|