| |
1
| +/*! jQuery UI - v1.12.1 - 2017-08-04 |
| |
2
| +* http://jqueryui.com |
| |
3
| +* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/datepicker.js |
| |
4
| +* Copyright jQuery Foundation and other contributors; Licensed MIT */ |
| |
5
| + |
| |
6
| +(function( factory ) { |
| |
7
| + if ( typeof define === "function" && define.amd ) { |
| |
8
| + |
| |
9
| + // AMD. Register as an anonymous module. |
| |
10
| + define([ "jquery" ], factory ); |
| |
11
| + } else { |
| |
12
| + |
| |
13
| + // Browser globals |
| |
14
| + factory( jQuery ); |
| |
15
| + } |
| |
16
| +}(function( $ ) { |
| |
17
| + |
| |
18
| +$.ui = $.ui || {}; |
| |
19
| + |
| |
20
| +var version = $.ui.version = "1.12.1"; |
| |
21
| + |
| |
22
| + |
| |
23
| +/*! |
| |
24
| + * jQuery UI Widget 1.12.1 |
| |
25
| + * http://jqueryui.com |
| |
26
| + * |
| |
27
| + * Copyright jQuery Foundation and other contributors |
| |
28
| + * Released under the MIT license. |
| |
29
| + * http://jquery.org/license |
| |
30
| + */ |
| |
31
| + |
| |
32
| +//>>label: Widget |
| |
33
| +//>>group: Core |
| |
34
| +//>>description: Provides a factory for creating stateful widgets with a common API. |
| |
35
| +//>>docs: http://api.jqueryui.com/jQuery.widget/ |
| |
36
| +//>>demos: http://jqueryui.com/widget/ |
| |
37
| + |
| |
38
| + |
| |
39
| + |
| |
40
| +var widgetUuid = 0; |
| |
41
| +var widgetSlice = Array.prototype.slice; |
| |
42
| + |
| |
43
| +$.cleanData = ( function( orig ) { |
| |
44
| + return function( elems ) { |
| |
45
| + var events, elem, i; |
| |
46
| + for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { |
| |
47
| + try { |
| |
48
| + |
| |
49
| + // Only trigger remove when necessary to save time |
| |
50
| + events = $._data( elem, "events" ); |
| |
51
| + if ( events && events.remove ) { |
| |
52
| + $( elem ).triggerHandler( "remove" ); |
| |
53
| + } |
| |
54
| + |
| |
55
| + // Http://bugs.jquery.com/ticket/8235 |
| |
56
| + } catch ( e ) {} |
| |
57
| + } |
| |
58
| + orig( elems ); |
| |
59
| + }; |
| |
60
| +} )( $.cleanData ); |
| |
61
| + |
| |
62
| +$.widget = function( name, base, prototype ) { |
| |
63
| + var existingConstructor, constructor, basePrototype; |
| |
64
| + |
| |
65
| + // ProxiedPrototype allows the provided prototype to remain unmodified |
| |
66
| + // so that it can be used as a mixin for multiple widgets (#8876) |
| |
67
| + var proxiedPrototype = {}; |
| |
68
| + |
| |
69
| + var namespace = name.split( "." )[ 0 ]; |
| |
70
| + name = name.split( "." )[ 1 ]; |
| |
71
| + var fullName = namespace + "-" + name; |
| |
72
| + |
| |
73
| + if ( !prototype ) { |
| |
74
| + prototype = base; |
| |
75
| + base = $.Widget; |
| |
76
| + } |
| |
77
| + |
| |
78
| + if ( $.isArray( prototype ) ) { |
| |
79
| + prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); |
| |
80
| + } |
| |
81
| + |
| |
82
| + // Create selector for plugin |
| |
83
| + $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { |
| |
84
| + return !!$.data( elem, fullName ); |
| |
85
| + }; |
| |
86
| + |
| |
87
| + $[ namespace ] = $[ namespace ] || {}; |
| |
88
| + existingConstructor = $[ namespace ][ name ]; |
| |
89
| + constructor = $[ namespace ][ name ] = function( options, element ) { |
| |
90
| + |
| |
91
| + // Allow instantiation without "new" keyword |
| |
92
| + if ( !this._createWidget ) { |
| |
93
| + return new constructor( options, element ); |
| |
94
| + } |
| |
95
| + |
| |
96
| + // Allow instantiation without initializing for simple inheritance |
| |
97
| + // must use "new" keyword (the code above always passes args) |
| |
98
| + if ( arguments.length ) { |
| |
99
| + this._createWidget( options, element ); |
| |
100
| + } |
| |
101
| + }; |
| |
102
| + |
| |
103
| + // Extend with the existing constructor to carry over any static properties |
| |
104
| + $.extend( constructor, existingConstructor, { |
| |
105
| + version: prototype.version, |
| |
106
| + |
| |
107
| + // Copy the object used to create the prototype in case we need to |
| |
108
| + // redefine the widget later |
| |
109
| + _proto: $.extend( {}, prototype ), |
| |
110
| + |
| |
111
| + // Track widgets that inherit from this widget in case this widget is |
| |
112
| + // redefined after a widget inherits from it |
| |
113
| + _childConstructors: [] |
| |
114
| + } ); |
| |
115
| + |
| |
116
| + basePrototype = new base(); |
| |
117
| + |
| |
118
| + // We need to make the options hash a property directly on the new instance |
| |
119
| + // otherwise we'll modify the options hash on the prototype that we're |
| |
120
| + // inheriting from |
| |
121
| + basePrototype.options = $.widget.extend( {}, basePrototype.options ); |
| |
122
| + $.each( prototype, function( prop, value ) { |
| |
123
| + if ( !$.isFunction( value ) ) { |
| |
124
| + proxiedPrototype[ prop ] = value; |
| |
125
| + return; |
| |
126
| + } |
| |
127
| + proxiedPrototype[ prop ] = ( function() { |
| |
128
| + function _super() { |
| |
129
| + return base.prototype[ prop ].apply( this, arguments ); |
| |
130
| + } |
| |
131
| + |
| |
132
| + function _superApply( args ) { |
| |
133
| + return base.prototype[ prop ].apply( this, args ); |
| |
134
| + } |
| |
135
| + |
| |
136
| + return function() { |
| |
137
| + var __super = this._super; |
| |
138
| + var __superApply = this._superApply; |
| |
139
| + var returnValue; |
| |
140
| + |
| |
141
| + this._super = _super; |
| |
142
| + this._superApply = _superApply; |
| |
143
| + |
| |
144
| + returnValue = value.apply( this, arguments ); |
| |
145
| + |
| |
146
| + this._super = __super; |
| |
147
| + this._superApply = __superApply; |
| |
148
| + |
| |
149
| + return returnValue; |
| |
150
| + }; |
| |
151
| + } )(); |
| |
152
| + } ); |
| |
153
| + constructor.prototype = $.widget.extend( basePrototype, { |
| |
154
| + |
| |
155
| + // TODO: remove support for widgetEventPrefix |
| |
156
| + // always use the name + a colon as the prefix, e.g., draggable:start |
| |
157
| + // don't prefix for widgets that aren't DOM-based |
| |
158
| + widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name |
| |
159
| + }, proxiedPrototype, { |
| |
160
| + constructor: constructor, |
| |
161
| + namespace: namespace, |
| |
162
| + widgetName: name, |
| |
163
| + widgetFullName: fullName |
| |
164
| + } ); |
| |
165
| + |
| |
166
| + // If this widget is being redefined then we need to find all widgets that |
| |
167
| + // are inheriting from it and redefine all of them so that they inherit from |
| |
168
| + // the new version of this widget. We're essentially trying to replace one |
| |
169
| + // level in the prototype chain. |
| |
170
| + if ( existingConstructor ) { |
| |
171
| + $.each( existingConstructor._childConstructors, function( i, child ) { |
| |
172
| + var childPrototype = child.prototype; |
| |
173
| + |
| |
174
| + // Redefine the child widget using the same prototype that was |
| |
175
| + // originally used, but inherit from the new version of the base |
| |
176
| + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, |
| |
177
| + child._proto ); |
| |
178
| + } ); |
| |
179
| + |
| |
180
| + // Remove the list of existing child constructors from the old constructor |
| |
181
| + // so the old child constructors can be garbage collected |
| |
182
| + delete existingConstructor._childConstructors; |
| |
183
| + } else { |
| |
184
| + base._childConstructors.push( constructor ); |
| |
185
| + } |
| |
186
| + |
| |
187
| + $.widget.bridge( name, constructor ); |
| |
188
| + |
| |
189
| + return constructor; |
| |
190
| +}; |
| |
191
| + |
| |
192
| +$.widget.extend = function( target ) { |
| |
193
| + var input = widgetSlice.call( arguments, 1 ); |
| |
194
| + var inputIndex = 0; |
| |
195
| + var inputLength = input.length; |
| |
196
| + var key; |
| |
197
| + var value; |
| |
198
| + |
| |
199
| + for ( ; inputIndex < inputLength; inputIndex++ ) { |
| |
200
| + for ( key in input[ inputIndex ] ) { |
| |
201
| + value = input[ inputIndex ][ key ]; |
| |
202
| + if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { |
| |
203
| + |
| |
204
| + // Clone objects |
| |
205
| + if ( $.isPlainObject( value ) ) { |
| |
206
| + target[ key ] = $.isPlainObject( target[ key ] ) ? |
| |
207
| + $.widget.extend( {}, target[ key ], value ) : |
| |
208
| + |
| |
209
| + // Don't extend strings, arrays, etc. with objects |
| |
210
| + $.widget.extend( {}, value ); |
| |
211
| + |
| |
212
| + // Copy everything else by reference |
| |
213
| + } else { |
| |
214
| + target[ key ] = value; |
| |
215
| + } |
| |
216
| + } |
| |
217
| + } |
| |
218
| + } |
| |
219
| + return target; |
| |
220
| +}; |
| |
221
| + |
| |
222
| +$.widget.bridge = function( name, object ) { |
| |
223
| + var fullName = object.prototype.widgetFullName || name; |
| |
224
| + $.fn[ name ] = function( options ) { |
| |
225
| + var isMethodCall = typeof options === "string"; |
| |
226
| + var args = widgetSlice.call( arguments, 1 ); |
| |
227
| + var returnValue = this; |
| |
228
| + |
| |
229
| + if ( isMethodCall ) { |
| |
230
| + |
| |
231
| + // If this is an empty collection, we need to have the instance method |
| |
232
| + // return undefined instead of the jQuery instance |
| |
233
| + if ( !this.length && options === "instance" ) { |
| |
234
| + returnValue = undefined; |
| |
235
| + } else { |
| |
236
| + this.each( function() { |
| |
237
| + var methodValue; |
| |
238
| + var instance = $.data( this, fullName ); |
| |
239
| + |
| |
240
| + if ( options === "instance" ) { |
| |
241
| + returnValue = instance; |
| |
242
| + return false; |
| |
243
| + } |
| |
244
| + |
| |
245
| + if ( !instance ) { |
| |
246
| + return $.error( "cannot call methods on " + name + |
| |
247
| + " prior to initialization; " + |
| |
248
| + "attempted to call method '" + options + "'" ); |
| |
249
| + } |
| |
250
| + |
| |
251
| + if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) { |
| |
252
| + return $.error( "no such method '" + options + "' for " + name + |
| |
253
| + " widget instance" ); |
| |
254
| + } |
| |
255
| + |
| |
256
| + methodValue = instance[ options ].apply( instance, args ); |
| |
257
| + |
| |
258
| + if ( methodValue !== instance && methodValue !== undefined ) { |
| |
259
| + returnValue = methodValue && methodValue.jquery ? |
| |
260
| + returnValue.pushStack( methodValue.get() ) : |
| |
261
| + methodValue; |
| |
262
| + return false; |
| |
263
| + } |
| |
264
| + } ); |
| |
265
| + } |
| |
266
| + } else { |
| |
267
| + |
| |
268
| + // Allow multiple hashes to be passed on init |
| |
269
| + if ( args.length ) { |
| |
270
| + options = $.widget.extend.apply( null, [ options ].concat( args ) ); |
| |
271
| + } |
| |
272
| + |
| |
273
| + this.each( function() { |
| |
274
| + var instance = $.data( this, fullName ); |
| |
275
| + if ( instance ) { |
| |
276
| + instance.option( options || {} ); |
| |
277
| + if ( instance._init ) { |
| |
278
| + instance._init(); |
| |
279
| + } |
| |
280
| + } else { |
| |
281
| + $.data( this, fullName, new object( options, this ) ); |
| |
282
| + } |
| |
283
| + } ); |
| |
284
| + } |
| |
285
| + |
| |
286
| + return returnValue; |
| |
287
| + }; |
| |
288
| +}; |
| |
289
| + |
| |
290
| +$.Widget = function( /* options, element */ ) {}; |
| |
291
| +$.Widget._childConstructors = []; |
| |
292
| + |
| |
293
| +$.Widget.prototype = { |
| |
294
| + widgetName: "widget", |
| |
295
| + widgetEventPrefix: "", |
| |
296
| + defaultElement: "<div>", |
| |
297
| + |
| |
298
| + options: { |
| |
299
| + classes: {}, |
| |
300
| + disabled: false, |
| |
301
| + |
| |
302
| + // Callbacks |
| |
303
| + create: null |
| |
304
| + }, |
| |
305
| + |
| |
306
| + _createWidget: function( options, element ) { |
| |
307
| + element = $( element || this.defaultElement || this )[ 0 ]; |
| |
308
| + this.element = $( element ); |
| |
309
| + this.uuid = widgetUuid++; |
| |
310
| + this.eventNamespace = "." + this.widgetName + this.uuid; |
| |
311
| + |
| |
312
| + this.bindings = $(); |
| |
313
| + this.hoverable = $(); |
| |
314
| + this.focusable = $(); |
| |
315
| + this.classesElementLookup = {}; |
| |
316
| + |
| |
317
| + if ( element !== this ) { |
| |
318
| + $.data( element, this.widgetFullName, this ); |
| |
319
| + this._on( true, this.element, { |
| |
320
| + remove: function( event ) { |
| |
321
| + if ( event.target === element ) { |
| |
322
| + this.destroy(); |
| |
323
| + } |
| |
324
| + } |
| |
325
| + } ); |
| |
326
| + this.document = $( element.style ? |
| |
327
| + |
| |
328
| + // Element within the document |
| |
329
| + element.ownerDocument : |
| |
330
| + |
| |
331
| + // Element is window or document |
| |
332
| + element.document || element ); |
| |
333
| + this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); |
| |
334
| + } |
| |
335
| + |
| |
336
| + this.options = $.widget.extend( {}, |
| |
337
| + this.options, |
| |
338
| + this._getCreateOptions(), |
| |
339
| + options ); |
| |
340
| + |
| |
341
| + this._create(); |
| |
342
| + |
| |
343
| + if ( this.options.disabled ) { |
| |
344
| + this._setOptionDisabled( this.options.disabled ); |
| |
345
| + } |
| |
346
| + |
| |
347
| + this._trigger( "create", null, this._getCreateEventData() ); |
| |
348
| + this._init(); |
| |
349
| + }, |
| |
350
| + |
| |
351
| + _getCreateOptions: function() { |
| |
352
| + return {}; |
| |
353
| + }, |
| |
354
| + |
| |
355
| + _getCreateEventData: $.noop, |
| |
356
| + |
| |
357
| + _create: $.noop, |
| |
358
| + |
| |
359
| + _init: $.noop, |
| |
360
| + |
| |
361
| + destroy: function() { |
| |
362
| + var that = this; |
| |
363
| + |
| |
364
| + this._destroy(); |
| |
365
| + $.each( this.classesElementLookup, function( key, value ) { |
| |
366
| + that._removeClass( value, key ); |
| |
367
| + } ); |
| |
368
| + |
| |
369
| + // We can probably remove the unbind calls in 2.0 |
| |
370
| + // all event bindings should go through this._on() |
| |
371
| + this.element |
| |
372
| + .off( this.eventNamespace ) |
| |
373
| + .removeData( this.widgetFullName ); |
| |
374
| + this.widget() |
| |
375
| + .off( this.eventNamespace ) |
| |
376
| + .removeAttr( "aria-disabled" ); |
| |
377
| + |
| |
378
| + // Clean up events and states |
| |
379
| + this.bindings.off( this.eventNamespace ); |
| |
380
| + }, |
| |
381
| + |
| |
382
| + _destroy: $.noop, |
| |
383
| + |
| |
384
| + widget: function() { |
| |
385
| + return this.element; |
| |
386
| + }, |
| |
387
| + |
| |
388
| + option: function( key, value ) { |
| |
389
| + var options = key; |
| |
390
| + var parts; |
| |
391
| + var curOption; |
| |
392
| + var i; |
| |
393
| + |
| |
394
| + if ( arguments.length === 0 ) { |
| |
395
| + |
| |
396
| + // Don't return a reference to the internal hash |
| |
397
| + return $.widget.extend( {}, this.options ); |
| |
398
| + } |
| |
399
| + |
| |
400
| + if ( typeof key === "string" ) { |
| |
401
| + |
| |
402
| + // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } |
| |
403
| + options = {}; |
| |
404
| + parts = key.split( "." ); |
| |
405
| + key = parts.shift(); |
| |
406
| + if ( parts.length ) { |
| |
407
| + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); |
| |
408
| + for ( i = 0; i < parts.length - 1; i++ ) { |
| |
409
| + curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; |
| |
410
| + curOption = curOption[ parts[ i ] ]; |
| |
411
| + } |
| |
412
| + key = parts.pop(); |
| |
413
| + if ( arguments.length === 1 ) { |
| |
414
| + return curOption[ key ] === undefined ? null : curOption[ key ]; |
| |
415
| + } |
| |
416
| + curOption[ key ] = value; |
| |
417
| + } else { |
| |
418
| + if ( arguments.length === 1 ) { |
| |
419
| + return this.options[ key ] === undefined ? null : this.options[ key ]; |
| |
420
| + } |
| |
421
| + options[ key ] = value; |
| |
422
| + } |
| |
423
| + } |
| |
424
| + |
| |
425
| + this._setOptions( options ); |
| |
426
| + |
| |
427
| + return this; |
| |
428
| + }, |
| |
429
| + |
| |
430
| + _setOptions: function( options ) { |
| |
431
| + var key; |
| |
432
| + |
| |
433
| + for ( key in options ) { |
| |
434
| + this._setOption( key, options[ key ] ); |
| |
435
| + } |
| |
436
| + |
| |
437
| + return this; |
| |
438
| + }, |
| |
439
| + |
| |
440
| + _setOption: function( key, value ) { |
| |
441
| + if ( key === "classes" ) { |
| |
442
| + this._setOptionClasses( value ); |
| |
443
| + } |
| |
444
| + |
| |
445
| + this.options[ key ] = value; |
| |
446
| + |
| |
447
| + if ( key === "disabled" ) { |
| |
448
| + this._setOptionDisabled( value ); |
| |
449
| + } |
| |
450
| + |
| |
451
| + return this; |
| |
452
| + }, |
| |
453
| + |
| |
454
| + _setOptionClasses: function( value ) { |
| |
455
| + var classKey, elements, currentElements; |
| |
456
| + |
| |
457
| + for ( classKey in value ) { |
| |
458
| + currentElements = this.classesElementLookup[ classKey ]; |
| |
459
| + if ( value[ classKey ] === this.options.classes[ classKey ] || |
| |
460
| + !currentElements || |
| |
461
| + !currentElements.length ) { |
| |
462
| + continue; |
| |
463
| + } |
| |
464
| + |
| |
465
| + // We are doing this to create a new jQuery object because the _removeClass() call |
| |
466
| + // on the next line is going to destroy the reference to the current elements being |
| |
467
| + // tracked. We need to save a copy of this collection so that we can add the new classes |
| |
468
| + // below. |
| |
469
| + elements = $( currentElements.get() ); |
| |
470
| + this._removeClass( currentElements, classKey ); |
| |
471
| + |
| |
472
| + // We don't use _addClass() here, because that uses this.options.classes |
| |
473
| + // for generating the string of classes. We want to use the value passed in from |
| |
474
| + // _setOption(), this is the new value of the classes option which was passed to |
| |
475
| + // _setOption(). We pass this value directly to _classes(). |
| |
476
| + elements.addClass( this._classes( { |
| |
477
| + element: elements, |
| |
478
| + keys: classKey, |
| |
479
| + classes: value, |
| |
480
| + add: true |
| |
481
| + } ) ); |
| |
482
| + } |
| |
483
| + }, |
| |
484
| + |
| |
485
| + _setOptionDisabled: function( value ) { |
| |
486
| + this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); |
| |
487
| + |
| |
488
| + // If the widget is becoming disabled, then nothing is interactive |
| |
489
| + if ( value ) { |
| |
490
| + this._removeClass( this.hoverable, null, "ui-state-hover" ); |
| |
491
| + this._removeClass( this.focusable, null, "ui-state-focus" ); |
| |
492
| + } |
| |
493
| + }, |
| |
494
| + |
| |
495
| + enable: function() { |
| |
496
| + return this._setOptions( { disabled: false } ); |
| |
497
| + }, |
| |
498
| + |
| |
499
| + disable: function() { |
| |
500
| + return this._setOptions( { disabled: true } ); |
| |
501
| + }, |
| |
502
| + |
| |
503
| + _classes: function( options ) { |
| |
504
| + var full = []; |
| |
505
| + var that = this; |
| |
506
| + |
| |
507
| + options = $.extend( { |
| |
508
| + element: this.element, |
| |
509
| + classes: this.options.classes || {} |
| |
510
| + }, options ); |
| |
511
| + |
| |
512
| + function processClassString( classes, checkOption ) { |
| |
513
| + var current, i; |
| |
514
| + for ( i = 0; i < classes.length; i++ ) { |
| |
515
| + current = that.classesElementLookup[ classes[ i ] ] || $(); |
| |
516
| + if ( options.add ) { |
| |
517
| + current = $( $.unique( current.get().concat( options.element.get() ) ) ); |
| |
518
| + } else { |
| |
519
| + current = $( current.not( options.element ).get() ); |
| |
520
| + } |
| |
521
| + that.classesElementLookup[ classes[ i ] ] = current; |
| |
522
| + full.push( classes[ i ] ); |
| |
523
| + if ( checkOption && options.classes[ classes[ i ] ] ) { |
| |
524
| + full.push( options.classes[ classes[ i ] ] ); |
| |
525
| + } |
| |
526
| + } |
| |
527
| + } |
| |
528
| + |
| |
529
| + this._on( options.element, { |
| |
530
| + "remove": "_untrackClassesElement" |
| |
531
| + } ); |
| |
532
| + |
| |
533
| + if ( options.keys ) { |
| |
534
| + processClassString( options.keys.match( /\S+/g ) || [], true ); |
| |
535
| + } |
| |
536
| + if ( options.extra ) { |
| |
537
| + processClassString( options.extra.match( /\S+/g ) || [] ); |
| |
538
| + } |
| |
539
| + |
| |
540
| + return full.join( " " ); |
| |
541
| + }, |
| |
542
| + |
| |
543
| + _untrackClassesElement: function( event ) { |
| |
544
| + var that = this; |
| |
545
| + $.each( that.classesElementLookup, function( key, value ) { |
| |
546
| + if ( $.inArray( event.target, value ) !== -1 ) { |
| |
547
| + that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); |
| |
548
| + } |
| |
549
| + } ); |
| |
550
| + }, |
| |
551
| + |
| |
552
| + _removeClass: function( element, keys, extra ) { |
| |
553
| + return this._toggleClass( element, keys, extra, false ); |
| |
554
| + }, |
| |
555
| + |
| |
556
| + _addClass: function( element, keys, extra ) { |
| |
557
| + return this._toggleClass( element, keys, extra, true ); |
| |
558
| + }, |
| |
559
| + |
| |
560
| + _toggleClass: function( element, keys, extra, add ) { |
| |
561
| + add = ( typeof add === "boolean" ) ? add : extra; |
| |
562
| + var shift = ( typeof element === "string" || element === null ), |
| |
563
| + options = { |
| |
564
| + extra: shift ? keys : extra, |
| |
565
| + keys: shift ? element : keys, |
| |
566
| + element: shift ? this.element : element, |
| |
567
| + add: add |
| |
568
| + }; |
| |
569
| + options.element.toggleClass( this._classes( options ), add ); |
| |
570
| + return this; |
| |
571
| + }, |
| |
572
| + |
| |
573
| + _on: function( suppressDisabledCheck, element, handlers ) { |
| |
574
| + var delegateElement; |
| |
575
| + var instance = this; |
| |
576
| + |
| |
577
| + // No suppressDisabledCheck flag, shuffle arguments |
| |
578
| + if ( typeof suppressDisabledCheck !== "boolean" ) { |
| |
579
| + handlers = element; |
| |
580
| + element = suppressDisabledCheck; |
| |
581
| + suppressDisabledCheck = false; |
| |
582
| + } |
| |
583
| + |
| |
584
| + // No element argument, shuffle and use this.element |
| |
585
| + if ( !handlers ) { |
| |
586
| + handlers = element; |
| |
587
| + element = this.element; |
| |
588
| + delegateElement = this.widget(); |
| |
589
| + } else { |
| |
590
| + element = delegateElement = $( element ); |
| |
591
| + this.bindings = this.bindings.add( element ); |
| |
592
| + } |
| |
593
| + |
| |
594
| + $.each( handlers, function( event, handler ) { |
| |
595
| + function handlerProxy() { |
| |
596
| + |
| |
597
| + // Allow widgets to customize the disabled handling |
| |
598
| + // - disabled as an array instead of boolean |
| |
599
| + // - disabled class as method for disabling individual parts |
| |
600
| + if ( !suppressDisabledCheck && |
| |
601
| + ( instance.options.disabled === true || |
| |
602
| + $( this ).hasClass( "ui-state-disabled" ) ) ) { |
| |
603
| + return; |
| |
604
| + } |
| |
605
| + return ( typeof handler === "string" ? instance[ handler ] : handler ) |
| |
606
| + .apply( instance, arguments ); |
| |
607
| + } |
| |
608
| + |
| |
609
| + // Copy the guid so direct unbinding works |
| |
610
| + if ( typeof handler !== "string" ) { |
| |
611
| + handlerProxy.guid = handler.guid = |
| |
612
| + handler.guid || handlerProxy.guid || $.guid++; |
| |
613
| + } |
| |
614
| + |
| |
615
| + var match = event.match( /^([\w:-]*)\s*(.*)$/ ); |
| |
616
| + var eventName = match[ 1 ] + instance.eventNamespace; |
| |
617
| + var selector = match[ 2 ]; |
| |
618
| + |
| |
619
| + if ( selector ) { |
| |
620
| + delegateElement.on( eventName, selector, handlerProxy ); |
| |
621
| + } else { |
| |
622
| + element.on( eventName, handlerProxy ); |
| |
623
| + } |
| |
624
| + } ); |
| |
625
| + }, |
| |
626
| + |
| |
627
| + _off: function( element, eventName ) { |
| |
628
| + eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + |
| |
629
| + this.eventNamespace; |
| |
630
| + element.off( eventName ).off( eventName ); |
| |
631
| + |
| |
632
| + // Clear the stack to avoid memory leaks (#10056) |
| |
633
| + this.bindings = $( this.bindings.not( element ).get() ); |
| |
634
| + this.focusable = $( this.focusable.not( element ).get() ); |
| |
635
| + this.hoverable = $( this.hoverable.not( element ).get() ); |
| |
636
| + }, |
| |
637
| + |
| |
638
| + _delay: function( handler, delay ) { |
| |
639
| + function handlerProxy() { |
| |
640
| + return ( typeof handler === "string" ? instance[ handler ] : handler ) |
| |
641
| + .apply( instance, arguments ); |
| |
642
| + } |
| |
643
| + var instance = this; |
| |
644
| + return setTimeout( handlerProxy, delay || 0 ); |
| |
645
| + }, |
| |
646
| + |
| |
647
| + _hoverable: function( element ) { |
| |
648
| + this.hoverable = this.hoverable.add( element ); |
| |
649
| + this._on( element, { |
| |
650
| + mouseenter: function( event ) { |
| |
651
| + this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); |
| |
652
| + }, |
| |
653
| + mouseleave: function( event ) { |
| |
654
| + this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); |
| |
655
| + } |
| |
656
| + } ); |
| |
657
| + }, |
| |
658
| + |
| |
659
| + _focusable: function( element ) { |
| |
660
| + this.focusable = this.focusable.add( element ); |
| |
661
| + this._on( element, { |
| |
662
| + focusin: function( event ) { |
| |
663
| + this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); |
| |
664
| + }, |
| |
665
| + focusout: function( event ) { |
| |
666
| + this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); |
| |
667
| + } |
| |
668
| + } ); |
| |
669
| + }, |
| |
670
| + |
| |
671
| + _trigger: function( type, event, data ) { |
| |
672
| + var prop, orig; |
| |
673
| + var callback = this.options[ type ]; |
| |
674
| + |
| |
675
| + data = data || {}; |
| |
676
| + event = $.Event( event ); |
| |
677
| + event.type = ( type === this.widgetEventPrefix ? |
| |
678
| + type : |
| |
679
| + this.widgetEventPrefix + type ).toLowerCase(); |
| |
680
| + |
| |
681
| + // The original event may come from any element |
| |
682
| + // so we need to reset the target on the new event |
| |
683
| + event.target = this.element[ 0 ]; |
| |
684
| + |
| |
685
| + // Copy original event properties over to the new event |
| |
686
| + orig = event.originalEvent; |
| |
687
| + if ( orig ) { |
| |
688
| + for ( prop in orig ) { |
| |
689
| + if ( !( prop in event ) ) { |
| |
690
| + event[ prop ] = orig[ prop ]; |
| |
691
| + } |
| |
692
| + } |
| |
693
| + } |
| |
694
| + |
| |
695
| + this.element.trigger( event, data ); |
| |
696
| + return !( $.isFunction( callback ) && |
| |
697
| + callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || |
| |
698
| + event.isDefaultPrevented() ); |
| |
699
| + } |
| |
700
| +}; |
| |
701
| + |
| |
702
| +$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { |
| |
703
| + $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { |
| |
704
| + if ( typeof options === "string" ) { |
| |
705
| + options = { effect: options }; |
| |
706
| + } |
| |
707
| + |
| |
708
| + var hasOptions; |
| |
709
| + var effectName = !options ? |
| |
710
| + method : |
| |
711
| + options === true || typeof options === "number" ? |
| |
712
| + defaultEffect : |
| |
713
| + options.effect || defaultEffect; |
| |
714
| + |
| |
715
| + options = options || {}; |
| |
716
| + if ( typeof options === "number" ) { |
| |
717
| + options = { duration: options }; |
| |
718
| + } |
| |
719
| + |
| |
720
| + hasOptions = !$.isEmptyObject( options ); |
| |
721
| + options.complete = callback; |
| |
722
| + |
| |
723
| + if ( options.delay ) { |
| |
724
| + element.delay( options.delay ); |
| |
725
| + } |
| |
726
| + |
| |
727
| + if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { |
| |
728
| + element[ method ]( options ); |
| |
729
| + } else if ( effectName !== method && element[ effectName ] ) { |
| |
730
| + element[ effectName ]( options.duration, options.easing, callback ); |
| |
731
| + } else { |
| |
732
| + element.queue( function( next ) { |
| |
733
| + $( this )[ method ](); |
| |
734
| + if ( callback ) { |
| |
735
| + callback.call( element[ 0 ] ); |
| |
736
| + } |
| |
737
| + next(); |
| |
738
| + } ); |
| |
739
| + } |
| |
740
| + }; |
| |
741
| +} ); |
| |
742
| + |
| |
743
| +var widget = $.widget; |
| |
744
| + |
| |
745
| + |
| |
746
| +/*! |
| |
747
| + * jQuery UI Position 1.12.1 |
| |
748
| + * http://jqueryui.com |
| |
749
| + * |
| |
750
| + * Copyright jQuery Foundation and other contributors |
| |
751
| + * Released under the MIT license. |
| |
752
| + * http://jquery.org/license |
| |
753
| + * |
| |
754
| + * http://api.jqueryui.com/position/ |
| |
755
| + */ |
| |
756
| + |
| |
757
| +//>>label: Position |
| |
758
| +//>>group: Core |
| |
759
| +//>>description: Positions elements relative to other elements. |
| |
760
| +//>>docs: http://api.jqueryui.com/position/ |
| |
761
| +//>>demos: http://jqueryui.com/position/ |
| |
762
| + |
| |
763
| + |
| |
764
| +( function() { |
| |
765
| +var cachedScrollbarWidth, |
| |
766
| + max = Math.max, |
| |
767
| + abs = Math.abs, |
| |
768
| + rhorizontal = /left|center|right/, |
| |
769
| + rvertical = /top|center|bottom/, |
| |
770
| + roffset = /[\+\-]\d+(\.[\d]+)?%?/, |
| |
771
| + rposition = /^\w+/, |
| |
772
| + rpercent = /%$/, |
| |
773
| + _position = $.fn.position; |
| |
774
| + |
| |
775
| +function getOffsets( offsets, width, height ) { |
| |
776
| + return [ |
| |
777
| + parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), |
| |
778
| + parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) |
| |
779
| + ]; |
| |
780
| +} |
| |
781
| + |
| |
782
| +function parseCss( element, property ) { |
| |
783
| + return parseInt( $.css( element, property ), 10 ) || 0; |
| |
784
| +} |
| |
785
| + |
| |
786
| +function getDimensions( elem ) { |
| |
787
| + var raw = elem[ 0 ]; |
| |
788
| + if ( raw.nodeType === 9 ) { |
| |
789
| + return { |
| |
790
| + width: elem.width(), |
| |
791
| + height: elem.height(), |
| |
792
| + offset: { top: 0, left: 0 } |
| |
793
| + }; |
| |
794
| + } |
| |
795
| + if ( $.isWindow( raw ) ) { |
| |
796
| + return { |
| |
797
| + width: elem.width(), |
| |
798
| + height: elem.height(), |
| |
799
| + offset: { top: elem.scrollTop(), left: elem.scrollLeft() } |
| |
800
| + }; |
| |
801
| + } |
| |
802
| + if ( raw.preventDefault ) { |
| |
803
| + return { |
| |
804
| + width: 0, |
| |
805
| + height: 0, |
| |
806
| + offset: { top: raw.pageY, left: raw.pageX } |
| |
807
| + }; |
| |
808
| + } |
| |
809
| + return { |
| |
810
| + width: elem.outerWidth(), |
| |
811
| + height: elem.outerHeight(), |
| |
812
| + offset: elem.offset() |
| |
813
| + }; |
| |
814
| +} |
| |
815
| + |
| |
816
| +$.position = { |
| |
817
| + scrollbarWidth: function() { |
| |
818
| + if ( cachedScrollbarWidth !== undefined ) { |
| |
819
| + return cachedScrollbarWidth; |
| |
820
| + } |
| |
821
| + var w1, w2, |
| |
822
| + div = $( "<div " + |
| |
823
| + "style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" + |
| |
824
| + "<div style='height:100px;width:auto;'></div></div>" ), |
| |
825
| + innerDiv = div.children()[ 0 ]; |
| |
826
| + |
| |
827
| + $( "body" ).append( div ); |
| |
828
| + w1 = innerDiv.offsetWidth; |
| |
829
| + div.css( "overflow", "scroll" ); |
| |
830
| + |
| |
831
| + w2 = innerDiv.offsetWidth; |
| |
832
| + |
| |
833
| + if ( w1 === w2 ) { |
| |
834
| + w2 = div[ 0 ].clientWidth; |
| |
835
| + } |
| |
836
| + |
| |
837
| + div.remove(); |
| |
838
| + |
| |
839
| + return ( cachedScrollbarWidth = w1 - w2 ); |
| |
840
| + }, |
| |
841
| + getScrollInfo: function( within ) { |
| |
842
| + var overflowX = within.isWindow || within.isDocument ? "" : |
| |
843
| + within.element.css( "overflow-x" ), |
| |
844
| + overflowY = within.isWindow || within.isDocument ? "" : |
| |
845
| + within.element.css( "overflow-y" ), |
| |
846
| + hasOverflowX = overflowX === "scroll" || |
| |
847
| + ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), |
| |
848
| + hasOverflowY = overflowY === "scroll" || |
| |
849
| + ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); |
| |
850
| + return { |
| |
851
| + width: hasOverflowY ? $.position.scrollbarWidth() : 0, |
| |
852
| + height: hasOverflowX ? $.position.scrollbarWidth() : 0 |
| |
853
| + }; |
| |
854
| + }, |
| |
855
| + getWithinInfo: function( element ) { |
| |
856
| + var withinElement = $( element || window ), |
| |
857
| + isWindow = $.isWindow( withinElement[ 0 ] ), |
| |
858
| + isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, |
| |
859
| + hasOffset = !isWindow && !isDocument; |
| |
860
| + return { |
| |
861
| + element: withinElement, |
| |
862
| + isWindow: isWindow, |
| |
863
| + isDocument: isDocument, |
| |
864
| + offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, |
| |
865
| + scrollLeft: withinElement.scrollLeft(), |
| |
866
| + scrollTop: withinElement.scrollTop(), |
| |
867
| + width: withinElement.outerWidth(), |
| |
868
| + height: withinElement.outerHeight() |
| |
869
| + }; |
| |
870
| + } |
| |
871
| +}; |
| |
872
| + |
| |
873
| +$.fn.position = function( options ) { |
| |
874
| + if ( !options || !options.of ) { |
| |
875
| + return _position.apply( this, arguments ); |
| |
876
| + } |
| |
877
| + |
| |
878
| + // Make a copy, we don't want to modify arguments |
| |
879
| + options = $.extend( {}, options ); |
| |
880
| + |
| |
881
| + var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, |
| |
882
| + target = $( options.of ), |
| |
883
| + within = $.position.getWithinInfo( options.within ), |
| |
884
| + scrollInfo = $.position.getScrollInfo( within ), |
| |
885
| + collision = ( options.collision || "flip" ).split( " " ), |
| |
886
| + offsets = {}; |
| |
887
| + |
| |
888
| + dimensions = getDimensions( target ); |
| |
889
| + if ( target[ 0 ].preventDefault ) { |
| |
890
| + |
| |
891
| + // Force left top to allow flipping |
| |
892
| + options.at = "left top"; |
| |
893
| + } |
| |
894
| + targetWidth = dimensions.width; |
| |
895
| + targetHeight = dimensions.height; |
| |
896
| + targetOffset = dimensions.offset; |
| |
897
| + |
| |
898
| + // Clone to reuse original targetOffset later |
| |
899
| + basePosition = $.extend( {}, targetOffset ); |
| |
900
| + |
| |
901
| + // Force my and at to have valid horizontal and vertical positions |
| |
902
| + // if a value is missing or invalid, it will be converted to center |
| |
903
| + $.each( [ "my", "at" ], function() { |
| |
904
| + var pos = ( options[ this ] || "" ).split( " " ), |
| |
905
| + horizontalOffset, |
| |
906
| + verticalOffset; |
| |
907
| + |
| |
908
| + if ( pos.length === 1 ) { |
| |
909
| + pos = rhorizontal.test( pos[ 0 ] ) ? |
| |
910
| + pos.concat( [ "center" ] ) : |
| |
911
| + rvertical.test( pos[ 0 ] ) ? |
| |
912
| + [ "center" ].concat( pos ) : |
| |
913
| + [ "center", "center" ]; |
| |
914
| + } |
| |
915
| + pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; |
| |
916
| + pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; |
| |
917
| + |
| |
918
| + // Calculate offsets |
| |
919
| + horizontalOffset = roffset.exec( pos[ 0 ] ); |
| |
920
| + verticalOffset = roffset.exec( pos[ 1 ] ); |
| |
921
| + offsets[ this ] = [ |
| |
922
| + horizontalOffset ? horizontalOffset[ 0 ] : 0, |
| |
923
| + verticalOffset ? verticalOffset[ 0 ] : 0 |
| |
924
| + ]; |
| |
925
| + |
| |
926
| + // Reduce to just the positions without the offsets |
| |
927
| + options[ this ] = [ |
| |
928
| + rposition.exec( pos[ 0 ] )[ 0 ], |
| |
929
| + rposition.exec( pos[ 1 ] )[ 0 ] |
| |
930
| + ]; |
| |
931
| + } ); |
| |
932
| + |
| |
933
| + // Normalize collision option |
| |
934
| + if ( collision.length === 1 ) { |
| |
935
| + collision[ 1 ] = collision[ 0 ]; |
| |
936
| + } |
| |
937
| + |
| |
938
| + if ( options.at[ 0 ] === "right" ) { |
| |
939
| + basePosition.left += targetWidth; |
| |
940
| + } else if ( options.at[ 0 ] === "center" ) { |
| |
941
| + basePosition.left += targetWidth / 2; |
| |
942
| + } |
| |
943
| + |
| |
944
| + if ( options.at[ 1 ] === "bottom" ) { |
| |
945
| + basePosition.top += targetHeight; |
| |
946
| + } else if ( options.at[ 1 ] === "center" ) { |
| |
947
| + basePosition.top += targetHeight / 2; |
| |
948
| + } |
| |
949
| + |
| |
950
| + atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); |
| |
951
| + basePosition.left += atOffset[ 0 ]; |
| |
952
| + basePosition.top += atOffset[ 1 ]; |
| |
953
| + |
| |
954
| + return this.each( function() { |
| |
955
| + var collisionPosition, using, |
| |
956
| + elem = $( this ), |
| |
957
| + elemWidth = elem.outerWidth(), |
| |
958
| + elemHeight = elem.outerHeight(), |
| |
959
| + marginLeft = parseCss( this, "marginLeft" ), |
| |
960
| + marginTop = parseCss( this, "marginTop" ), |
| |
961
| + collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + |
| |
962
| + scrollInfo.width, |
| |
963
| + collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + |
| |
964
| + scrollInfo.height, |
| |
965
| + position = $.extend( {}, basePosition ), |
| |
966
| + myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); |
| |
967
| + |
| |
968
| + if ( options.my[ 0 ] === "right" ) { |
| |
969
| + position.left -= elemWidth; |
| |
970
| + } else if ( options.my[ 0 ] === "center" ) { |
| |
971
| + position.left -= elemWidth / 2; |
| |
972
| + } |
| |
973
| + |
| |
974
| + if ( options.my[ 1 ] === "bottom" ) { |
| |
975
| + position.top -= elemHeight; |
| |
976
| + } else if ( options.my[ 1 ] === "center" ) { |
| |
977
| + position.top -= elemHeight / 2; |
| |
978
| + } |
| |
979
| + |
| |
980
| + position.left += myOffset[ 0 ]; |
| |
981
| + position.top += myOffset[ 1 ]; |
| |
982
| + |
| |
983
| + collisionPosition = { |
| |
984
| + marginLeft: marginLeft, |
| |
985
| + marginTop: marginTop |
| |
986
| + }; |
| |
987
| + |
| |
988
| + $.each( [ "left", "top" ], function( i, dir ) { |
| |
989
| + if ( $.ui.position[ collision[ i ] ] ) { |
| |
990
| + $.ui.position[ collision[ i ] ][ dir ]( position, { |
| |
991
| + targetWidth: targetWidth, |
| |
992
| + targetHeight: targetHeight, |
| |
993
| + elemWidth: elemWidth, |
| |
994
| + elemHeight: elemHeight, |
| |
995
| + collisionPosition: collisionPosition, |
| |
996
| + collisionWidth: collisionWidth, |
| |
997
| + collisionHeight: collisionHeight, |
| |
998
| + offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], |
| |
999
| + my: options.my, |
| |
1000
| + at: options.at, |
| |
1001
| + within: within, |
| |
1002
| + elem: elem |
| |
1003
| + } ); |
| |
1004
| + } |
| |
1005
| + } ); |
| |
1006
| + |
| |
1007
| + if ( options.using ) { |
| |
1008
| + |
| |
1009
| + // Adds feedback as second argument to using callback, if present |
| |
1010
| + using = function( props ) { |
| |
1011
| + var left = targetOffset.left - position.left, |
| |
1012
| + right = left + targetWidth - elemWidth, |
| |
1013
| + top = targetOffset.top - position.top, |
| |
1014
| + bottom = top + targetHeight - elemHeight, |
| |
1015
| + feedback = { |
| |
1016
| + target: { |
| |
1017
| + element: target, |
| |
1018
| + left: targetOffset.left, |
| |
1019
| + top: targetOffset.top, |
| |
1020
| + width: targetWidth, |
| |
1021
| + height: targetHeight |
| |
1022
| + }, |
| |
1023
| + element: { |
| |
1024
| + element: elem, |
| |
1025
| + left: position.left, |
| |
1026
| + top: position.top, |
| |
1027
| + width: elemWidth, |
| |
1028
| + height: elemHeight |
| |
1029
| + }, |
| |
1030
| + horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", |
| |
1031
| + vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" |
| |
1032
| + }; |
| |
1033
| + if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { |
| |
1034
| + feedback.horizontal = "center"; |
| |
1035
| + } |
| |
1036
| + if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { |
| |
1037
| + feedback.vertical = "middle"; |
| |
1038
| + } |
| |
1039
| + if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { |
| |
1040
| + feedback.important = "horizontal"; |
| |
1041
| + } else { |
| |
1042
| + feedback.important = "vertical"; |
| |
1043
| + } |
| |
1044
| + options.using.call( this, props, feedback ); |
| |
1045
| + }; |
| |
1046
| + } |
| |
1047
| + |
| |
1048
| + elem.offset( $.extend( position, { using: using } ) ); |
| |
1049
| + } ); |
| |
1050
| +}; |
| |
1051
| + |
| |
1052
| +$.ui.position = { |
| |
1053
| + fit: { |
| |
1054
| + left: function( position, data ) { |
| |
1055
| + var within = data.within, |
| |
1056
| + withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, |
| |
1057
| + outerWidth = within.width, |
| |
1058
| + collisionPosLeft = position.left - data.collisionPosition.marginLeft, |
| |
1059
| + overLeft = withinOffset - collisionPosLeft, |
| |
1060
| + overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, |
| |
1061
| + newOverRight; |
| |
1062
| + |
| |
1063
| + // Element is wider than within |
| |
1064
| + if ( data.collisionWidth > outerWidth ) { |
| |
1065
| + |
| |
1066
| + // Element is initially over the left side of within |
| |
1067
| + if ( overLeft > 0 && overRight <= 0 ) { |
| |
1068
| + newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - |
| |
1069
| + withinOffset; |
| |
1070
| + position.left += overLeft - newOverRight; |
| |
1071
| + |
| |
1072
| + // Element is initially over right side of within |
| |
1073
| + } else if ( overRight > 0 && overLeft <= 0 ) { |
| |
1074
| + position.left = withinOffset; |
| |
1075
| + |
| |
1076
| + // Element is initially over both left and right sides of within |
| |
1077
| + } else { |
| |
1078
| + if ( overLeft > overRight ) { |
| |
1079
| + position.left = withinOffset + outerWidth - data.collisionWidth; |
| |
1080
| + } else { |
| |
1081
| + position.left = withinOffset; |
| |
1082
| + } |
| |
1083
| + } |
| |
1084
| + |
| |
1085
| + // Too far left -> align with left edge |
| |
1086
| + } else if ( overLeft > 0 ) { |
| |
1087
| + position.left += overLeft; |
| |
1088
| + |
| |
1089
| + // Too far right -> align with right edge |
| |
1090
| + } else if ( overRight > 0 ) { |
| |
1091
| + position.left -= overRight; |
| |
1092
| + |
| |
1093
| + // Adjust based on position and margin |
| |
1094
| + } else { |
| |
1095
| + position.left = max( position.left - collisionPosLeft, position.left ); |
| |
1096
| + } |
| |
1097
| + }, |
| |
1098
| + top: function( position, data ) { |
| |
1099
| + var within = data.within, |
| |
1100
| + withinOffset = within.isWindow ? within.scrollTop : within.offset.top, |
| |
1101
| + outerHeight = data.within.height, |
| |
1102
| + collisionPosTop = position.top - data.collisionPosition.marginTop, |
| |
1103
| + overTop = withinOffset - collisionPosTop, |
| |
1104
| + overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, |
| |
1105
| + newOverBottom; |
| |
1106
| + |
| |
1107
| + // Element is taller than within |
| |
1108
| + if ( data.collisionHeight > outerHeight ) { |
| |
1109
| + |
| |
1110
| + // Element is initially over the top of within |
| |
1111
| + if ( overTop > 0 && overBottom <= 0 ) { |
| |
1112
| + newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - |
| |
1113
| + withinOffset; |
| |
1114
| + position.top += overTop - newOverBottom; |
| |
1115
| + |
| |
1116
| + // Element is initially over bottom of within |
| |
1117
| + } else if ( overBottom > 0 && overTop <= 0 ) { |
| |
1118
| + position.top = withinOffset; |
| |
1119
| + |
| |
1120
| + // Element is initially over both top and bottom of within |
| |
1121
| + } else { |
| |
1122
| + if ( overTop > overBottom ) { |
| |
1123
| + position.top = withinOffset + outerHeight - data.collisionHeight; |
| |
1124
| + } else { |
| |
1125
| + position.top = withinOffset; |
| |
1126
| + } |
| |
1127
| + } |
| |
1128
| + |
| |
1129
| + // Too far up -> align with top |
| |
1130
| + } else if ( overTop > 0 ) { |
| |
1131
| + position.top += overTop; |
| |
1132
| + |
| |
1133
| + // Too far down -> align with bottom edge |
| |
1134
| + } else if ( overBottom > 0 ) { |
| |
1135
| + position.top -= overBottom; |
| |
1136
| + |
| |
1137
| + // Adjust based on position and margin |
| |
1138
| + } else { |
| |
1139
| + position.top = max( position.top - collisionPosTop, position.top ); |
| |
1140
| + } |
| |
1141
| + } |
| |
1142
| + }, |
| |
1143
| + flip: { |
| |
1144
| + left: function( position, data ) { |
| |
1145
| + var within = data.within, |
| |
1146
| + withinOffset = within.offset.left + within.scrollLeft, |
| |
1147
| + outerWidth = within.width, |
| |
1148
| + offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, |
| |
1149
| + collisionPosLeft = position.left - data.collisionPosition.marginLeft, |
| |
1150
| + overLeft = collisionPosLeft - offsetLeft, |
| |
1151
| + overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, |
| |
1152
| + myOffset = data.my[ 0 ] === "left" ? |
| |
1153
| + -data.elemWidth : |
| |
1154
| + data.my[ 0 ] === "right" ? |
| |
1155
| + data.elemWidth : |
| |
1156
| + 0, |
| |
1157
| + atOffset = data.at[ 0 ] === "left" ? |
| |
1158
| + data.targetWidth : |
| |
1159
| + data.at[ 0 ] === "right" ? |
| |
1160
| + -data.targetWidth : |
| |
1161
| + 0, |
| |
1162
| + offset = -2 * data.offset[ 0 ], |
| |
1163
| + newOverRight, |
| |
1164
| + newOverLeft; |
| |
1165
| + |
| |
1166
| + if ( overLeft < 0 ) { |
| |
1167
| + newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - |
| |
1168
| + outerWidth - withinOffset; |
| |
1169
| + if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { |
| |
1170
| + position.left += myOffset + atOffset + offset; |
| |
1171
| + } |
| |
1172
| + } else if ( overRight > 0 ) { |
| |
1173
| + newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + |
| |
1174
| + atOffset + offset - offsetLeft; |
| |
1175
| + if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { |
| |
1176
| + position.left += myOffset + atOffset + offset; |
| |
1177
| + } |
| |
1178
| + } |
| |
1179
| + }, |
| |
1180
| + top: function( position, data ) { |
| |
1181
| + var within = data.within, |
| |
1182
| + withinOffset = within.offset.top + within.scrollTop, |
| |
1183
| + outerHeight = within.height, |
| |
1184
| + offsetTop = within.isWindow ? within.scrollTop : within.offset.top, |
| |
1185
| + collisionPosTop = position.top - data.collisionPosition.marginTop, |
| |
1186
| + overTop = collisionPosTop - offsetTop, |
| |
1187
| + overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, |
| |
1188
| + top = data.my[ 1 ] === "top", |
| |
1189
| + myOffset = top ? |
| |
1190
| + -data.elemHeight : |
| |
1191
| + data.my[ 1 ] === "bottom" ? |
| |
1192
| + data.elemHeight : |
| |
1193
| + 0, |
| |
1194
| + atOffset = data.at[ 1 ] === "top" ? |
| |
1195
| + data.targetHeight : |
| |
1196
| + data.at[ 1 ] === "bottom" ? |
| |
1197
| + -data.targetHeight : |
| |
1198
| + 0, |
| |
1199
| + offset = -2 * data.offset[ 1 ], |
| |
1200
| + newOverTop, |
| |
1201
| + newOverBottom; |
| |
1202
| + if ( overTop < 0 ) { |
| |
1203
| + newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - |
| |
1204
| + outerHeight - withinOffset; |
| |
1205
| + if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { |
| |
1206
| + position.top += myOffset + atOffset + offset; |
| |
1207
| + } |
| |
1208
| + } else if ( overBottom > 0 ) { |
| |
1209
| + newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + |
| |
1210
| + offset - offsetTop; |
| |
1211
| + if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { |
| |
1212
| + position.top += myOffset + atOffset + offset; |
| |
1213
| + } |
| |
1214
| + } |
| |
1215
| + } |
| |
1216
| + }, |
| |
1217
| + flipfit: { |
| |
1218
| + left: function() { |
| |
1219
| + $.ui.position.flip.left.apply( this, arguments ); |
| |
1220
| + $.ui.position.fit.left.apply( this, arguments ); |
| |
1221
| + }, |
| |
1222
| + top: function() { |
| |
1223
| + $.ui.position.flip.top.apply( this, arguments ); |
| |
1224
| + $.ui.position.fit.top.apply( this, arguments ); |
| |
1225
| + } |
| |
1226
| + } |
| |
1227
| +}; |
| |
1228
| + |
| |
1229
| +} )(); |
| |
1230
| + |
| |
1231
| +var position = $.ui.position; |
| |
1232
| + |
| |
1233
| + |
| |
1234
| +/*! |
| |
1235
| + * jQuery UI :data 1.12.1 |
| |
1236
| + * http://jqueryui.com |
| |
1237
| + * |
| |
1238
| + * Copyright jQuery Foundation and other contributors |
| |
1239
| + * Released under the MIT license. |
| |
1240
| + * http://jquery.org/license |
| |
1241
| + */ |
| |
1242
| + |
| |
1243
| +//>>label: :data Selector |
| |
1244
| +//>>group: Core |
| |
1245
| +//>>description: Selects elements which have data stored under the specified key. |
| |
1246
| +//>>docs: http://api.jqueryui.com/data-selector/ |
| |
1247
| + |
| |
1248
| + |
| |
1249
| +var data = $.extend( $.expr[ ":" ], { |
| |
1250
| + data: $.expr.createPseudo ? |
| |
1251
| + $.expr.createPseudo( function( dataName ) { |
| |
1252
| + return function( elem ) { |
| |
1253
| + return !!$.data( elem, dataName ); |
| |
1254
| + }; |
| |
1255
| + } ) : |
| |
1256
| + |
| |
1257
| + // Support: jQuery <1.8 |
| |
1258
| + function( elem, i, match ) { |
| |
1259
| + return !!$.data( elem, match[ 3 ] ); |
| |
1260
| + } |
| |
1261
| +} ); |
| |
1262
| + |
| |
1263
| +/*! |
| |
1264
| + * jQuery UI Disable Selection 1.12.1 |
| |
1265
| + * http://jqueryui.com |
| |
1266
| + * |
| |
1267
| + * Copyright jQuery Foundation and other contributors |
| |
1268
| + * Released under the MIT license. |
| |
1269
| + * http://jquery.org/license |
| |
1270
| + */ |
| |
1271
| + |
| |
1272
| +//>>label: disableSelection |
| |
1273
| +//>>group: Core |
| |
1274
| +//>>description: Disable selection of text content within the set of matched elements. |
| |
1275
| +//>>docs: http://api.jqueryui.com/disableSelection/ |
| |
1276
| + |
| |
1277
| +// This file is deprecated |
| |
1278
| + |
| |
1279
| + |
| |
1280
| +var disableSelection = $.fn.extend( { |
| |
1281
| + disableSelection: ( function() { |
| |
1282
| + var eventType = "onselectstart" in document.createElement( "div" ) ? |
| |
1283
| + "selectstart" : |
| |
1284
| + "mousedown"; |
| |
1285
| + |
| |
1286
| + return function() { |
| |
1287
| + return this.on( eventType + ".ui-disableSelection", function( event ) { |
| |
1288
| + event.preventDefault(); |
| |
1289
| + } ); |
| |
1290
| + }; |
| |
1291
| + } )(), |
| |
1292
| + |
| |
1293
| + enableSelection: function() { |
| |
1294
| + return this.off( ".ui-disableSelection" ); |
| |
1295
| + } |
| |
1296
| +} ); |
| |
1297
| + |
| |
1298
| + |
| |
1299
| +/*! |
| |
1300
| + * jQuery UI Focusable 1.12.1 |
| |
1301
| + * http://jqueryui.com |
| |
1302
| + * |
| |
1303
| + * Copyright jQuery Foundation and other contributors |
| |
1304
| + * Released under the MIT license. |
| |
1305
| + * http://jquery.org/license |
| |
1306
| + */ |
| |
1307
| + |
| |
1308
| +//>>label: :focusable Selector |
| |
1309
| +//>>group: Core |
| |
1310
| +//>>description: Selects elements which can be focused. |
| |
1311
| +//>>docs: http://api.jqueryui.com/focusable-selector/ |
| |
1312
| + |
| |
1313
| + |
| |
1314
| + |
| |
1315
| +// Selectors |
| |
1316
| +$.ui.focusable = function( element, hasTabindex ) { |
| |
1317
| + var map, mapName, img, focusableIfVisible, fieldset, |
| |
1318
| + nodeName = element.nodeName.toLowerCase(); |
| |
1319
| + |
| |
1320
| + if ( "area" === nodeName ) { |
| |
1321
| + map = element.parentNode; |
| |
1322
| + mapName = map.name; |
| |
1323
| + if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { |
| |
1324
| + return false; |
| |
1325
| + } |
| |
1326
| + img = $( "img[usemap='#" + mapName + "']" ); |
| |
1327
| + return img.length > 0 && img.is( ":visible" ); |
| |
1328
| + } |
| |
1329
| + |
| |
1330
| + if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { |
| |
1331
| + focusableIfVisible = !element.disabled; |
| |
1332
| + |
| |
1333
| + if ( focusableIfVisible ) { |
| |
1334
| + |
| |
1335
| + // Form controls within a disabled fieldset are disabled. |
| |
1336
| + // However, controls within the fieldset's legend do not get disabled. |
| |
1337
| + // Since controls generally aren't placed inside legends, we skip |
| |
1338
| + // this portion of the check. |
| |
1339
| + fieldset = $( element ).closest( "fieldset" )[ 0 ]; |
| |
1340
| + if ( fieldset ) { |
| |
1341
| + focusableIfVisible = !fieldset.disabled; |
| |
1342
| + } |
| |
1343
| + } |
| |
1344
| + } else if ( "a" === nodeName ) { |
| |
1345
| + focusableIfVisible = element.href || hasTabindex; |
| |
1346
| + } else { |
| |
1347
| + focusableIfVisible = hasTabindex; |
| |
1348
| + } |
| |
1349
| + |
| |
1350
| + return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); |
| |
1351
| +}; |
| |
1352
| + |
| |
1353
| +// Support: IE 8 only |
| |
1354
| +// IE 8 doesn't resolve inherit to visible/hidden for computed values |
| |
1355
| +function visible( element ) { |
| |
1356
| + var visibility = element.css( "visibility" ); |
| |
1357
| + while ( visibility === "inherit" ) { |
| |
1358
| + element = element.parent(); |
| |
1359
| + visibility = element.css( "visibility" ); |
| |
1360
| + } |
| |
1361
| + return visibility !== "hidden"; |
| |
1362
| +} |
| |
1363
| + |
| |
1364
| +$.extend( $.expr[ ":" ], { |
| |
1365
| + focusable: function( element ) { |
| |
1366
| + return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); |
| |
1367
| + } |
| |
1368
| +} ); |
| |
1369
| + |
| |
1370
| +var focusable = $.ui.focusable; |
| |
1371
| + |
| |
1372
| + |
| |
1373
| + |
| |
1374
| + |
| |
1375
| +// Support: IE8 Only |
| |
1376
| +// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop |
| |
1377
| +// with a string, so we need to find the proper form. |
| |
1378
| +var form = $.fn.form = function() { |
| |
1379
| + return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form ); |
| |
1380
| +}; |
| |
1381
| + |
| |
1382
| + |
| |
1383
| +/*! |
| |
1384
| + * jQuery UI Form Reset Mixin 1.12.1 |
| |
1385
| + * http://jqueryui.com |
| |
1386
| + * |
| |
1387
| + * Copyright jQuery Foundation and other contributors |
| |
1388
| + * Released under the MIT license. |
| |
1389
| + * http://jquery.org/license |
| |
1390
| + */ |
| |
1391
| + |
| |
1392
| +//>>label: Form Reset Mixin |
| |
1393
| +//>>group: Core |
| |
1394
| +//>>description: Refresh input widgets when their form is reset |
| |
1395
| +//>>docs: http://api.jqueryui.com/form-reset-mixin/ |
| |
1396
| + |
| |
1397
| + |
| |
1398
| + |
| |
1399
| +var formResetMixin = $.ui.formResetMixin = { |
| |
1400
| + _formResetHandler: function() { |
| |
1401
| + var form = $( this ); |
| |
1402
| + |
| |
1403
| + // Wait for the form reset to actually happen before refreshing |
| |
1404
| + setTimeout( function() { |
| |
1405
| + var instances = form.data( "ui-form-reset-instances" ); |
| |
1406
| + $.each( instances, function() { |
| |
1407
| + this.refresh(); |
| |
1408
| + } ); |
| |
1409
| + } ); |
| |
1410
| + }, |
| |
1411
| + |
| |
1412
| + _bindFormResetHandler: function() { |
| |
1413
| + this.form = this.element.form(); |
| |
1414
| + if ( !this.form.length ) { |
| |
1415
| + return; |
| |
1416
| + } |
| |
1417
| + |
| |
1418
| + var instances = this.form.data( "ui-form-reset-instances" ) || []; |
| |
1419
| + if ( !instances.length ) { |
| |
1420
| + |
| |
1421
| + // We don't use _on() here because we use a single event handler per form |
| |
1422
| + this.form.on( "reset.ui-form-reset", this._formResetHandler ); |
| |
1423
| + } |
| |
1424
| + instances.push( this ); |
| |
1425
| + this.form.data( "ui-form-reset-instances", instances ); |
| |
1426
| + }, |
| |
1427
| + |
| |
1428
| + _unbindFormResetHandler: function() { |
| |
1429
| + if ( !this.form.length ) { |
| |
1430
| + return; |
| |
1431
| + } |
| |
1432
| + |
| |
1433
| + var instances = this.form.data( "ui-form-reset-instances" ); |
| |
1434
| + instances.splice( $.inArray( this, instances ), 1 ); |
| |
1435
| + if ( instances.length ) { |
| |
1436
| + this.form.data( "ui-form-reset-instances", instances ); |
| |
1437
| + } else { |
| |
1438
| + this.form |
| |
1439
| + .removeData( "ui-form-reset-instances" ) |
| |
1440
| + .off( "reset.ui-form-reset" ); |
| |
1441
| + } |
| |
1442
| + } |
| |
1443
| +}; |
| |
1444
| + |
| |
1445
| + |
| |
1446
| +/*! |
| |
1447
| + * jQuery UI Support for jQuery core 1.7.x 1.12.1 |
| |
1448
| + * http://jqueryui.com |
| |
1449
| + * |
| |
1450
| + * Copyright jQuery Foundation and other contributors |
| |
1451
| + * Released under the MIT license. |
| |
1452
| + * http://jquery.org/license |
| |
1453
| + * |
| |
1454
| + */ |
| |
1455
| + |
| |
1456
| +//>>label: jQuery 1.7 Support |
| |
1457
| +//>>group: Core |
| |
1458
| +//>>description: Support version 1.7.x of jQuery core |
| |
1459
| + |
| |
1460
| + |
| |
1461
| + |
| |
1462
| +// Support: jQuery 1.7 only |
| |
1463
| +// Not a great way to check versions, but since we only support 1.7+ and only |
| |
1464
| +// need to detect <1.8, this is a simple check that should suffice. Checking |
| |
1465
| +// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0 |
| |
1466
| +// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting |
| |
1467
| +// 1.7 anymore). See #11197 for why we're not using feature detection. |
| |
1468
| +if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) { |
| |
1469
| + |
| |
1470
| + // Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight() |
| |
1471
| + // Unlike jQuery Core 1.8+, these only support numeric values to set the |
| |
1472
| + // dimensions in pixels |
| |
1473
| + $.each( [ "Width", "Height" ], function( i, name ) { |
| |
1474
| + var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], |
| |
1475
| + type = name.toLowerCase(), |
| |
1476
| + orig = { |
| |
1477
| + innerWidth: $.fn.innerWidth, |
| |
1478
| + innerHeight: $.fn.innerHeight, |
| |
1479
| + outerWidth: $.fn.outerWidth, |
| |
1480
| + outerHeight: $.fn.outerHeight |
| |
1481
| + }; |
| |
1482
| + |
| |
1483
| + function reduce( elem, size, border, margin ) { |
| |
1484
| + $.each( side, function() { |
| |
1485
| + size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; |
| |
1486
| + if ( border ) { |
| |
1487
| + size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; |
| |
1488
| + } |
| |
1489
| + if ( margin ) { |
| |
1490
| + size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; |
| |
1491
| + } |
| |
1492
| + } ); |
| |
1493
| + return size; |
| |
1494
| + } |
| |
1495
| + |
| |
1496
| + $.fn[ "inner" + name ] = function( size ) { |
| |
1497
| + if ( size === undefined ) { |
| |
1498
| + return orig[ "inner" + name ].call( this ); |
| |
1499
| + } |
| |
1500
| + |
| |
1501
| + return this.each( function() { |
| |
1502
| + $( this ).css( type, reduce( this, size ) + "px" ); |
| |
1503
| + } ); |
| |
1504
| + }; |
| |
1505
| + |
| |
1506
| + $.fn[ "outer" + name ] = function( size, margin ) { |
| |
1507
| + if ( typeof size !== "number" ) { |
| |
1508
| + return orig[ "outer" + name ].call( this, size ); |
| |
1509
| + } |
| |
1510
| + |
| |
1511
| + return this.each( function() { |
| |
1512
| + $( this ).css( type, reduce( this, size, true, margin ) + "px" ); |
| |
1513
| + } ); |
| |
1514
| + }; |
| |
1515
| + } ); |
| |
1516
| + |
| |
1517
| + $.fn.addBack = function( selector ) { |
| |
1518
| + return this.add( selector == null ? |
| |
1519
| + this.prevObject : this.prevObject.filter( selector ) |
| |
1520
| + ); |
| |
1521
| + }; |
| |
1522
| +} |
| |
1523
| + |
| |
1524
| +; |
| |
1525
| +/*! |
| |
1526
| + * jQuery UI Keycode 1.12.1 |
| |
1527
| + * http://jqueryui.com |
| |
1528
| + * |
| |
1529
| + * Copyright jQuery Foundation and other contributors |
| |
1530
| + * Released under the MIT license. |
| |
1531
| + * http://jquery.org/license |
| |
1532
| + */ |
| |
1533
| + |
| |
1534
| +//>>label: Keycode |
| |
1535
| +//>>group: Core |
| |
1536
| +//>>description: Provide keycodes as keynames |
| |
1537
| +//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ |
| |
1538
| + |
| |
1539
| + |
| |
1540
| +var keycode = $.ui.keyCode = { |
| |
1541
| + BACKSPACE: 8, |
| |
1542
| + COMMA: 188, |
| |
1543
| + DELETE: 46, |
| |
1544
| + DOWN: 40, |
| |
1545
| + END: 35, |
| |
1546
| + ENTER: 13, |
| |
1547
| + ESCAPE: 27, |
| |
1548
| + HOME: 36, |
| |
1549
| + LEFT: 37, |
| |
1550
| + PAGE_DOWN: 34, |
| |
1551
| + PAGE_UP: 33, |
| |
1552
| + PERIOD: 190, |
| |
1553
| + RIGHT: 39, |
| |
1554
| + SPACE: 32, |
| |
1555
| + TAB: 9, |
| |
1556
| + UP: 38 |
| |
1557
| +}; |
| |
1558
| + |
| |
1559
| + |
| |
1560
| + |
| |
1561
| + |
| |
1562
| +// Internal use only |
| |
1563
| +var escapeSelector = $.ui.escapeSelector = ( function() { |
| |
1564
| + var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g; |
| |
1565
| + return function( selector ) { |
| |
1566
| + return selector.replace( selectorEscape, "\\$1" ); |
| |
1567
| + }; |
| |
1568
| +} )(); |
| |
1569
| + |
| |
1570
| + |
| |
1571
| +/*! |
| |
1572
| + * jQuery UI Labels 1.12.1 |
| |
1573
| + * http://jqueryui.com |
| |
1574
| + * |
| |
1575
| + * Copyright jQuery Foundation and other contributors |
| |
1576
| + * Released under the MIT license. |
| |
1577
| + * http://jquery.org/license |
| |
1578
| + */ |
| |
1579
| + |
| |
1580
| +//>>label: labels |
| |
1581
| +//>>group: Core |
| |
1582
| +//>>description: Find all the labels associated with a given input |
| |
1583
| +//>>docs: http://api.jqueryui.com/labels/ |
| |
1584
| + |
| |
1585
| + |
| |
1586
| + |
| |
1587
| +var labels = $.fn.labels = function() { |
| |
1588
| + var ancestor, selector, id, labels, ancestors; |
| |
1589
| + |
| |
1590
| + // Check control.labels first |
| |
1591
| + if ( this[ 0 ].labels && this[ 0 ].labels.length ) { |
| |
1592
| + return this.pushStack( this[ 0 ].labels ); |
| |
1593
| + } |
| |
1594
| + |
| |
1595
| + // Support: IE <= 11, FF <= 37, Android <= 2.3 only |
| |
1596
| + // Above browsers do not support control.labels. Everything below is to support them |
| |
1597
| + // as well as document fragments. control.labels does not work on document fragments |
| |
1598
| + labels = this.eq( 0 ).parents( "label" ); |
| |
1599
| + |
| |
1600
| + // Look for the label based on the id |
| |
1601
| + id = this.attr( "id" ); |
| |
1602
| + if ( id ) { |
| |
1603
| + |
| |
1604
| + // We don't search against the document in case the element |
| |
1605
| + // is disconnected from the DOM |
| |
1606
| + ancestor = this.eq( 0 ).parents().last(); |
| |
1607
| + |
| |
1608
| + // Get a full set of top level ancestors |
| |
1609
| + ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); |
| |
1610
| + |
| |
1611
| + // Create a selector for the label based on the id |
| |
1612
| + selector = "label[for='" + $.ui.escapeSelector( id ) + "']"; |
| |
1613
| + |
| |
1614
| + labels = labels.add( ancestors.find( selector ).addBack( selector ) ); |
| |
1615
| + |
| |
1616
| + } |
| |
1617
| + |
| |
1618
| + // Return whatever we have found for labels |
| |
1619
| + return this.pushStack( labels ); |
| |
1620
| +}; |
| |
1621
| + |
| |
1622
| + |
| |
1623
| +/*! |
| |
1624
| + * jQuery UI Scroll Parent 1.12.1 |
| |
1625
| + * http://jqueryui.com |
| |
1626
| + * |
| |
1627
| + * Copyright jQuery Foundation and other contributors |
| |
1628
| + * Released under the MIT license. |
| |
1629
| + * http://jquery.org/license |
| |
1630
| + */ |
| |
1631
| + |
| |
1632
| +//>>label: scrollParent |
| |
1633
| +//>>group: Core |
| |
1634
| +//>>description: Get the closest ancestor element that is scrollable. |
| |
1635
| +//>>docs: http://api.jqueryui.com/scrollParent/ |
| |
1636
| + |
| |
1637
| + |
| |
1638
| + |
| |
1639
| +var scrollParent = $.fn.scrollParent = function( includeHidden ) { |
| |
1640
| + var position = this.css( "position" ), |
| |
1641
| + excludeStaticParent = position === "absolute", |
| |
1642
| + overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, |
| |
1643
| + scrollParent = this.parents().filter( function() { |
| |
1644
| + var parent = $( this ); |
| |
1645
| + if ( excludeStaticParent && parent.css( "position" ) === "static" ) { |
| |
1646
| + return false; |
| |
1647
| + } |
| |
1648
| + return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + |
| |
1649
| + parent.css( "overflow-x" ) ); |
| |
1650
| + } ).eq( 0 ); |
| |
1651
| + |
| |
1652
| + return position === "fixed" || !scrollParent.length ? |
| |
1653
| + $( this[ 0 ].ownerDocument || document ) : |
| |
1654
| + scrollParent; |
| |
1655
| +}; |
| |
1656
| + |
| |
1657
| + |
| |
1658
| +/*! |
| |
1659
| + * jQuery UI Tabbable 1.12.1 |
| |
1660
| + * http://jqueryui.com |
| |
1661
| + * |
| |
1662
| + * Copyright jQuery Foundation and other contributors |
| |
1663
| + * Released under the MIT license. |
| |
1664
| + * http://jquery.org/license |
| |
1665
| + */ |
| |
1666
| + |
| |
1667
| +//>>label: :tabbable Selector |
| |
1668
| +//>>group: Core |
| |
1669
| +//>>description: Selects elements which can be tabbed to. |
| |
1670
| +//>>docs: http://api.jqueryui.com/tabbable-selector/ |
| |
1671
| + |
| |
1672
| + |
| |
1673
| + |
| |
1674
| +var tabbable = $.extend( $.expr[ ":" ], { |
| |
1675
| + tabbable: function( element ) { |
| |
1676
| + var tabIndex = $.attr( element, "tabindex" ), |
| |
1677
| + hasTabindex = tabIndex != null; |
| |
1678
| + return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); |
| |
1679
| + } |
| |
1680
| +} ); |
| |
1681
| + |
| |
1682
| + |
| |
1683
| +/*! |
| |
1684
| + * jQuery UI Unique ID 1.12.1 |
| |
1685
| + * http://jqueryui.com |
| |
1686
| + * |
| |
1687
| + * Copyright jQuery Foundation and other contributors |
| |
1688
| + * Released under the MIT license. |
| |
1689
| + * http://jquery.org/license |
| |
1690
| + */ |
| |
1691
| + |
| |
1692
| +//>>label: uniqueId |
| |
1693
| +//>>group: Core |
| |
1694
| +//>>description: Functions to generate and remove uniqueId's |
| |
1695
| +//>>docs: http://api.jqueryui.com/uniqueId/ |
| |
1696
| + |
| |
1697
| + |
| |
1698
| + |
| |
1699
| +var uniqueId = $.fn.extend( { |
| |
1700
| + uniqueId: ( function() { |
| |
1701
| + var uuid = 0; |
| |
1702
| + |
| |
1703
| + return function() { |
| |
1704
| + return this.each( function() { |
| |
1705
| + if ( !this.id ) { |
| |
1706
| + this.id = "ui-id-" + ( ++uuid ); |
| |
1707
| + } |
| |
1708
| + } ); |
| |
1709
| + }; |
| |
1710
| + } )(), |
| |
1711
| + |
| |
1712
| + removeUniqueId: function() { |
| |
1713
| + return this.each( function() { |
| |
1714
| + if ( /^ui-id-\d+$/.test( this.id ) ) { |
| |
1715
| + $( this ).removeAttr( "id" ); |
| |
1716
| + } |
| |
1717
| + } ); |
| |
1718
| + } |
| |
1719
| +} ); |
| |
1720
| + |
| |
1721
| + |
| |
1722
| +// jscs:disable maximumLineLength |
| |
1723
| +/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */ |
| |
1724
| +/*! |
| |
1725
| + * jQuery UI Datepicker 1.12.1 |
| |
1726
| + * http://jqueryui.com |
| |
1727
| + * |
| |
1728
| + * Copyright jQuery Foundation and other contributors |
| |
1729
| + * Released under the MIT license. |
| |
1730
| + * http://jquery.org/license |
| |
1731
| + */ |
| |
1732
| + |
| |
1733
| +//>>label: Datepicker |
| |
1734
| +//>>group: Widgets |
| |
1735
| +//>>description: Displays a calendar from an input or inline for selecting dates. |
| |
1736
| +//>>docs: http://api.jqueryui.com/datepicker/ |
| |
1737
| +//>>demos: http://jqueryui.com/datepicker/ |
| |
1738
| +//>>css.structure: ../../themes/base/core.css |
| |
1739
| +//>>css.structure: ../../themes/base/datepicker.css |
| |
1740
| +//>>css.theme: ../../themes/base/theme.css |
| |
1741
| + |
| |
1742
| + |
| |
1743
| + |
| |
1744
| +$.extend( $.ui, { datepicker: { version: "1.12.1" } } ); |
| |
1745
| + |
| |
1746
| +var datepicker_instActive; |
| |
1747
| + |
| |
1748
| +function datepicker_getZindex( elem ) { |
| |
1749
| + var position, value; |
| |
1750
| + while ( elem.length && elem[ 0 ] !== document ) { |
| |
1751
| + |
| |
1752
| + // Ignore z-index if position is set to a value where z-index is ignored by the browser |
| |
1753
| + // This makes behavior of this function consistent across browsers |
| |
1754
| + // WebKit always returns auto if the element is positioned |
| |
1755
| + position = elem.css( "position" ); |
| |
1756
| + if ( position === "absolute" || position === "relative" || position === "fixed" ) { |
| |
1757
| + |
| |
1758
| + // IE returns 0 when zIndex is not specified |
| |
1759
| + // other browsers return a string |
| |
1760
| + // we ignore the case of nested elements with an explicit value of 0 |
| |
1761
| + // <div style="z-index: -10;"><div style="z-index: 0;"></div></div> |
| |
1762
| + value = parseInt( elem.css( "zIndex" ), 10 ); |
| |
1763
| + if ( !isNaN( value ) && value !== 0 ) { |
| |
1764
| + return value; |
| |
1765
| + } |
| |
1766
| + } |
| |
1767
| + elem = elem.parent(); |
| |
1768
| + } |
| |
1769
| + |
| |
1770
| + return 0; |
| |
1771
| +} |
| |
1772
| +/* Date picker manager. |
| |
1773
| + Use the singleton instance of this class, $.datepicker, to interact with the date picker. |
| |
1774
| + Settings for (groups of) date pickers are maintained in an instance object, |
| |
1775
| + allowing multiple different settings on the same page. */ |
| |
1776
| + |
| |
1777
| +function Datepicker() { |
| |
1778
| + this._curInst = null; // The current instance in use |
| |
1779
| + this._keyEvent = false; // If the last event was a key event |
| |
1780
| + this._disabledInputs = []; // List of date picker inputs that have been disabled |
| |
1781
| + this._datepickerShowing = false; // True if the popup picker is showing , false if not |
| |
1782
| + this._inDialog = false; // True if showing within a "dialog", false if not |
| |
1783
| + this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division |
| |
1784
| + this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class |
| |
1785
| + this._appendClass = "ui-datepicker-append"; // The name of the append marker class |
| |
1786
| + this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class |
| |
1787
| + this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class |
| |
1788
| + this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class |
| |
1789
| + this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class |
| |
1790
| + this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class |
| |
1791
| + this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class |
| |
1792
| + this.regional = []; // Available regional settings, indexed by language code |
| |
1793
| + this.regional[ "" ] = { // Default regional settings |
| |
1794
| + closeText: "Done", // Display text for close link |
| |
1795
| + prevText: "Prev", // Display text for previous month link |
| |
1796
| + nextText: "Next", // Display text for next month link |
| |
1797
| + currentText: "Today", // Display text for current month link |
| |
1798
| + monthNames: [ "January","February","March","April","May","June", |
| |
1799
| + "July","August","September","October","November","December" ], // Names of months for drop-down and formatting |
| |
1800
| + monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting |
| |
1801
| + dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting |
| |
1802
| + dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting |
| |
1803
| + dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday |
| |
1804
| + weekHeader: "Wk", // Column header for week of the year |
| |
1805
| + dateFormat: "mm/dd/yy", // See format options on parseDate |
| |
1806
| + firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... |
| |
1807
| + isRTL: false, // True if right-to-left language, false if left-to-right |
| |
1808
| + showMonthAfterYear: false, // True if the year select precedes month, false for month then year |
| |
1809
| + yearSuffix: "" // Additional text to append to the year in the month headers |
| |
1810
| + }; |
| |
1811
| + this._defaults = { // Global defaults for all the date picker instances |
| |
1812
| + showOn: "focus", // "focus" for popup on focus, |
| |
1813
| + // "button" for trigger button, or "both" for either |
| |
1814
| + showAnim: "fadeIn", // Name of jQuery animation for popup |
| |
1815
| + showOptions: {}, // Options for enhanced animations |
| |
1816
| + defaultDate: null, // Used when field is blank: actual date, |
| |
1817
| + // +/-number for offset from today, null for today |
| |
1818
| + appendText: "", // Display text following the input box, e.g. showing the format |
| |
1819
| + buttonText: "...", // Text for trigger button |
| |
1820
| + buttonImage: "", // URL for trigger button image |
| |
1821
| + buttonImageOnly: false, // True if the image appears alone, false if it appears on a button |
| |
1822
| + hideIfNoPrevNext: false, // True to hide next/previous month links |
| |
1823
| + // if not applicable, false to just disable them |
| |
1824
| + navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links |
| |
1825
| + gotoCurrent: false, // True if today link goes back to current selection instead |
| |
1826
| + changeMonth: false, // True if month can be selected directly, false if only prev/next |
| |
1827
| + changeYear: false, // True if year can be selected directly, false if only prev/next |
| |
1828
| + yearRange: "c-10:c+10", // Range of years to display in drop-down, |
| |
1829
| + // either relative to today's year (-nn:+nn), relative to currently displayed year |
| |
1830
| + // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) |
| |
1831
| + showOtherMonths: false, // True to show dates in other months, false to leave blank |
| |
1832
| + selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable |
| |
1833
| + showWeek: false, // True to show week of the year, false to not show it |
| |
1834
| + calculateWeek: this.iso8601Week, // How to calculate the week of the year, |
| |
1835
| + // takes a Date and returns the number of the week for it |
| |
1836
| + shortYearCutoff: "+10", // Short year values < this are in the current century, |
| |
1837
| + // > this are in the previous century, |
| |
1838
| + // string value starting with "+" for current year + value |
| |
1839
| + minDate: null, // The earliest selectable date, or null for no limit |
| |
1840
| + maxDate: null, // The latest selectable date, or null for no limit |
| |
1841
| + duration: "fast", // Duration of display/closure |
| |
1842
| + beforeShowDay: null, // Function that takes a date and returns an array with |
| |
1843
| + // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "", |
| |
1844
| + // [2] = cell title (optional), e.g. $.datepicker.noWeekends |
| |
1845
| + beforeShow: null, // Function that takes an input field and |
| |
1846
| + // returns a set of custom settings for the date picker |
| |
1847
| + onSelect: null, // Define a callback function when a date is selected |
| |
1848
| + onChangeMonthYear: null, // Define a callback function when the month or year is changed |
| |
1849
| + onClose: null, // Define a callback function when the datepicker is closed |
| |
1850
| + numberOfMonths: 1, // Number of months to show at a time |
| |
1851
| + showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) |
| |
1852
| + stepMonths: 1, // Number of months to step back/forward |
| |
1853
| + stepBigMonths: 12, // Number of months to step back/forward for the big links |
| |
1854
| + altField: "", // Selector for an alternate field to store selected dates into |
| |
1855
| + altFormat: "", // The date format to use for the alternate field |
| |
1856
| + constrainInput: true, // The input is constrained by the current date format |
| |
1857
| + showButtonPanel: false, // True to show button panel, false to not show it |
| |
1858
| + autoSize: false, // True to size the input for the date format, false to leave as is |
| |
1859
| + disabled: false // The initial disabled state |
| |
1860
| + }; |
| |
1861
| + $.extend( this._defaults, this.regional[ "" ] ); |
| |
1862
| + this.regional.en = $.extend( true, {}, this.regional[ "" ] ); |
| |
1863
| + this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en ); |
| |
1864
| + this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ); |
| |
1865
| +} |
| |
1866
| + |
| |
1867
| +$.extend( Datepicker.prototype, { |
| |
1868
| + /* Class name added to elements to indicate already configured with a date picker. */ |
| |
1869
| + markerClassName: "hasDatepicker", |
| |
1870
| + |
| |
1871
| + //Keep track of the maximum number of rows displayed (see #7043) |
| |
1872
| + maxRows: 4, |
| |
1873
| + |
| |
1874
| + // TODO rename to "widget" when switching to widget factory |
| |
1875
| + _widgetDatepicker: function() { |
| |
1876
| + return this.dpDiv; |
| |
1877
| + }, |
| |
1878
| + |
| |
1879
| + /* Override the default settings for all instances of the date picker. |
| |
1880
| + * @param settings object - the new settings to use as defaults (anonymous object) |
| |
1881
| + * @return the manager object |
| |
1882
| + */ |
| |
1883
| + setDefaults: function( settings ) { |
| |
1884
| + datepicker_extendRemove( this._defaults, settings || {} ); |
| |
1885
| + return this; |
| |
1886
| + }, |
| |
1887
| + |
| |
1888
| + /* Attach the date picker to a jQuery selection. |
| |
1889
| + * @param target element - the target input field or division or span |
| |
1890
| + * @param settings object - the new settings to use for this date picker instance (anonymous) |
| |
1891
| + */ |
| |
1892
| + _attachDatepicker: function( target, settings ) { |
| |
1893
| + var nodeName, inline, inst; |
| |
1894
| + nodeName = target.nodeName.toLowerCase(); |
| |
1895
| + inline = ( nodeName === "div" || nodeName === "span" ); |
| |
1896
| + if ( !target.id ) { |
| |
1897
| + this.uuid += 1; |
| |
1898
| + target.id = "dp" + this.uuid; |
| |
1899
| + } |
| |
1900
| + inst = this._newInst( $( target ), inline ); |
| |
1901
| + inst.settings = $.extend( {}, settings || {} ); |
| |
1902
| + if ( nodeName === "input" ) { |
| |
1903
| + this._connectDatepicker( target, inst ); |
| |
1904
| + } else if ( inline ) { |
| |
1905
| + this._inlineDatepicker( target, inst ); |
| |
1906
| + } |
| |
1907
| + }, |
| |
1908
| + |
| |
1909
| + /* Create a new instance object. */ |
| |
1910
| + _newInst: function( target, inline ) { |
| |
1911
| + var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars |
| |
1912
| + return { id: id, input: target, // associated target |
| |
1913
| + selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection |
| |
1914
| + drawMonth: 0, drawYear: 0, // month being drawn |
| |
1915
| + inline: inline, // is datepicker inline or not |
| |
1916
| + dpDiv: ( !inline ? this.dpDiv : // presentation div |
| |
1917
| + datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) }; |
| |
1918
| + }, |
| |
1919
| + |
| |
1920
| + /* Attach the date picker to an input field. */ |
| |
1921
| + _connectDatepicker: function( target, inst ) { |
| |
1922
| + var input = $( target ); |
| |
1923
| + inst.append = $( [] ); |
| |
1924
| + inst.trigger = $( [] ); |
| |
1925
| + if ( input.hasClass( this.markerClassName ) ) { |
| |
1926
| + return; |
| |
1927
| + } |
| |
1928
| + this._attachments( input, inst ); |
| |
1929
| + input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ). |
| |
1930
| + on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp ); |
| |
1931
| + this._autoSize( inst ); |
| |
1932
| + $.data( target, "datepicker", inst ); |
| |
1933
| + |
| |
1934
| + //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) |
| |
1935
| + if ( inst.settings.disabled ) { |
| |
1936
| + this._disableDatepicker( target ); |
| |
1937
| + } |
| |
1938
| + }, |
| |
1939
| + |
| |
1940
| + /* Make attachments based on settings. */ |
| |
1941
| + _attachments: function( input, inst ) { |
| |
1942
| + var showOn, buttonText, buttonImage, |
| |
1943
| + appendText = this._get( inst, "appendText" ), |
| |
1944
| + isRTL = this._get( inst, "isRTL" ); |
| |
1945
| + |
| |
1946
| + if ( inst.append ) { |
| |
1947
| + inst.append.remove(); |
| |
1948
| + } |
| |
1949
| + if ( appendText ) { |
| |
1950
| + inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" ); |
| |
1951
| + input[ isRTL ? "before" : "after" ]( inst.append ); |
| |
1952
| + } |
| |
1953
| + |
| |
1954
| + input.off( "focus", this._showDatepicker ); |
| |
1955
| + |
| |
1956
| + if ( inst.trigger ) { |
| |
1957
| + inst.trigger.remove(); |
| |
1958
| + } |
| |
1959
| + |
| |
1960
| + showOn = this._get( inst, "showOn" ); |
| |
1961
| + if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field |
| |
1962
| + input.on( "focus", this._showDatepicker ); |
| |
1963
| + } |
| |
1964
| + if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked |
| |
1965
| + buttonText = this._get( inst, "buttonText" ); |
| |
1966
| + buttonImage = this._get( inst, "buttonImage" ); |
| |
1967
| + inst.trigger = $( this._get( inst, "buttonImageOnly" ) ? |
| |
1968
| + $( "<img/>" ).addClass( this._triggerClass ). |
| |
1969
| + attr( { src: buttonImage, alt: buttonText, title: buttonText } ) : |
| |
1970
| + $( "<button type='button'></button>" ).addClass( this._triggerClass ). |
| |
1971
| + html( !buttonImage ? buttonText : $( "<img/>" ).attr( |
| |
1972
| + { src:buttonImage, alt:buttonText, title:buttonText } ) ) ); |
| |
1973
| + input[ isRTL ? "before" : "after" ]( inst.trigger ); |
| |
1974
| + inst.trigger.on( "click", function() { |
| |
1975
| + if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) { |
| |
1976
| + $.datepicker._hideDatepicker(); |
| |
1977
| + } else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) { |
| |
1978
| + $.datepicker._hideDatepicker(); |
| |
1979
| + $.datepicker._showDatepicker( input[ 0 ] ); |
| |
1980
| + } else { |
| |
1981
| + $.datepicker._showDatepicker( input[ 0 ] ); |
| |
1982
| + } |
| |
1983
| + return false; |
| |
1984
| + } ); |
| |
1985
| + } |
| |
1986
| + }, |
| |
1987
| + |
| |
1988
| + /* Apply the maximum length for the date format. */ |
| |
1989
| + _autoSize: function( inst ) { |
| |
1990
| + if ( this._get( inst, "autoSize" ) && !inst.inline ) { |
| |
1991
| + var findMax, max, maxI, i, |
| |
1992
| + date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits |
| |
1993
| + dateFormat = this._get( inst, "dateFormat" ); |
| |
1994
| + |
| |
1995
| + if ( dateFormat.match( /[DM]/ ) ) { |
| |
1996
| + findMax = function( names ) { |
| |
1997
| + max = 0; |
| |
1998
| + maxI = 0; |
| |
1999
| + for ( i = 0; i < names.length; i++ ) { |
| |
2000
| + if ( names[ i ].length > max ) { |
| |
2001
| + max = names[ i ].length; |
| |
2002
| + maxI = i; |
| |
2003
| + } |
| |
2004
| + } |
| |
2005
| + return maxI; |
| |
2006
| + }; |
| |
2007
| + date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ? |
| |
2008
| + "monthNames" : "monthNamesShort" ) ) ) ); |
| |
2009
| + date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ? |
| |
2010
| + "dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() ); |
| |
2011
| + } |
| |
2012
| + inst.input.attr( "size", this._formatDate( inst, date ).length ); |
| |
2013
| + } |
| |
2014
| + }, |
| |
2015
| + |
| |
2016
| + /* Attach an inline date picker to a div. */ |
| |
2017
| + _inlineDatepicker: function( target, inst ) { |
| |
2018
| + var divSpan = $( target ); |
| |
2019
| + if ( divSpan.hasClass( this.markerClassName ) ) { |
| |
2020
| + return; |
| |
2021
| + } |
| |
2022
| + divSpan.addClass( this.markerClassName ).append( inst.dpDiv ); |
| |
2023
| + $.data( target, "datepicker", inst ); |
| |
2024
| + this._setDate( inst, this._getDefaultDate( inst ), true ); |
| |
2025
| + this._updateDatepicker( inst ); |
| |
2026
| + this._updateAlternate( inst ); |
| |
2027
| + |
| |
2028
| + //If disabled option is true, disable the datepicker before showing it (see ticket #5665) |
| |
2029
| + if ( inst.settings.disabled ) { |
| |
2030
| + this._disableDatepicker( target ); |
| |
2031
| + } |
| |
2032
| + |
| |
2033
| + // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements |
| |
2034
| + // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height |
| |
2035
| + inst.dpDiv.css( "display", "block" ); |
| |
2036
| + }, |
| |
2037
| + |
| |
2038
| + /* Pop-up the date picker in a "dialog" box. |
| |
2039
| + * @param input element - ignored |
| |
2040
| + * @param date string or Date - the initial date to display |
| |
2041
| + * @param onSelect function - the function to call when a date is selected |
| |
2042
| + * @param settings object - update the dialog date picker instance's settings (anonymous object) |
| |
2043
| + * @param pos int[2] - coordinates for the dialog's position within the screen or |
| |
2044
| + * event - with x/y coordinates or |
| |
2045
| + * leave empty for default (screen centre) |
| |
2046
| + * @return the manager object |
| |
2047
| + */ |
| |
2048
| + _dialogDatepicker: function( input, date, onSelect, settings, pos ) { |
| |
2049
| + var id, browserWidth, browserHeight, scrollX, scrollY, |
| |
2050
| + inst = this._dialogInst; // internal instance |
| |
2051
| + |
| |
2052
| + if ( !inst ) { |
| |
2053
| + this.uuid += 1; |
| |
2054
| + id = "dp" + this.uuid; |
| |
2055
| + this._dialogInput = $( "<input type='text' id='" + id + |
| |
2056
| + "' style='position: absolute; top: -100px; width: 0px;'/>" ); |
| |
2057
| + this._dialogInput.on( "keydown", this._doKeyDown ); |
| |
2058
| + $( "body" ).append( this._dialogInput ); |
| |
2059
| + inst = this._dialogInst = this._newInst( this._dialogInput, false ); |
| |
2060
| + inst.settings = {}; |
| |
2061
| + $.data( this._dialogInput[ 0 ], "datepicker", inst ); |
| |
2062
| + } |
| |
2063
| + datepicker_extendRemove( inst.settings, settings || {} ); |
| |
2064
| + date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date ); |
| |
2065
| + this._dialogInput.val( date ); |
| |
2066
| + |
| |
2067
| + this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null ); |
| |
2068
| + if ( !this._pos ) { |
| |
2069
| + browserWidth = document.documentElement.clientWidth; |
| |
2070
| + browserHeight = document.documentElement.clientHeight; |
| |
2071
| + scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; |
| |
2072
| + scrollY = document.documentElement.scrollTop || document.body.scrollTop; |
| |
2073
| + this._pos = // should use actual width/height below |
| |
2074
| + [ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ]; |
| |
2075
| + } |
| |
2076
| + |
| |
2077
| + // Move input on screen for focus, but hidden behind dialog |
| |
2078
| + this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" ); |
| |
2079
| + inst.settings.onSelect = onSelect; |
| |
2080
| + this._inDialog = true; |
| |
2081
| + this.dpDiv.addClass( this._dialogClass ); |
| |
2082
| + this._showDatepicker( this._dialogInput[ 0 ] ); |
| |
2083
| + if ( $.blockUI ) { |
| |
2084
| + $.blockUI( this.dpDiv ); |
| |
2085
| + } |
| |
2086
| + $.data( this._dialogInput[ 0 ], "datepicker", inst ); |
| |
2087
| + return this; |
| |
2088
| + }, |
| |
2089
| + |
| |
2090
| + /* Detach a datepicker from its control. |
| |
2091
| + * @param target element - the target input field or division or span |
| |
2092
| + */ |
| |
2093
| + _destroyDatepicker: function( target ) { |
| |
2094
| + var nodeName, |
| |
2095
| + $target = $( target ), |
| |
2096
| + inst = $.data( target, "datepicker" ); |
| |
2097
| + |
| |
2098
| + if ( !$target.hasClass( this.markerClassName ) ) { |
| |
2099
| + return; |
| |
2100
| + } |
| |
2101
| + |
| |
2102
| + nodeName = target.nodeName.toLowerCase(); |
| |
2103
| + $.removeData( target, "datepicker" ); |
| |
2104
| + if ( nodeName === "input" ) { |
| |
2105
| + inst.append.remove(); |
| |
2106
| + inst.trigger.remove(); |
| |
2107
| + $target.removeClass( this.markerClassName ). |
| |
2108
| + off( "focus", this._showDatepicker ). |
| |
2109
| + off( "keydown", this._doKeyDown ). |
| |
2110
| + off( "keypress", this._doKeyPress ). |
| |
2111
| + off( "keyup", this._doKeyUp ); |
| |
2112
| + } else if ( nodeName === "div" || nodeName === "span" ) { |
| |
2113
| + $target.removeClass( this.markerClassName ).empty(); |
| |
2114
| + } |
| |
2115
| + |
| |
2116
| + if ( datepicker_instActive === inst ) { |
| |
2117
| + datepicker_instActive = null; |
| |
2118
| + } |
| |
2119
| + }, |
| |
2120
| + |
| |
2121
| + /* Enable the date picker to a jQuery selection. |
| |
2122
| + * @param target element - the target input field or division or span |
| |
2123
| + */ |
| |
2124
| + _enableDatepicker: function( target ) { |
| |
2125
| + var nodeName, inline, |
| |
2126
| + $target = $( target ), |
| |
2127
| + inst = $.data( target, "datepicker" ); |
| |
2128
| + |
| |
2129
| + if ( !$target.hasClass( this.markerClassName ) ) { |
| |
2130
| + return; |
| |
2131
| + } |
| |
2132
| + |
| |
2133
| + nodeName = target.nodeName.toLowerCase(); |
| |
2134
| + if ( nodeName === "input" ) { |
| |
2135
| + target.disabled = false; |
| |
2136
| + inst.trigger.filter( "button" ). |
| |
2137
| + each( function() { this.disabled = false; } ).end(). |
| |
2138
| + filter( "img" ).css( { opacity: "1.0", cursor: "" } ); |
| |
2139
| + } else if ( nodeName === "div" || nodeName === "span" ) { |
| |
2140
| + inline = $target.children( "." + this._inlineClass ); |
| |
2141
| + inline.children().removeClass( "ui-state-disabled" ); |
| |
2142
| + inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). |
| |
2143
| + prop( "disabled", false ); |
| |
2144
| + } |
| |
2145
| + this._disabledInputs = $.map( this._disabledInputs, |
| |
2146
| + function( value ) { return ( value === target ? null : value ); } ); // delete entry |
| |
2147
| + }, |
| |
2148
| + |
| |
2149
| + /* Disable the date picker to a jQuery selection. |
| |
2150
| + * @param target element - the target input field or division or span |
| |
2151
| + */ |
| |
2152
| + _disableDatepicker: function( target ) { |
| |
2153
| + var nodeName, inline, |
| |
2154
| + $target = $( target ), |
| |
2155
| + inst = $.data( target, "datepicker" ); |
| |
2156
| + |
| |
2157
| + if ( !$target.hasClass( this.markerClassName ) ) { |
| |
2158
| + return; |
| |
2159
| + } |
| |
2160
| + |
| |
2161
| + nodeName = target.nodeName.toLowerCase(); |
| |
2162
| + if ( nodeName === "input" ) { |
| |
2163
| + target.disabled = true; |
| |
2164
| + inst.trigger.filter( "button" ). |
| |
2165
| + each( function() { this.disabled = true; } ).end(). |
| |
2166
| + filter( "img" ).css( { opacity: "0.5", cursor: "default" } ); |
| |
2167
| + } else if ( nodeName === "div" || nodeName === "span" ) { |
| |
2168
| + inline = $target.children( "." + this._inlineClass ); |
| |
2169
| + inline.children().addClass( "ui-state-disabled" ); |
| |
2170
| + inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ). |
| |
2171
| + prop( "disabled", true ); |
| |
2172
| + } |
| |
2173
| + this._disabledInputs = $.map( this._disabledInputs, |
| |
2174
| + function( value ) { return ( value === target ? null : value ); } ); // delete entry |
| |
2175
| + this._disabledInputs[ this._disabledInputs.length ] = target; |
| |
2176
| + }, |
| |
2177
| + |
| |
2178
| + /* Is the first field in a jQuery collection disabled as a datepicker? |
| |
2179
| + * @param target element - the target input field or division or span |
| |
2180
| + * @return boolean - true if disabled, false if enabled |
| |
2181
| + */ |
| |
2182
| + _isDisabledDatepicker: function( target ) { |
| |
2183
| + if ( !target ) { |
| |
2184
| + return false; |
| |
2185
| + } |
| |
2186
| + for ( var i = 0; i < this._disabledInputs.length; i++ ) { |
| |
2187
| + if ( this._disabledInputs[ i ] === target ) { |
| |
2188
| + return true; |
| |
2189
| + } |
| |
2190
| + } |
| |
2191
| + return false; |
| |
2192
| + }, |
| |
2193
| + |
| |
2194
| + /* Retrieve the instance data for the target control. |
| |
2195
| + * @param target element - the target input field or division or span |
| |
2196
| + * @return object - the associated instance data |
| |
2197
| + * @throws error if a jQuery problem getting data |
| |
2198
| + */ |
| |
2199
| + _getInst: function( target ) { |
| |
2200
| + try { |
| |
2201
| + return $.data( target, "datepicker" ); |
| |
2202
| + } |
| |
2203
| + catch ( err ) { |
| |
2204
| + throw "Missing instance data for this datepicker"; |
| |
2205
| + } |
| |
2206
| + }, |
| |
2207
| + |
| |
2208
| + /* Update or retrieve the settings for a date picker attached to an input field or division. |
| |
2209
| + * @param target element - the target input field or division or span |
| |
2210
| + * @param name object - the new settings to update or |
| |
2211
| + * string - the name of the setting to change or retrieve, |
| |
2212
| + * when retrieving also "all" for all instance settings or |
| |
2213
| + * "defaults" for all global defaults |
| |
2214
| + * @param value any - the new value for the setting |
| |
2215
| + * (omit if above is an object or to retrieve a value) |
| |
2216
| + */ |
| |
2217
| + _optionDatepicker: function( target, name, value ) { |
| |
2218
| + var settings, date, minDate, maxDate, |
| |
2219
| + inst = this._getInst( target ); |
| |
2220
| + |
| |
2221
| + if ( arguments.length === 2 && typeof name === "string" ) { |
| |
2222
| + return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) : |
| |
2223
| + ( inst ? ( name === "all" ? $.extend( {}, inst.settings ) : |
| |
2224
| + this._get( inst, name ) ) : null ) ); |
| |
2225
| + } |
| |
2226
| + |
| |
2227
| + settings = name || {}; |
| |
2228
| + if ( typeof name === "string" ) { |
| |
2229
| + settings = {}; |
| |
2230
| + settings[ name ] = value; |
| |
2231
| + } |
| |
2232
| + |
| |
2233
| + if ( inst ) { |
| |
2234
| + if ( this._curInst === inst ) { |
| |
2235
| + this._hideDatepicker(); |
| |
2236
| + } |
| |
2237
| + |
| |
2238
| + date = this._getDateDatepicker( target, true ); |
| |
2239
| + minDate = this._getMinMaxDate( inst, "min" ); |
| |
2240
| + maxDate = this._getMinMaxDate( inst, "max" ); |
| |
2241
| + datepicker_extendRemove( inst.settings, settings ); |
| |
2242
| + |
| |
2243
| + // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided |
| |
2244
| + if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) { |
| |
2245
| + inst.settings.minDate = this._formatDate( inst, minDate ); |
| |
2246
| + } |
| |
2247
| + if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) { |
| |
2248
| + inst.settings.maxDate = this._formatDate( inst, maxDate ); |
| |
2249
| + } |
| |
2250
| + if ( "disabled" in settings ) { |
| |
2251
| + if ( settings.disabled ) { |
| |
2252
| + this._disableDatepicker( target ); |
| |
2253
| + } else { |
| |
2254
| + this._enableDatepicker( target ); |
| |
2255
| + } |
| |
2256
| + } |
| |
2257
| + this._attachments( $( target ), inst ); |
| |
2258
| + this._autoSize( inst ); |
| |
2259
| + this._setDate( inst, date ); |
| |
2260
| + this._updateAlternate( inst ); |
| |
2261
| + this._updateDatepicker( inst ); |
| |
2262
| + } |
| |
2263
| + }, |
| |
2264
| + |
| |
2265
| + // Change method deprecated |
| |
2266
| + _changeDatepicker: function( target, name, value ) { |
| |
2267
| + this._optionDatepicker( target, name, value ); |
| |
2268
| + }, |
| |
2269
| + |
| |
2270
| + /* Redraw the date picker attached to an input field or division. |
| |
2271
| + * @param target element - the target input field or division or span |
| |
2272
| + */ |
| |
2273
| + _refreshDatepicker: function( target ) { |
| |
2274
| + var inst = this._getInst( target ); |
| |
2275
| + if ( inst ) { |
| |
2276
| + this._updateDatepicker( inst ); |
| |
2277
| + } |
| |
2278
| + }, |
| |
2279
| + |
| |
2280
| + /* Set the dates for a jQuery selection. |
| |
2281
| + * @param target element - the target input field or division or span |
| |
2282
| + * @param date Date - the new date |
| |
2283
| + */ |
| |
2284
| + _setDateDatepicker: function( target, date ) { |
| |
2285
| + var inst = this._getInst( target ); |
| |
2286
| + if ( inst ) { |
| |
2287
| + this._setDate( inst, date ); |
| |
2288
| + this._updateDatepicker( inst ); |
| |
2289
| + this._updateAlternate( inst ); |
| |
2290
| + } |
| |
2291
| + }, |
| |
2292
| + |
| |
2293
| + /* Get the date(s) for the first entry in a jQuery selection. |
| |
2294
| + * @param target element - the target input field or division or span |
| |
2295
| + * @param noDefault boolean - true if no default date is to be used |
| |
2296
| + * @return Date - the current date |
| |
2297
| + */ |
| |
2298
| + _getDateDatepicker: function( target, noDefault ) { |
| |
2299
| + var inst = this._getInst( target ); |
| |
2300
| + if ( inst && !inst.inline ) { |
| |
2301
| + this._setDateFromField( inst, noDefault ); |
| |
2302
| + } |
| |
2303
| + return ( inst ? this._getDate( inst ) : null ); |
| |
2304
| + }, |
| |
2305
| + |
| |
2306
| + /* Handle keystrokes. */ |
| |
2307
| + _doKeyDown: function( event ) { |
| |
2308
| + var onSelect, dateStr, sel, |
| |
2309
| + inst = $.datepicker._getInst( event.target ), |
| |
2310
| + handled = true, |
| |
2311
| + isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" ); |
| |
2312
| + |
| |
2313
| + inst._keyEvent = true; |
| |
2314
| + if ( $.datepicker._datepickerShowing ) { |
| |
2315
| + switch ( event.keyCode ) { |
| |
2316
| + case 9: $.datepicker._hideDatepicker(); |
| |
2317
| + handled = false; |
| |
2318
| + break; // hide on tab out |
| |
2319
| + case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." + |
| |
2320
| + $.datepicker._currentClass + ")", inst.dpDiv ); |
| |
2321
| + if ( sel[ 0 ] ) { |
| |
2322
| + $.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] ); |
| |
2323
| + } |
| |
2324
| + |
| |
2325
| + onSelect = $.datepicker._get( inst, "onSelect" ); |
| |
2326
| + if ( onSelect ) { |
| |
2327
| + dateStr = $.datepicker._formatDate( inst ); |
| |
2328
| + |
| |
2329
| + // Trigger custom callback |
| |
2330
| + onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); |
| |
2331
| + } else { |
| |
2332
| + $.datepicker._hideDatepicker(); |
| |
2333
| + } |
| |
2334
| + |
| |
2335
| + return false; // don't submit the form |
| |
2336
| + case 27: $.datepicker._hideDatepicker(); |
| |
2337
| + break; // hide on escape |
| |
2338
| + case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? |
| |
2339
| + -$.datepicker._get( inst, "stepBigMonths" ) : |
| |
2340
| + -$.datepicker._get( inst, "stepMonths" ) ), "M" ); |
| |
2341
| + break; // previous month/year on page up/+ ctrl |
| |
2342
| + case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ? |
| |
2343
| + +$.datepicker._get( inst, "stepBigMonths" ) : |
| |
2344
| + +$.datepicker._get( inst, "stepMonths" ) ), "M" ); |
| |
2345
| + break; // next month/year on page down/+ ctrl |
| |
2346
| + case 35: if ( event.ctrlKey || event.metaKey ) { |
| |
2347
| + $.datepicker._clearDate( event.target ); |
| |
2348
| + } |
| |
2349
| + handled = event.ctrlKey || event.metaKey; |
| |
2350
| + break; // clear on ctrl or command +end |
| |
2351
| + case 36: if ( event.ctrlKey || event.metaKey ) { |
| |
2352
| + $.datepicker._gotoToday( event.target ); |
| |
2353
| + } |
| |
2354
| + handled = event.ctrlKey || event.metaKey; |
| |
2355
| + break; // current on ctrl or command +home |
| |
2356
| + case 37: if ( event.ctrlKey || event.metaKey ) { |
| |
2357
| + $.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" ); |
| |
2358
| + } |
| |
2359
| + handled = event.ctrlKey || event.metaKey; |
| |
2360
| + |
| |
2361
| + // -1 day on ctrl or command +left |
| |
2362
| + if ( event.originalEvent.altKey ) { |
| |
2363
| + $.datepicker._adjustDate( event.target, ( event.ctrlKey ? |
| |
2364
| + -$.datepicker._get( inst, "stepBigMonths" ) : |
| |
2365
| + -$.datepicker._get( inst, "stepMonths" ) ), "M" ); |
| |
2366
| + } |
| |
2367
| + |
| |
2368
| + // next month/year on alt +left on Mac |
| |
2369
| + break; |
| |
2370
| + case 38: if ( event.ctrlKey || event.metaKey ) { |
| |
2371
| + $.datepicker._adjustDate( event.target, -7, "D" ); |
| |
2372
| + } |
| |
2373
| + handled = event.ctrlKey || event.metaKey; |
| |
2374
| + break; // -1 week on ctrl or command +up |
| |
2375
| + case 39: if ( event.ctrlKey || event.metaKey ) { |
| |
2376
| + $.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" ); |
| |
2377
| + } |
| |
2378
| + handled = event.ctrlKey || event.metaKey; |
| |
2379
| + |
| |
2380
| + // +1 day on ctrl or command +right |
| |
2381
| + if ( event.originalEvent.altKey ) { |
| |
2382
| + $.datepicker._adjustDate( event.target, ( event.ctrlKey ? |
| |
2383
| + +$.datepicker._get( inst, "stepBigMonths" ) : |
| |
2384
| + +$.datepicker._get( inst, "stepMonths" ) ), "M" ); |
| |
2385
| + } |
| |
2386
| + |
| |
2387
| + // next month/year on alt +right |
| |
2388
| + break; |
| |
2389
| + case 40: if ( event.ctrlKey || event.metaKey ) { |
| |
2390
| + $.datepicker._adjustDate( event.target, +7, "D" ); |
| |
2391
| + } |
| |
2392
| + handled = event.ctrlKey || event.metaKey; |
| |
2393
| + break; // +1 week on ctrl or command +down |
| |
2394
| + default: handled = false; |
| |
2395
| + } |
| |
2396
| + } else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home |
| |
2397
| + $.datepicker._showDatepicker( this ); |
| |
2398
| + } else { |
| |
2399
| + handled = false; |
| |
2400
| + } |
| |
2401
| + |
| |
2402
| + if ( handled ) { |
| |
2403
| + event.preventDefault(); |
| |
2404
| + event.stopPropagation(); |
| |
2405
| + } |
| |
2406
| + }, |
| |
2407
| + |
| |
2408
| + /* Filter entered characters - based on date format. */ |
| |
2409
| + _doKeyPress: function( event ) { |
| |
2410
| + var chars, chr, |
| |
2411
| + inst = $.datepicker._getInst( event.target ); |
| |
2412
| + |
| |
2413
| + if ( $.datepicker._get( inst, "constrainInput" ) ) { |
| |
2414
| + chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) ); |
| |
2415
| + chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode ); |
| |
2416
| + return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 ); |
| |
2417
| + } |
| |
2418
| + }, |
| |
2419
| + |
| |
2420
| + /* Synchronise manual entry and field/alternate field. */ |
| |
2421
| + _doKeyUp: function( event ) { |
| |
2422
| + var date, |
| |
2423
| + inst = $.datepicker._getInst( event.target ); |
| |
2424
| + |
| |
2425
| + if ( inst.input.val() !== inst.lastVal ) { |
| |
2426
| + try { |
| |
2427
| + date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), |
| |
2428
| + ( inst.input ? inst.input.val() : null ), |
| |
2429
| + $.datepicker._getFormatConfig( inst ) ); |
| |
2430
| + |
| |
2431
| + if ( date ) { // only if valid |
| |
2432
| + $.datepicker._setDateFromField( inst ); |
| |
2433
| + $.datepicker._updateAlternate( inst ); |
| |
2434
| + $.datepicker._updateDatepicker( inst ); |
| |
2435
| + } |
| |
2436
| + } |
| |
2437
| + catch ( err ) { |
| |
2438
| + } |
| |
2439
| + } |
| |
2440
| + return true; |
| |
2441
| + }, |
| |
2442
| + |
| |
2443
| + /* Pop-up the date picker for a given input field. |
| |
2444
| + * If false returned from beforeShow event handler do not show. |
| |
2445
| + * @param input element - the input field attached to the date picker or |
| |
2446
| + * event - if triggered by focus |
| |
2447
| + */ |
| |
2448
| + _showDatepicker: function( input ) { |
| |
2449
| + input = input.target || input; |
| |
2450
| + if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger |
| |
2451
| + input = $( "input", input.parentNode )[ 0 ]; |
| |
2452
| + } |
| |
2453
| + |
| |
2454
| + if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here |
| |
2455
| + return; |
| |
2456
| + } |
| |
2457
| + |
| |
2458
| + var inst, beforeShow, beforeShowSettings, isFixed, |
| |
2459
| + offset, showAnim, duration; |
| |
2460
| + |
| |
2461
| + inst = $.datepicker._getInst( input ); |
| |
2462
| + if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) { |
| |
2463
| + $.datepicker._curInst.dpDiv.stop( true, true ); |
| |
2464
| + if ( inst && $.datepicker._datepickerShowing ) { |
| |
2465
| + $.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] ); |
| |
2466
| + } |
| |
2467
| + } |
| |
2468
| + |
| |
2469
| + beforeShow = $.datepicker._get( inst, "beforeShow" ); |
| |
2470
| + beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {}; |
| |
2471
| + if ( beforeShowSettings === false ) { |
| |
2472
| + return; |
| |
2473
| + } |
| |
2474
| + datepicker_extendRemove( inst.settings, beforeShowSettings ); |
| |
2475
| + |
| |
2476
| + inst.lastVal = null; |
| |
2477
| + $.datepicker._lastInput = input; |
| |
2478
| + $.datepicker._setDateFromField( inst ); |
| |
2479
| + |
| |
2480
| + if ( $.datepicker._inDialog ) { // hide cursor |
| |
2481
| + input.value = ""; |
| |
2482
| + } |
| |
2483
| + if ( !$.datepicker._pos ) { // position below input |
| |
2484
| + $.datepicker._pos = $.datepicker._findPos( input ); |
| |
2485
| + $.datepicker._pos[ 1 ] += input.offsetHeight; // add the height |
| |
2486
| + } |
| |
2487
| + |
| |
2488
| + isFixed = false; |
| |
2489
| + $( input ).parents().each( function() { |
| |
2490
| + isFixed |= $( this ).css( "position" ) === "fixed"; |
| |
2491
| + return !isFixed; |
| |
2492
| + } ); |
| |
2493
| + |
| |
2494
| + offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] }; |
| |
2495
| + $.datepicker._pos = null; |
| |
2496
| + |
| |
2497
| + //to avoid flashes on Firefox |
| |
2498
| + inst.dpDiv.empty(); |
| |
2499
| + |
| |
2500
| + // determine sizing offscreen |
| |
2501
| + inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } ); |
| |
2502
| + $.datepicker._updateDatepicker( inst ); |
| |
2503
| + |
| |
2504
| + // fix width for dynamic number of date pickers |
| |
2505
| + // and adjust position before showing |
| |
2506
| + offset = $.datepicker._checkOffset( inst, offset, isFixed ); |
| |
2507
| + inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ? |
| |
2508
| + "static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none", |
| |
2509
| + left: offset.left + "px", top: offset.top + "px" } ); |
| |
2510
| + |
| |
2511
| + if ( !inst.inline ) { |
| |
2512
| + showAnim = $.datepicker._get( inst, "showAnim" ); |
| |
2513
| + duration = $.datepicker._get( inst, "duration" ); |
| |
2514
| + inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 ); |
| |
2515
| + $.datepicker._datepickerShowing = true; |
| |
2516
| + |
| |
2517
| + if ( $.effects && $.effects.effect[ showAnim ] ) { |
| |
2518
| + inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration ); |
| |
2519
| + } else { |
| |
2520
| + inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null ); |
| |
2521
| + } |
| |
2522
| + |
| |
2523
| + if ( $.datepicker._shouldFocusInput( inst ) ) { |
| |
2524
| + inst.input.trigger( "focus" ); |
| |
2525
| + } |
| |
2526
| + |
| |
2527
| + $.datepicker._curInst = inst; |
| |
2528
| + } |
| |
2529
| + }, |
| |
2530
| + |
| |
2531
| + /* Generate the date picker content. */ |
| |
2532
| + _updateDatepicker: function( inst ) { |
| |
2533
| + this.maxRows = 4; //Reset the max number of rows being displayed (see #7043) |
| |
2534
| + datepicker_instActive = inst; // for delegate hover events |
| |
2535
| + inst.dpDiv.empty().append( this._generateHTML( inst ) ); |
| |
2536
| + this._attachHandlers( inst ); |
| |
2537
| + |
| |
2538
| + var origyearshtml, |
| |
2539
| + numMonths = this._getNumberOfMonths( inst ), |
| |
2540
| + cols = numMonths[ 1 ], |
| |
2541
| + width = 17, |
| |
2542
| + activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ); |
| |
2543
| + |
| |
2544
| + if ( activeCell.length > 0 ) { |
| |
2545
| + datepicker_handleMouseover.apply( activeCell.get( 0 ) ); |
| |
2546
| + } |
| |
2547
| + |
| |
2548
| + inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" ); |
| |
2549
| + if ( cols > 1 ) { |
| |
2550
| + inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" ); |
| |
2551
| + } |
| |
2552
| + inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) + |
| |
2553
| + "Class" ]( "ui-datepicker-multi" ); |
| |
2554
| + inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) + |
| |
2555
| + "Class" ]( "ui-datepicker-rtl" ); |
| |
2556
| + |
| |
2557
| + if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) { |
| |
2558
| + inst.input.trigger( "focus" ); |
| |
2559
| + } |
| |
2560
| + |
| |
2561
| + // Deffered render of the years select (to avoid flashes on Firefox) |
| |
2562
| + if ( inst.yearshtml ) { |
| |
2563
| + origyearshtml = inst.yearshtml; |
| |
2564
| + setTimeout( function() { |
| |
2565
| + |
| |
2566
| + //assure that inst.yearshtml didn't change. |
| |
2567
| + if ( origyearshtml === inst.yearshtml && inst.yearshtml ) { |
| |
2568
| + inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml ); |
| |
2569
| + } |
| |
2570
| + origyearshtml = inst.yearshtml = null; |
| |
2571
| + }, 0 ); |
| |
2572
| + } |
| |
2573
| + }, |
| |
2574
| + |
| |
2575
| + // #6694 - don't focus the input if it's already focused |
| |
2576
| + // this breaks the change event in IE |
| |
2577
| + // Support: IE and jQuery <1.9 |
| |
2578
| + _shouldFocusInput: function( inst ) { |
| |
2579
| + return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" ); |
| |
2580
| + }, |
| |
2581
| + |
| |
2582
| + /* Check positioning to remain on screen. */ |
| |
2583
| + _checkOffset: function( inst, offset, isFixed ) { |
| |
2584
| + var dpWidth = inst.dpDiv.outerWidth(), |
| |
2585
| + dpHeight = inst.dpDiv.outerHeight(), |
| |
2586
| + inputWidth = inst.input ? inst.input.outerWidth() : 0, |
| |
2587
| + inputHeight = inst.input ? inst.input.outerHeight() : 0, |
| |
2588
| + viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ), |
| |
2589
| + viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() ); |
| |
2590
| + |
| |
2591
| + offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 ); |
| |
2592
| + offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0; |
| |
2593
| + offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0; |
| |
2594
| + |
| |
2595
| + // Now check if datepicker is showing outside window viewport - move to a better place if so. |
| |
2596
| + offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ? |
| |
2597
| + Math.abs( offset.left + dpWidth - viewWidth ) : 0 ); |
| |
2598
| + offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ? |
| |
2599
| + Math.abs( dpHeight + inputHeight ) : 0 ); |
| |
2600
| + |
| |
2601
| + return offset; |
| |
2602
| + }, |
| |
2603
| + |
| |
2604
| + /* Find an object's position on the screen. */ |
| |
2605
| + _findPos: function( obj ) { |
| |
2606
| + var position, |
| |
2607
| + inst = this._getInst( obj ), |
| |
2608
| + isRTL = this._get( inst, "isRTL" ); |
| |
2609
| + |
| |
2610
| + while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) { |
| |
2611
| + obj = obj[ isRTL ? "previousSibling" : "nextSibling" ]; |
| |
2612
| + } |
| |
2613
| + |
| |
2614
| + position = $( obj ).offset(); |
| |
2615
| + return [ position.left, position.top ]; |
| |
2616
| + }, |
| |
2617
| + |
| |
2618
| + /* Hide the date picker from view. |
| |
2619
| + * @param input element - the input field attached to the date picker |
| |
2620
| + */ |
| |
2621
| + _hideDatepicker: function( input ) { |
| |
2622
| + var showAnim, duration, postProcess, onClose, |
| |
2623
| + inst = this._curInst; |
| |
2624
| + |
| |
2625
| + if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) { |
| |
2626
| + return; |
| |
2627
| + } |
| |
2628
| + |
| |
2629
| + if ( this._datepickerShowing ) { |
| |
2630
| + showAnim = this._get( inst, "showAnim" ); |
| |
2631
| + duration = this._get( inst, "duration" ); |
| |
2632
| + postProcess = function() { |
| |
2633
| + $.datepicker._tidyDialog( inst ); |
| |
2634
| + }; |
| |
2635
| + |
| |
2636
| + // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed |
| |
2637
| + if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) { |
| |
2638
| + inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess ); |
| |
2639
| + } else { |
| |
2640
| + inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" : |
| |
2641
| + ( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess ); |
| |
2642
| + } |
| |
2643
| + |
| |
2644
| + if ( !showAnim ) { |
| |
2645
| + postProcess(); |
| |
2646
| + } |
| |
2647
| + this._datepickerShowing = false; |
| |
2648
| + |
| |
2649
| + onClose = this._get( inst, "onClose" ); |
| |
2650
| + if ( onClose ) { |
| |
2651
| + onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] ); |
| |
2652
| + } |
| |
2653
| + |
| |
2654
| + this._lastInput = null; |
| |
2655
| + if ( this._inDialog ) { |
| |
2656
| + this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } ); |
| |
2657
| + if ( $.blockUI ) { |
| |
2658
| + $.unblockUI(); |
| |
2659
| + $( "body" ).append( this.dpDiv ); |
| |
2660
| + } |
| |
2661
| + } |
| |
2662
| + this._inDialog = false; |
| |
2663
| + } |
| |
2664
| + }, |
| |
2665
| + |
| |
2666
| + /* Tidy up after a dialog display. */ |
| |
2667
| + _tidyDialog: function( inst ) { |
| |
2668
| + inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" ); |
| |
2669
| + }, |
| |
2670
| + |
| |
2671
| + /* Close date picker if clicked elsewhere. */ |
| |
2672
| + _checkExternalClick: function( event ) { |
| |
2673
| + if ( !$.datepicker._curInst ) { |
| |
2674
| + return; |
| |
2675
| + } |
| |
2676
| + |
| |
2677
| + var $target = $( event.target ), |
| |
2678
| + inst = $.datepicker._getInst( $target[ 0 ] ); |
| |
2679
| + |
| |
2680
| + if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId && |
| |
2681
| + $target.parents( "#" + $.datepicker._mainDivId ).length === 0 && |
| |
2682
| + !$target.hasClass( $.datepicker.markerClassName ) && |
| |
2683
| + !$target.closest( "." + $.datepicker._triggerClass ).length && |
| |
2684
| + $.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) || |
| |
2685
| + ( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) { |
| |
2686
| + $.datepicker._hideDatepicker(); |
| |
2687
| + } |
| |
2688
| + }, |
| |
2689
| + |
| |
2690
| + /* Adjust one of the date sub-fields. */ |
| |
2691
| + _adjustDate: function( id, offset, period ) { |
| |
2692
| + var target = $( id ), |
| |
2693
| + inst = this._getInst( target[ 0 ] ); |
| |
2694
| + |
| |
2695
| + if ( this._isDisabledDatepicker( target[ 0 ] ) ) { |
| |
2696
| + return; |
| |
2697
| + } |
| |
2698
| + this._adjustInstDate( inst, offset + |
| |
2699
| + ( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning |
| |
2700
| + period ); |
| |
2701
| + this._updateDatepicker( inst ); |
| |
2702
| + }, |
| |
2703
| + |
| |
2704
| + /* Action for current link. */ |
| |
2705
| + _gotoToday: function( id ) { |
| |
2706
| + var date, |
| |
2707
| + target = $( id ), |
| |
2708
| + inst = this._getInst( target[ 0 ] ); |
| |
2709
| + |
| |
2710
| + if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) { |
| |
2711
| + inst.selectedDay = inst.currentDay; |
| |
2712
| + inst.drawMonth = inst.selectedMonth = inst.currentMonth; |
| |
2713
| + inst.drawYear = inst.selectedYear = inst.currentYear; |
| |
2714
| + } else { |
| |
2715
| + date = new Date(); |
| |
2716
| + inst.selectedDay = date.getDate(); |
| |
2717
| + inst.drawMonth = inst.selectedMonth = date.getMonth(); |
| |
2718
| + inst.drawYear = inst.selectedYear = date.getFullYear(); |
| |
2719
| + } |
| |
2720
| + this._notifyChange( inst ); |
| |
2721
| + this._adjustDate( target ); |
| |
2722
| + }, |
| |
2723
| + |
| |
2724
| + /* Action for selecting a new month/year. */ |
| |
2725
| + _selectMonthYear: function( id, select, period ) { |
| |
2726
| + var target = $( id ), |
| |
2727
| + inst = this._getInst( target[ 0 ] ); |
| |
2728
| + |
| |
2729
| + inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] = |
| |
2730
| + inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] = |
| |
2731
| + parseInt( select.options[ select.selectedIndex ].value, 10 ); |
| |
2732
| + |
| |
2733
| + this._notifyChange( inst ); |
| |
2734
| + this._adjustDate( target ); |
| |
2735
| + }, |
| |
2736
| + |
| |
2737
| + /* Action for selecting a day. */ |
| |
2738
| + _selectDay: function( id, month, year, td ) { |
| |
2739
| + var inst, |
| |
2740
| + target = $( id ); |
| |
2741
| + |
| |
2742
| + if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) { |
| |
2743
| + return; |
| |
2744
| + } |
| |
2745
| + |
| |
2746
| + inst = this._getInst( target[ 0 ] ); |
| |
2747
| + inst.selectedDay = inst.currentDay = $( "a", td ).html(); |
| |
2748
| + inst.selectedMonth = inst.currentMonth = month; |
| |
2749
| + inst.selectedYear = inst.currentYear = year; |
| |
2750
| + this._selectDate( id, this._formatDate( inst, |
| |
2751
| + inst.currentDay, inst.currentMonth, inst.currentYear ) ); |
| |
2752
| + }, |
| |
2753
| + |
| |
2754
| + /* Erase the input field and hide the date picker. */ |
| |
2755
| + _clearDate: function( id ) { |
| |
2756
| + var target = $( id ); |
| |
2757
| + this._selectDate( target, "" ); |
| |
2758
| + }, |
| |
2759
| + |
| |
2760
| + /* Update the input field with the selected date. */ |
| |
2761
| + _selectDate: function( id, dateStr ) { |
| |
2762
| + var onSelect, |
| |
2763
| + target = $( id ), |
| |
2764
| + inst = this._getInst( target[ 0 ] ); |
| |
2765
| + |
| |
2766
| + dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) ); |
| |
2767
| + if ( inst.input ) { |
| |
2768
| + inst.input.val( dateStr ); |
| |
2769
| + } |
| |
2770
| + this._updateAlternate( inst ); |
| |
2771
| + |
| |
2772
| + onSelect = this._get( inst, "onSelect" ); |
| |
2773
| + if ( onSelect ) { |
| |
2774
| + onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] ); // trigger custom callback |
| |
2775
| + } else if ( inst.input ) { |
| |
2776
| + inst.input.trigger( "change" ); // fire the change event |
| |
2777
| + } |
| |
2778
| + |
| |
2779
| + if ( inst.inline ) { |
| |
2780
| + this._updateDatepicker( inst ); |
| |
2781
| + } else { |
| |
2782
| + this._hideDatepicker(); |
| |
2783
| + this._lastInput = inst.input[ 0 ]; |
| |
2784
| + if ( typeof( inst.input[ 0 ] ) !== "object" ) { |
| |
2785
| + inst.input.trigger( "focus" ); // restore focus |
| |
2786
| + } |
| |
2787
| + this._lastInput = null; |
| |
2788
| + } |
| |
2789
| + }, |
| |
2790
| + |
| |
2791
| + /* Update any alternate field to synchronise with the main field. */ |
| |
2792
| + _updateAlternate: function( inst ) { |
| |
2793
| + var altFormat, date, dateStr, |
| |
2794
| + altField = this._get( inst, "altField" ); |
| |
2795
| + |
| |
2796
| + if ( altField ) { // update alternate field too |
| |
2797
| + altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" ); |
| |
2798
| + date = this._getDate( inst ); |
| |
2799
| + dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) ); |
| |
2800
| + $( altField ).val( dateStr ); |
| |
2801
| + } |
| |
2802
| + }, |
| |
2803
| + |
| |
2804
| + /* Set as beforeShowDay function to prevent selection of weekends. |
| |
2805
| + * @param date Date - the date to customise |
| |
2806
| + * @return [boolean, string] - is this date selectable?, what is its CSS class? |
| |
2807
| + */ |
| |
2808
| + noWeekends: function( date ) { |
| |
2809
| + var day = date.getDay(); |
| |
2810
| + return [ ( day > 0 && day < 6 ), "" ]; |
| |
2811
| + }, |
| |
2812
| + |
| |
2813
| + /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. |
| |
2814
| + * @param date Date - the date to get the week for |
| |
2815
| + * @return number - the number of the week within the year that contains this date |
| |
2816
| + */ |
| |
2817
| + iso8601Week: function( date ) { |
| |
2818
| + var time, |
| |
2819
| + checkDate = new Date( date.getTime() ); |
| |
2820
| + |
| |
2821
| + // Find Thursday of this week starting on Monday |
| |
2822
| + checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); |
| |
2823
| + |
| |
2824
| + time = checkDate.getTime(); |
| |
2825
| + checkDate.setMonth( 0 ); // Compare with Jan 1 |
| |
2826
| + checkDate.setDate( 1 ); |
| |
2827
| + return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1; |
| |
2828
| + }, |
| |
2829
| + |
| |
2830
| + /* Parse a string value into a date object. |
| |
2831
| + * See formatDate below for the possible formats. |
| |
2832
| + * |
| |
2833
| + * @param format string - the expected format of the date |
| |
2834
| + * @param value string - the date in the above format |
| |
2835
| + * @param settings Object - attributes include: |
| |
2836
| + * shortYearCutoff number - the cutoff year for determining the century (optional) |
| |
2837
| + * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) |
| |
2838
| + * dayNames string[7] - names of the days from Sunday (optional) |
| |
2839
| + * monthNamesShort string[12] - abbreviated names of the months (optional) |
| |
2840
| + * monthNames string[12] - names of the months (optional) |
| |
2841
| + * @return Date - the extracted date value or null if value is blank |
| |
2842
| + */ |
| |
2843
| + parseDate: function( format, value, settings ) { |
| |
2844
| + if ( format == null || value == null ) { |
| |
2845
| + throw "Invalid arguments"; |
| |
2846
| + } |
| |
2847
| + |
| |
2848
| + value = ( typeof value === "object" ? value.toString() : value + "" ); |
| |
2849
| + if ( value === "" ) { |
| |
2850
| + return null; |
| |
2851
| + } |
| |
2852
| + |
| |
2853
| + var iFormat, dim, extra, |
| |
2854
| + iValue = 0, |
| |
2855
| + shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff, |
| |
2856
| + shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp : |
| |
2857
| + new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ), |
| |
2858
| + dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, |
| |
2859
| + dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, |
| |
2860
| + monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, |
| |
2861
| + monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, |
| |
2862
| + year = -1, |
| |
2863
| + month = -1, |
| |
2864
| + day = -1, |
| |
2865
| + doy = -1, |
| |
2866
| + literal = false, |
| |
2867
| + date, |
| |
2868
| + |
| |
2869
| + // Check whether a format character is doubled |
| |
2870
| + lookAhead = function( match ) { |
| |
2871
| + var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); |
| |
2872
| + if ( matches ) { |
| |
2873
| + iFormat++; |
| |
2874
| + } |
| |
2875
| + return matches; |
| |
2876
| + }, |
| |
2877
| + |
| |
2878
| + // Extract a number from the string value |
| |
2879
| + getNumber = function( match ) { |
| |
2880
| + var isDoubled = lookAhead( match ), |
| |
2881
| + size = ( match === "@" ? 14 : ( match === "!" ? 20 : |
| |
2882
| + ( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ), |
| |
2883
| + minSize = ( match === "y" ? size : 1 ), |
| |
2884
| + digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ), |
| |
2885
| + num = value.substring( iValue ).match( digits ); |
| |
2886
| + if ( !num ) { |
| |
2887
| + throw "Missing number at position " + iValue; |
| |
2888
| + } |
| |
2889
| + iValue += num[ 0 ].length; |
| |
2890
| + return parseInt( num[ 0 ], 10 ); |
| |
2891
| + }, |
| |
2892
| + |
| |
2893
| + // Extract a name from the string value and convert to an index |
| |
2894
| + getName = function( match, shortNames, longNames ) { |
| |
2895
| + var index = -1, |
| |
2896
| + names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) { |
| |
2897
| + return [ [ k, v ] ]; |
| |
2898
| + } ).sort( function( a, b ) { |
| |
2899
| + return -( a[ 1 ].length - b[ 1 ].length ); |
| |
2900
| + } ); |
| |
2901
| + |
| |
2902
| + $.each( names, function( i, pair ) { |
| |
2903
| + var name = pair[ 1 ]; |
| |
2904
| + if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) { |
| |
2905
| + index = pair[ 0 ]; |
| |
2906
| + iValue += name.length; |
| |
2907
| + return false; |
| |
2908
| + } |
| |
2909
| + } ); |
| |
2910
| + if ( index !== -1 ) { |
| |
2911
| + return index + 1; |
| |
2912
| + } else { |
| |
2913
| + throw "Unknown name at position " + iValue; |
| |
2914
| + } |
| |
2915
| + }, |
| |
2916
| + |
| |
2917
| + // Confirm that a literal character matches the string value |
| |
2918
| + checkLiteral = function() { |
| |
2919
| + if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) { |
| |
2920
| + throw "Unexpected literal at position " + iValue; |
| |
2921
| + } |
| |
2922
| + iValue++; |
| |
2923
| + }; |
| |
2924
| + |
| |
2925
| + for ( iFormat = 0; iFormat < format.length; iFormat++ ) { |
| |
2926
| + if ( literal ) { |
| |
2927
| + if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { |
| |
2928
| + literal = false; |
| |
2929
| + } else { |
| |
2930
| + checkLiteral(); |
| |
2931
| + } |
| |
2932
| + } else { |
| |
2933
| + switch ( format.charAt( iFormat ) ) { |
| |
2934
| + case "d": |
| |
2935
| + day = getNumber( "d" ); |
| |
2936
| + break; |
| |
2937
| + case "D": |
| |
2938
| + getName( "D", dayNamesShort, dayNames ); |
| |
2939
| + break; |
| |
2940
| + case "o": |
| |
2941
| + doy = getNumber( "o" ); |
| |
2942
| + break; |
| |
2943
| + case "m": |
| |
2944
| + month = getNumber( "m" ); |
| |
2945
| + break; |
| |
2946
| + case "M": |
| |
2947
| + month = getName( "M", monthNamesShort, monthNames ); |
| |
2948
| + break; |
| |
2949
| + case "y": |
| |
2950
| + year = getNumber( "y" ); |
| |
2951
| + break; |
| |
2952
| + case "@": |
| |
2953
| + date = new Date( getNumber( "@" ) ); |
| |
2954
| + year = date.getFullYear(); |
| |
2955
| + month = date.getMonth() + 1; |
| |
2956
| + day = date.getDate(); |
| |
2957
| + break; |
| |
2958
| + case "!": |
| |
2959
| + date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 ); |
| |
2960
| + year = date.getFullYear(); |
| |
2961
| + month = date.getMonth() + 1; |
| |
2962
| + day = date.getDate(); |
| |
2963
| + break; |
| |
2964
| + case "'": |
| |
2965
| + if ( lookAhead( "'" ) ) { |
| |
2966
| + checkLiteral(); |
| |
2967
| + } else { |
| |
2968
| + literal = true; |
| |
2969
| + } |
| |
2970
| + break; |
| |
2971
| + default: |
| |
2972
| + checkLiteral(); |
| |
2973
| + } |
| |
2974
| + } |
| |
2975
| + } |
| |
2976
| + |
| |
2977
| + if ( iValue < value.length ) { |
| |
2978
| + extra = value.substr( iValue ); |
| |
2979
| + if ( !/^\s+/.test( extra ) ) { |
| |
2980
| + throw "Extra/unparsed characters found in date: " + extra; |
| |
2981
| + } |
| |
2982
| + } |
| |
2983
| + |
| |
2984
| + if ( year === -1 ) { |
| |
2985
| + year = new Date().getFullYear(); |
| |
2986
| + } else if ( year < 100 ) { |
| |
2987
| + year += new Date().getFullYear() - new Date().getFullYear() % 100 + |
| |
2988
| + ( year <= shortYearCutoff ? 0 : -100 ); |
| |
2989
| + } |
| |
2990
| + |
| |
2991
| + if ( doy > -1 ) { |
| |
2992
| + month = 1; |
| |
2993
| + day = doy; |
| |
2994
| + do { |
| |
2995
| + dim = this._getDaysInMonth( year, month - 1 ); |
| |
2996
| + if ( day <= dim ) { |
| |
2997
| + break; |
| |
2998
| + } |
| |
2999
| + month++; |
| |
3000
| + day -= dim; |
| |
3001
| + } while ( true ); |
| |
3002
| + } |
| |
3003
| + |
| |
3004
| + date = this._daylightSavingAdjust( new Date( year, month - 1, day ) ); |
| |
3005
| + if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) { |
| |
3006
| + throw "Invalid date"; // E.g. 31/02/00 |
| |
3007
| + } |
| |
3008
| + return date; |
| |
3009
| + }, |
| |
3010
| + |
| |
3011
| + /* Standard date formats. */ |
| |
3012
| + ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601) |
| |
3013
| + COOKIE: "D, dd M yy", |
| |
3014
| + ISO_8601: "yy-mm-dd", |
| |
3015
| + RFC_822: "D, d M y", |
| |
3016
| + RFC_850: "DD, dd-M-y", |
| |
3017
| + RFC_1036: "D, d M y", |
| |
3018
| + RFC_1123: "D, d M yy", |
| |
3019
| + RFC_2822: "D, d M yy", |
| |
3020
| + RSS: "D, d M y", // RFC 822 |
| |
3021
| + TICKS: "!", |
| |
3022
| + TIMESTAMP: "@", |
| |
3023
| + W3C: "yy-mm-dd", // ISO 8601 |
| |
3024
| + |
| |
3025
| + _ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) + |
| |
3026
| + Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ), |
| |
3027
| + |
| |
3028
| + /* Format a date object into a string value. |
| |
3029
| + * The format can be combinations of the following: |
| |
3030
| + * d - day of month (no leading zero) |
| |
3031
| + * dd - day of month (two digit) |
| |
3032
| + * o - day of year (no leading zeros) |
| |
3033
| + * oo - day of year (three digit) |
| |
3034
| + * D - day name short |
| |
3035
| + * DD - day name long |
| |
3036
| + * m - month of year (no leading zero) |
| |
3037
| + * mm - month of year (two digit) |
| |
3038
| + * M - month name short |
| |
3039
| + * MM - month name long |
| |
3040
| + * y - year (two digit) |
| |
3041
| + * yy - year (four digit) |
| |
3042
| + * @ - Unix timestamp (ms since 01/01/1970) |
| |
3043
| + * ! - Windows ticks (100ns since 01/01/0001) |
| |
3044
| + * "..." - literal text |
| |
3045
| + * '' - single quote |
| |
3046
| + * |
| |
3047
| + * @param format string - the desired format of the date |
| |
3048
| + * @param date Date - the date value to format |
| |
3049
| + * @param settings Object - attributes include: |
| |
3050
| + * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) |
| |
3051
| + * dayNames string[7] - names of the days from Sunday (optional) |
| |
3052
| + * monthNamesShort string[12] - abbreviated names of the months (optional) |
| |
3053
| + * monthNames string[12] - names of the months (optional) |
| |
3054
| + * @return string - the date in the above format |
| |
3055
| + */ |
| |
3056
| + formatDate: function( format, date, settings ) { |
| |
3057
| + if ( !date ) { |
| |
3058
| + return ""; |
| |
3059
| + } |
| |
3060
| + |
| |
3061
| + var iFormat, |
| |
3062
| + dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort, |
| |
3063
| + dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames, |
| |
3064
| + monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort, |
| |
3065
| + monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames, |
| |
3066
| + |
| |
3067
| + // Check whether a format character is doubled |
| |
3068
| + lookAhead = function( match ) { |
| |
3069
| + var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); |
| |
3070
| + if ( matches ) { |
| |
3071
| + iFormat++; |
| |
3072
| + } |
| |
3073
| + return matches; |
| |
3074
| + }, |
| |
3075
| + |
| |
3076
| + // Format a number, with leading zero if necessary |
| |
3077
| + formatNumber = function( match, value, len ) { |
| |
3078
| + var num = "" + value; |
| |
3079
| + if ( lookAhead( match ) ) { |
| |
3080
| + while ( num.length < len ) { |
| |
3081
| + num = "0" + num; |
| |
3082
| + } |
| |
3083
| + } |
| |
3084
| + return num; |
| |
3085
| + }, |
| |
3086
| + |
| |
3087
| + // Format a name, short or long as requested |
| |
3088
| + formatName = function( match, value, shortNames, longNames ) { |
| |
3089
| + return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] ); |
| |
3090
| + }, |
| |
3091
| + output = "", |
| |
3092
| + literal = false; |
| |
3093
| + |
| |
3094
| + if ( date ) { |
| |
3095
| + for ( iFormat = 0; iFormat < format.length; iFormat++ ) { |
| |
3096
| + if ( literal ) { |
| |
3097
| + if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { |
| |
3098
| + literal = false; |
| |
3099
| + } else { |
| |
3100
| + output += format.charAt( iFormat ); |
| |
3101
| + } |
| |
3102
| + } else { |
| |
3103
| + switch ( format.charAt( iFormat ) ) { |
| |
3104
| + case "d": |
| |
3105
| + output += formatNumber( "d", date.getDate(), 2 ); |
| |
3106
| + break; |
| |
3107
| + case "D": |
| |
3108
| + output += formatName( "D", date.getDay(), dayNamesShort, dayNames ); |
| |
3109
| + break; |
| |
3110
| + case "o": |
| |
3111
| + output += formatNumber( "o", |
| |
3112
| + Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 ); |
| |
3113
| + break; |
| |
3114
| + case "m": |
| |
3115
| + output += formatNumber( "m", date.getMonth() + 1, 2 ); |
| |
3116
| + break; |
| |
3117
| + case "M": |
| |
3118
| + output += formatName( "M", date.getMonth(), monthNamesShort, monthNames ); |
| |
3119
| + break; |
| |
3120
| + case "y": |
| |
3121
| + output += ( lookAhead( "y" ) ? date.getFullYear() : |
| |
3122
| + ( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 ); |
| |
3123
| + break; |
| |
3124
| + case "@": |
| |
3125
| + output += date.getTime(); |
| |
3126
| + break; |
| |
3127
| + case "!": |
| |
3128
| + output += date.getTime() * 10000 + this._ticksTo1970; |
| |
3129
| + break; |
| |
3130
| + case "'": |
| |
3131
| + if ( lookAhead( "'" ) ) { |
| |
3132
| + output += "'"; |
| |
3133
| + } else { |
| |
3134
| + literal = true; |
| |
3135
| + } |
| |
3136
| + break; |
| |
3137
| + default: |
| |
3138
| + output += format.charAt( iFormat ); |
| |
3139
| + } |
| |
3140
| + } |
| |
3141
| + } |
| |
3142
| + } |
| |
3143
| + return output; |
| |
3144
| + }, |
| |
3145
| + |
| |
3146
| + /* Extract all possible characters from the date format. */ |
| |
3147
| + _possibleChars: function( format ) { |
| |
3148
| + var iFormat, |
| |
3149
| + chars = "", |
| |
3150
| + literal = false, |
| |
3151
| + |
| |
3152
| + // Check whether a format character is doubled |
| |
3153
| + lookAhead = function( match ) { |
| |
3154
| + var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match ); |
| |
3155
| + if ( matches ) { |
| |
3156
| + iFormat++; |
| |
3157
| + } |
| |
3158
| + return matches; |
| |
3159
| + }; |
| |
3160
| + |
| |
3161
| + for ( iFormat = 0; iFormat < format.length; iFormat++ ) { |
| |
3162
| + if ( literal ) { |
| |
3163
| + if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) { |
| |
3164
| + literal = false; |
| |
3165
| + } else { |
| |
3166
| + chars += format.charAt( iFormat ); |
| |
3167
| + } |
| |
3168
| + } else { |
| |
3169
| + switch ( format.charAt( iFormat ) ) { |
| |
3170
| + case "d": case "m": case "y": case "@": |
| |
3171
| + chars += "0123456789"; |
| |
3172
| + break; |
| |
3173
| + case "D": case "M": |
| |
3174
| + return null; // Accept anything |
| |
3175
| + case "'": |
| |
3176
| + if ( lookAhead( "'" ) ) { |
| |
3177
| + chars += "'"; |
| |
3178
| + } else { |
| |
3179
| + literal = true; |
| |
3180
| + } |
| |
3181
| + break; |
| |
3182
| + default: |
| |
3183
| + chars += format.charAt( iFormat ); |
| |
3184
| + } |
| |
3185
| + } |
| |
3186
| + } |
| |
3187
| + return chars; |
| |
3188
| + }, |
| |
3189
| + |
| |
3190
| + /* Get a setting value, defaulting if necessary. */ |
| |
3191
| + _get: function( inst, name ) { |
| |
3192
| + return inst.settings[ name ] !== undefined ? |
| |
3193
| + inst.settings[ name ] : this._defaults[ name ]; |
| |
3194
| + }, |
| |
3195
| + |
| |
3196
| + /* Parse existing date and initialise date picker. */ |
| |
3197
| + _setDateFromField: function( inst, noDefault ) { |
| |
3198
| + if ( inst.input.val() === inst.lastVal ) { |
| |
3199
| + return; |
| |
3200
| + } |
| |
3201
| + |
| |
3202
| + var dateFormat = this._get( inst, "dateFormat" ), |
| |
3203
| + dates = inst.lastVal = inst.input ? inst.input.val() : null, |
| |
3204
| + defaultDate = this._getDefaultDate( inst ), |
| |
3205
| + date = defaultDate, |
| |
3206
| + settings = this._getFormatConfig( inst ); |
| |
3207
| + |
| |
3208
| + try { |
| |
3209
| + date = this.parseDate( dateFormat, dates, settings ) || defaultDate; |
| |
3210
| + } catch ( event ) { |
| |
3211
| + dates = ( noDefault ? "" : dates ); |
| |
3212
| + } |
| |
3213
| + inst.selectedDay = date.getDate(); |
| |
3214
| + inst.drawMonth = inst.selectedMonth = date.getMonth(); |
| |
3215
| + inst.drawYear = inst.selectedYear = date.getFullYear(); |
| |
3216
| + inst.currentDay = ( dates ? date.getDate() : 0 ); |
| |
3217
| + inst.currentMonth = ( dates ? date.getMonth() : 0 ); |
| |
3218
| + inst.currentYear = ( dates ? date.getFullYear() : 0 ); |
| |
3219
| + this._adjustInstDate( inst ); |
| |
3220
| + }, |
| |
3221
| + |
| |
3222
| + /* Retrieve the default date shown on opening. */ |
| |
3223
| + _getDefaultDate: function( inst ) { |
| |
3224
| + return this._restrictMinMax( inst, |
| |
3225
| + this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) ); |
| |
3226
| + }, |
| |
3227
| + |
| |
3228
| + /* A date may be specified as an exact value or a relative one. */ |
| |
3229
| + _determineDate: function( inst, date, defaultDate ) { |
| |
3230
| + var offsetNumeric = function( offset ) { |
| |
3231
| + var date = new Date(); |
| |
3232
| + date.setDate( date.getDate() + offset ); |
| |
3233
| + return date; |
| |
3234
| + }, |
| |
3235
| + offsetString = function( offset ) { |
| |
3236
| + try { |
| |
3237
| + return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ), |
| |
3238
| + offset, $.datepicker._getFormatConfig( inst ) ); |
| |
3239
| + } |
| |
3240
| + catch ( e ) { |
| |
3241
| + |
| |
3242
| + // Ignore |
| |
3243
| + } |
| |
3244
| + |
| |
3245
| + var date = ( offset.toLowerCase().match( /^c/ ) ? |
| |
3246
| + $.datepicker._getDate( inst ) : null ) || new Date(), |
| |
3247
| + year = date.getFullYear(), |
| |
3248
| + month = date.getMonth(), |
| |
3249
| + day = date.getDate(), |
| |
3250
| + pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g, |
| |
3251
| + matches = pattern.exec( offset ); |
| |
3252
| + |
| |
3253
| + while ( matches ) { |
| |
3254
| + switch ( matches[ 2 ] || "d" ) { |
| |
3255
| + case "d" : case "D" : |
| |
3256
| + day += parseInt( matches[ 1 ], 10 ); break; |
| |
3257
| + case "w" : case "W" : |
| |
3258
| + day += parseInt( matches[ 1 ], 10 ) * 7; break; |
| |
3259
| + case "m" : case "M" : |
| |
3260
| + month += parseInt( matches[ 1 ], 10 ); |
| |
3261
| + day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); |
| |
3262
| + break; |
| |
3263
| + case "y": case "Y" : |
| |
3264
| + year += parseInt( matches[ 1 ], 10 ); |
| |
3265
| + day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) ); |
| |
3266
| + break; |
| |
3267
| + } |
| |
3268
| + matches = pattern.exec( offset ); |
| |
3269
| + } |
| |
3270
| + return new Date( year, month, day ); |
| |
3271
| + }, |
| |
3272
| + newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) : |
| |
3273
| + ( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) ); |
| |
3274
| + |
| |
3275
| + newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate ); |
| |
3276
| + if ( newDate ) { |
| |
3277
| + newDate.setHours( 0 ); |
| |
3278
| + newDate.setMinutes( 0 ); |
| |
3279
| + newDate.setSeconds( 0 ); |
| |
3280
| + newDate.setMilliseconds( 0 ); |
| |
3281
| + } |
| |
3282
| + return this._daylightSavingAdjust( newDate ); |
| |
3283
| + }, |
| |
3284
| + |
| |
3285
| + /* Handle switch to/from daylight saving. |
| |
3286
| + * Hours may be non-zero on daylight saving cut-over: |
| |
3287
| + * > 12 when midnight changeover, but then cannot generate |
| |
3288
| + * midnight datetime, so jump to 1AM, otherwise reset. |
| |
3289
| + * @param date (Date) the date to check |
| |
3290
| + * @return (Date) the corrected date |
| |
3291
| + */ |
| |
3292
| + _daylightSavingAdjust: function( date ) { |
| |
3293
| + if ( !date ) { |
| |
3294
| + return null; |
| |
3295
| + } |
| |
3296
| + date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 ); |
| |
3297
| + return date; |
| |
3298
| + }, |
| |
3299
| + |
| |
3300
| + /* Set the date(s) directly. */ |
| |
3301
| + _setDate: function( inst, date, noChange ) { |
| |
3302
| + var clear = !date, |
| |
3303
| + origMonth = inst.selectedMonth, |
| |
3304
| + origYear = inst.selectedYear, |
| |
3305
| + newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) ); |
| |
3306
| + |
| |
3307
| + inst.selectedDay = inst.currentDay = newDate.getDate(); |
| |
3308
| + inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); |
| |
3309
| + inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); |
| |
3310
| + if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) { |
| |
3311
| + this._notifyChange( inst ); |
| |
3312
| + } |
| |
3313
| + this._adjustInstDate( inst ); |
| |
3314
| + if ( inst.input ) { |
| |
3315
| + inst.input.val( clear ? "" : this._formatDate( inst ) ); |
| |
3316
| + } |
| |
3317
| + }, |
| |
3318
| + |
| |
3319
| + /* Retrieve the date(s) directly. */ |
| |
3320
| + _getDate: function( inst ) { |
| |
3321
| + var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null : |
| |
3322
| + this._daylightSavingAdjust( new Date( |
| |
3323
| + inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); |
| |
3324
| + return startDate; |
| |
3325
| + }, |
| |
3326
| + |
| |
3327
| + /* Attach the onxxx handlers. These are declared statically so |
| |
3328
| + * they work with static code transformers like Caja. |
| |
3329
| + */ |
| |
3330
| + _attachHandlers: function( inst ) { |
| |
3331
| + var stepMonths = this._get( inst, "stepMonths" ), |
| |
3332
| + id = "#" + inst.id.replace( /\\\\/g, "\\" ); |
| |
3333
| + inst.dpDiv.find( "[data-handler]" ).map( function() { |
| |
3334
| + var handler = { |
| |
3335
| + prev: function() { |
| |
3336
| + $.datepicker._adjustDate( id, -stepMonths, "M" ); |
| |
3337
| + }, |
| |
3338
| + next: function() { |
| |
3339
| + $.datepicker._adjustDate( id, +stepMonths, "M" ); |
| |
3340
| + }, |
| |
3341
| + hide: function() { |
| |
3342
| + $.datepicker._hideDatepicker(); |
| |
3343
| + }, |
| |
3344
| + today: function() { |
| |
3345
| + $.datepicker._gotoToday( id ); |
| |
3346
| + }, |
| |
3347
| + selectDay: function() { |
| |
3348
| + $.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this ); |
| |
3349
| + return false; |
| |
3350
| + }, |
| |
3351
| + selectMonth: function() { |
| |
3352
| + $.datepicker._selectMonthYear( id, this, "M" ); |
| |
3353
| + return false; |
| |
3354
| + }, |
| |
3355
| + selectYear: function() { |
| |
3356
| + $.datepicker._selectMonthYear( id, this, "Y" ); |
| |
3357
| + return false; |
| |
3358
| + } |
| |
3359
| + }; |
| |
3360
| + $( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] ); |
| |
3361
| + } ); |
| |
3362
| + }, |
| |
3363
| + |
| |
3364
| + /* Generate the HTML for the current state of the date picker. */ |
| |
3365
| + _generateHTML: function( inst ) { |
| |
3366
| + var maxDraw, prevText, prev, nextText, next, currentText, gotoDate, |
| |
3367
| + controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin, |
| |
3368
| + monthNames, monthNamesShort, beforeShowDay, showOtherMonths, |
| |
3369
| + selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate, |
| |
3370
| + cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows, |
| |
3371
| + printDate, dRow, tbody, daySettings, otherMonth, unselectable, |
| |
3372
| + tempDate = new Date(), |
| |
3373
| + today = this._daylightSavingAdjust( |
| |
3374
| + new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time |
| |
3375
| + isRTL = this._get( inst, "isRTL" ), |
| |
3376
| + showButtonPanel = this._get( inst, "showButtonPanel" ), |
| |
3377
| + hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ), |
| |
3378
| + navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ), |
| |
3379
| + numMonths = this._getNumberOfMonths( inst ), |
| |
3380
| + showCurrentAtPos = this._get( inst, "showCurrentAtPos" ), |
| |
3381
| + stepMonths = this._get( inst, "stepMonths" ), |
| |
3382
| + isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ), |
| |
3383
| + currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) : |
| |
3384
| + new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ), |
| |
3385
| + minDate = this._getMinMaxDate( inst, "min" ), |
| |
3386
| + maxDate = this._getMinMaxDate( inst, "max" ), |
| |
3387
| + drawMonth = inst.drawMonth - showCurrentAtPos, |
| |
3388
| + drawYear = inst.drawYear; |
| |
3389
| + |
| |
3390
| + if ( drawMonth < 0 ) { |
| |
3391
| + drawMonth += 12; |
| |
3392
| + drawYear--; |
| |
3393
| + } |
| |
3394
| + if ( maxDate ) { |
| |
3395
| + maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(), |
| |
3396
| + maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) ); |
| |
3397
| + maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw ); |
| |
3398
| + while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) { |
| |
3399
| + drawMonth--; |
| |
3400
| + if ( drawMonth < 0 ) { |
| |
3401
| + drawMonth = 11; |
| |
3402
| + drawYear--; |
| |
3403
| + } |
| |
3404
| + } |
| |
3405
| + } |
| |
3406
| + inst.drawMonth = drawMonth; |
| |
3407
| + inst.drawYear = drawYear; |
| |
3408
| + |
| |
3409
| + prevText = this._get( inst, "prevText" ); |
| |
3410
| + prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText, |
| |
3411
| + this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ), |
| |
3412
| + this._getFormatConfig( inst ) ) ); |
| |
3413
| + |
| |
3414
| + prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ? |
| |
3415
| + "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" + |
| |
3416
| + " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" : |
| |
3417
| + ( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" ) ); |
| |
3418
| + |
| |
3419
| + nextText = this._get( inst, "nextText" ); |
| |
3420
| + nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText, |
| |
3421
| + this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ), |
| |
3422
| + this._getFormatConfig( inst ) ) ); |
| |
3423
| + |
| |
3424
| + next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ? |
| |
3425
| + "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" + |
| |
3426
| + " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" : |
| |
3427
| + ( hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" ) ); |
| |
3428
| + |
| |
3429
| + currentText = this._get( inst, "currentText" ); |
| |
3430
| + gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today ); |
| |
3431
| + currentText = ( !navigationAsDateFormat ? currentText : |
| |
3432
| + this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) ); |
| |
3433
| + |
| |
3434
| + controls = ( !inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" + |
| |
3435
| + this._get( inst, "closeText" ) + "</button>" : "" ); |
| |
3436
| + |
| |
3437
| + buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) + |
| |
3438
| + ( this._isInRange( inst, gotoDate ) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" + |
| |
3439
| + ">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : ""; |
| |
3440
| + |
| |
3441
| + firstDay = parseInt( this._get( inst, "firstDay" ), 10 ); |
| |
3442
| + firstDay = ( isNaN( firstDay ) ? 0 : firstDay ); |
| |
3443
| + |
| |
3444
| + showWeek = this._get( inst, "showWeek" ); |
| |
3445
| + dayNames = this._get( inst, "dayNames" ); |
| |
3446
| + dayNamesMin = this._get( inst, "dayNamesMin" ); |
| |
3447
| + monthNames = this._get( inst, "monthNames" ); |
| |
3448
| + monthNamesShort = this._get( inst, "monthNamesShort" ); |
| |
3449
| + beforeShowDay = this._get( inst, "beforeShowDay" ); |
| |
3450
| + showOtherMonths = this._get( inst, "showOtherMonths" ); |
| |
3451
| + selectOtherMonths = this._get( inst, "selectOtherMonths" ); |
| |
3452
| + defaultDate = this._getDefaultDate( inst ); |
| |
3453
| + html = ""; |
| |
3454
| + |
| |
3455
| + for ( row = 0; row < numMonths[ 0 ]; row++ ) { |
| |
3456
| + group = ""; |
| |
3457
| + this.maxRows = 4; |
| |
3458
| + for ( col = 0; col < numMonths[ 1 ]; col++ ) { |
| |
3459
| + selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) ); |
| |
3460
| + cornerClass = " ui-corner-all"; |
| |
3461
| + calender = ""; |
| |
3462
| + if ( isMultiMonth ) { |
| |
3463
| + calender += "<div class='ui-datepicker-group"; |
| |
3464
| + if ( numMonths[ 1 ] > 1 ) { |
| |
3465
| + switch ( col ) { |
| |
3466
| + case 0: calender += " ui-datepicker-group-first"; |
| |
3467
| + cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break; |
| |
3468
| + case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last"; |
| |
3469
| + cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break; |
| |
3470
| + default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break; |
| |
3471
| + } |
| |
3472
| + } |
| |
3473
| + calender += "'>"; |
| |
3474
| + } |
| |
3475
| + calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" + |
| |
3476
| + ( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) + |
| |
3477
| + ( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) + |
| |
3478
| + this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate, |
| |
3479
| + row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers |
| |
3480
| + "</div><table class='ui-datepicker-calendar'><thead>" + |
| |
3481
| + "<tr>"; |
| |
3482
| + thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" ); |
| |
3483
| + for ( dow = 0; dow < 7; dow++ ) { // days of the week |
| |
3484
| + day = ( dow + firstDay ) % 7; |
| |
3485
| + thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" + |
| |
3486
| + "<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>"; |
| |
3487
| + } |
| |
3488
| + calender += thead + "</tr></thead><tbody>"; |
| |
3489
| + daysInMonth = this._getDaysInMonth( drawYear, drawMonth ); |
| |
3490
| + if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) { |
| |
3491
| + inst.selectedDay = Math.min( inst.selectedDay, daysInMonth ); |
| |
3492
| + } |
| |
3493
| + leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7; |
| |
3494
| + curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate |
| |
3495
| + numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043) |
| |
3496
| + this.maxRows = numRows; |
| |
3497
| + printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) ); |
| |
3498
| + for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows |
| |
3499
| + calender += "<tr>"; |
| |
3500
| + tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" + |
| |
3501
| + this._get( inst, "calculateWeek" )( printDate ) + "</td>" ); |
| |
3502
| + for ( dow = 0; dow < 7; dow++ ) { // create date picker days |
| |
3503
| + daySettings = ( beforeShowDay ? |
| |
3504
| + beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] ); |
| |
3505
| + otherMonth = ( printDate.getMonth() !== drawMonth ); |
| |
3506
| + unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] || |
| |
3507
| + ( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate ); |
| |
3508
| + tbody += "<td class='" + |
| |
3509
| + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends |
| |
3510
| + ( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months |
| |
3511
| + ( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key |
| |
3512
| + ( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ? |
| |
3513
| + |
| |
3514
| + // or defaultDate is current printedDate and defaultDate is selectedDate |
| |
3515
| + " " + this._dayOverClass : "" ) + // highlight selected day |
| |
3516
| + ( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) + // highlight unselectable days |
| |
3517
| + ( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates |
| |
3518
| + ( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day |
| |
3519
| + ( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different) |
| |
3520
| + ( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "'" ) + "'" : "" ) + // cell title |
| |
3521
| + ( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions |
| |
3522
| + ( otherMonth && !showOtherMonths ? " " : // display for other months |
| |
3523
| + ( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" + |
| |
3524
| + ( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) + |
| |
3525
| + ( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day |
| |
3526
| + ( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months |
| |
3527
| + "' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date |
| |
3528
| + printDate.setDate( printDate.getDate() + 1 ); |
| |
3529
| + printDate = this._daylightSavingAdjust( printDate ); |
| |
3530
| + } |
| |
3531
| + calender += tbody + "</tr>"; |
| |
3532
| + } |
| |
3533
| + drawMonth++; |
| |
3534
| + if ( drawMonth > 11 ) { |
| |
3535
| + drawMonth = 0; |
| |
3536
| + drawYear++; |
| |
3537
| + } |
| |
3538
| + calender += "</tbody></table>" + ( isMultiMonth ? "</div>" + |
| |
3539
| + ( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" ); |
| |
3540
| + group += calender; |
| |
3541
| + } |
| |
3542
| + html += group; |
| |
3543
| + } |
| |
3544
| + html += buttonPanel; |
| |
3545
| + inst._keyEvent = false; |
| |
3546
| + return html; |
| |
3547
| + }, |
| |
3548
| + |
| |
3549
| + /* Generate the month and year header. */ |
| |
3550
| + _generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate, |
| |
3551
| + secondary, monthNames, monthNamesShort ) { |
| |
3552
| + |
| |
3553
| + var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, |
| |
3554
| + changeMonth = this._get( inst, "changeMonth" ), |
| |
3555
| + changeYear = this._get( inst, "changeYear" ), |
| |
3556
| + showMonthAfterYear = this._get( inst, "showMonthAfterYear" ), |
| |
3557
| + html = "<div class='ui-datepicker-title'>", |
| |
3558
| + monthHtml = ""; |
| |
3559
| + |
| |
3560
| + // Month selection |
| |
3561
| + if ( secondary || !changeMonth ) { |
| |
3562
| + monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>"; |
| |
3563
| + } else { |
| |
3564
| + inMinYear = ( minDate && minDate.getFullYear() === drawYear ); |
| |
3565
| + inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear ); |
| |
3566
| + monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>"; |
| |
3567
| + for ( month = 0; month < 12; month++ ) { |
| |
3568
| + if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) { |
| |
3569
| + monthHtml += "<option value='" + month + "'" + |
| |
3570
| + ( month === drawMonth ? " selected='selected'" : "" ) + |
| |
3571
| + ">" + monthNamesShort[ month ] + "</option>"; |
| |
3572
| + } |
| |
3573
| + } |
| |
3574
| + monthHtml += "</select>"; |
| |
3575
| + } |
| |
3576
| + |
| |
3577
| + if ( !showMonthAfterYear ) { |
| |
3578
| + html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? " " : "" ); |
| |
3579
| + } |
| |
3580
| + |
| |
3581
| + // Year selection |
| |
3582
| + if ( !inst.yearshtml ) { |
| |
3583
| + inst.yearshtml = ""; |
| |
3584
| + if ( secondary || !changeYear ) { |
| |
3585
| + html += "<span class='ui-datepicker-year'>" + drawYear + "</span>"; |
| |
3586
| + } else { |
| |
3587
| + |
| |
3588
| + // determine range of years to display |
| |
3589
| + years = this._get( inst, "yearRange" ).split( ":" ); |
| |
3590
| + thisYear = new Date().getFullYear(); |
| |
3591
| + determineYear = function( value ) { |
| |
3592
| + var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) : |
| |
3593
| + ( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) : |
| |
3594
| + parseInt( value, 10 ) ) ); |
| |
3595
| + return ( isNaN( year ) ? thisYear : year ); |
| |
3596
| + }; |
| |
3597
| + year = determineYear( years[ 0 ] ); |
| |
3598
| + endYear = Math.max( year, determineYear( years[ 1 ] || "" ) ); |
| |
3599
| + year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year ); |
| |
3600
| + endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear ); |
| |
3601
| + inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>"; |
| |
3602
| + for ( ; year <= endYear; year++ ) { |
| |
3603
| + inst.yearshtml += "<option value='" + year + "'" + |
| |
3604
| + ( year === drawYear ? " selected='selected'" : "" ) + |
| |
3605
| + ">" + year + "</option>"; |
| |
3606
| + } |
| |
3607
| + inst.yearshtml += "</select>"; |
| |
3608
| + |
| |
3609
| + html += inst.yearshtml; |
| |
3610
| + inst.yearshtml = null; |
| |
3611
| + } |
| |
3612
| + } |
| |
3613
| + |
| |
3614
| + html += this._get( inst, "yearSuffix" ); |
| |
3615
| + if ( showMonthAfterYear ) { |
| |
3616
| + html += ( secondary || !( changeMonth && changeYear ) ? " " : "" ) + monthHtml; |
| |
3617
| + } |
| |
3618
| + html += "</div>"; // Close datepicker_header |
| |
3619
| + return html; |
| |
3620
| + }, |
| |
3621
| + |
| |
3622
| + /* Adjust one of the date sub-fields. */ |
| |
3623
| + _adjustInstDate: function( inst, offset, period ) { |
| |
3624
| + var year = inst.selectedYear + ( period === "Y" ? offset : 0 ), |
| |
3625
| + month = inst.selectedMonth + ( period === "M" ? offset : 0 ), |
| |
3626
| + day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ), |
| |
3627
| + date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) ); |
| |
3628
| + |
| |
3629
| + inst.selectedDay = date.getDate(); |
| |
3630
| + inst.drawMonth = inst.selectedMonth = date.getMonth(); |
| |
3631
| + inst.drawYear = inst.selectedYear = date.getFullYear(); |
| |
3632
| + if ( period === "M" || period === "Y" ) { |
| |
3633
| + this._notifyChange( inst ); |
| |
3634
| + } |
| |
3635
| + }, |
| |
3636
| + |
| |
3637
| + /* Ensure a date is within any min/max bounds. */ |
| |
3638
| + _restrictMinMax: function( inst, date ) { |
| |
3639
| + var minDate = this._getMinMaxDate( inst, "min" ), |
| |
3640
| + maxDate = this._getMinMaxDate( inst, "max" ), |
| |
3641
| + newDate = ( minDate && date < minDate ? minDate : date ); |
| |
3642
| + return ( maxDate && newDate > maxDate ? maxDate : newDate ); |
| |
3643
| + }, |
| |
3644
| + |
| |
3645
| + /* Notify change of month/year. */ |
| |
3646
| + _notifyChange: function( inst ) { |
| |
3647
| + var onChange = this._get( inst, "onChangeMonthYear" ); |
| |
3648
| + if ( onChange ) { |
| |
3649
| + onChange.apply( ( inst.input ? inst.input[ 0 ] : null ), |
| |
3650
| + [ inst.selectedYear, inst.selectedMonth + 1, inst ] ); |
| |
3651
| + } |
| |
3652
| + }, |
| |
3653
| + |
| |
3654
| + /* Determine the number of months to show. */ |
| |
3655
| + _getNumberOfMonths: function( inst ) { |
| |
3656
| + var numMonths = this._get( inst, "numberOfMonths" ); |
| |
3657
| + return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) ); |
| |
3658
| + }, |
| |
3659
| + |
| |
3660
| + /* Determine the current maximum date - ensure no time components are set. */ |
| |
3661
| + _getMinMaxDate: function( inst, minMax ) { |
| |
3662
| + return this._determineDate( inst, this._get( inst, minMax + "Date" ), null ); |
| |
3663
| + }, |
| |
3664
| + |
| |
3665
| + /* Find the number of days in a given month. */ |
| |
3666
| + _getDaysInMonth: function( year, month ) { |
| |
3667
| + return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate(); |
| |
3668
| + }, |
| |
3669
| + |
| |
3670
| + /* Find the day of the week of the first of a month. */ |
| |
3671
| + _getFirstDayOfMonth: function( year, month ) { |
| |
3672
| + return new Date( year, month, 1 ).getDay(); |
| |
3673
| + }, |
| |
3674
| + |
| |
3675
| + /* Determines if we should allow a "next/prev" month display change. */ |
| |
3676
| + _canAdjustMonth: function( inst, offset, curYear, curMonth ) { |
| |
3677
| + var numMonths = this._getNumberOfMonths( inst ), |
| |
3678
| + date = this._daylightSavingAdjust( new Date( curYear, |
| |
3679
| + curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) ); |
| |
3680
| + |
| |
3681
| + if ( offset < 0 ) { |
| |
3682
| + date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) ); |
| |
3683
| + } |
| |
3684
| + return this._isInRange( inst, date ); |
| |
3685
| + }, |
| |
3686
| + |
| |
3687
| + /* Is the given date in the accepted range? */ |
| |
3688
| + _isInRange: function( inst, date ) { |
| |
3689
| + var yearSplit, currentYear, |
| |
3690
| + minDate = this._getMinMaxDate( inst, "min" ), |
| |
3691
| + maxDate = this._getMinMaxDate( inst, "max" ), |
| |
3692
| + minYear = null, |
| |
3693
| + maxYear = null, |
| |
3694
| + years = this._get( inst, "yearRange" ); |
| |
3695
| + if ( years ) { |
| |
3696
| + yearSplit = years.split( ":" ); |
| |
3697
| + currentYear = new Date().getFullYear(); |
| |
3698
| + minYear = parseInt( yearSplit[ 0 ], 10 ); |
| |
3699
| + maxYear = parseInt( yearSplit[ 1 ], 10 ); |
| |
3700
| + if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) { |
| |
3701
| + minYear += currentYear; |
| |
3702
| + } |
| |
3703
| + if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) { |
| |
3704
| + maxYear += currentYear; |
| |
3705
| + } |
| |
3706
| + } |
| |
3707
| + |
| |
3708
| + return ( ( !minDate || date.getTime() >= minDate.getTime() ) && |
| |
3709
| + ( !maxDate || date.getTime() <= maxDate.getTime() ) && |
| |
3710
| + ( !minYear || date.getFullYear() >= minYear ) && |
| |
3711
| + ( !maxYear || date.getFullYear() <= maxYear ) ); |
| |
3712
| + }, |
| |
3713
| + |
| |
3714
| + /* Provide the configuration settings for formatting/parsing. */ |
| |
3715
| + _getFormatConfig: function( inst ) { |
| |
3716
| + var shortYearCutoff = this._get( inst, "shortYearCutoff" ); |
| |
3717
| + shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff : |
| |
3718
| + new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) ); |
| |
3719
| + return { shortYearCutoff: shortYearCutoff, |
| |
3720
| + dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ), |
| |
3721
| + monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) }; |
| |
3722
| + }, |
| |
3723
| + |
| |
3724
| + /* Format the given date for display. */ |
| |
3725
| + _formatDate: function( inst, day, month, year ) { |
| |
3726
| + if ( !day ) { |
| |
3727
| + inst.currentDay = inst.selectedDay; |
| |
3728
| + inst.currentMonth = inst.selectedMonth; |
| |
3729
| + inst.currentYear = inst.selectedYear; |
| |
3730
| + } |
| |
3731
| + var date = ( day ? ( typeof day === "object" ? day : |
| |
3732
| + this._daylightSavingAdjust( new Date( year, month, day ) ) ) : |
| |
3733
| + this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ); |
| |
3734
| + return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) ); |
| |
3735
| + } |
| |
3736
| +} ); |
| |
3737
| + |
| |
3738
| +/* |
| |
3739
| + * Bind hover events for datepicker elements. |
| |
3740
| + * Done via delegate so the binding only occurs once in the lifetime of the parent div. |
| |
3741
| + * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. |
| |
3742
| + */ |
| |
3743
| +function datepicker_bindHover( dpDiv ) { |
| |
3744
| + var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; |
| |
3745
| + return dpDiv.on( "mouseout", selector, function() { |
| |
3746
| + $( this ).removeClass( "ui-state-hover" ); |
| |
3747
| + if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { |
| |
3748
| + $( this ).removeClass( "ui-datepicker-prev-hover" ); |
| |
3749
| + } |
| |
3750
| + if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { |
| |
3751
| + $( this ).removeClass( "ui-datepicker-next-hover" ); |
| |
3752
| + } |
| |
3753
| + } ) |
| |
3754
| + .on( "mouseover", selector, datepicker_handleMouseover ); |
| |
3755
| +} |
| |
3756
| + |
| |
3757
| +function datepicker_handleMouseover() { |
| |
3758
| + if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) { |
| |
3759
| + $( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" ); |
| |
3760
| + $( this ).addClass( "ui-state-hover" ); |
| |
3761
| + if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) { |
| |
3762
| + $( this ).addClass( "ui-datepicker-prev-hover" ); |
| |
3763
| + } |
| |
3764
| + if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) { |
| |
3765
| + $( this ).addClass( "ui-datepicker-next-hover" ); |
| |
3766
| + } |
| |
3767
| + } |
| |
3768
| +} |
| |
3769
| + |
| |
3770
| +/* jQuery extend now ignores nulls! */ |
| |
3771
| +function datepicker_extendRemove( target, props ) { |
| |
3772
| + $.extend( target, props ); |
| |
3773
| + for ( var name in props ) { |
| |
3774
| + if ( props[ name ] == null ) { |
| |
3775
| + target[ name ] = props[ name ]; |
| |
3776
| + } |
| |
3777
| + } |
| |
3778
| + return target; |
| |
3779
| +} |
| |
3780
| + |
| |
3781
| +/* Invoke the datepicker functionality. |
| |
3782
| + @param options string - a command, optionally followed by additional parameters or |
| |
3783
| + Object - settings for attaching new datepicker functionality |
| |
3784
| + @return jQuery object */ |
| |
3785
| +$.fn.datepicker = function( options ) { |
| |
3786
| + |
| |
3787
| + /* Verify an empty collection wasn't passed - Fixes #6976 */ |
| |
3788
| + if ( !this.length ) { |
| |
3789
| + return this; |
| |
3790
| + } |
| |
3791
| + |
| |
3792
| + /* Initialise the date picker. */ |
| |
3793
| + if ( !$.datepicker.initialized ) { |
| |
3794
| + $( document ).on( "mousedown", $.datepicker._checkExternalClick ); |
| |
3795
| + $.datepicker.initialized = true; |
| |
3796
| + } |
| |
3797
| + |
| |
3798
| + /* Append datepicker main container to body if not exist. */ |
| |
3799
| + if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) { |
| |
3800
| + $( "body" ).append( $.datepicker.dpDiv ); |
| |
3801
| + } |
| |
3802
| + |
| |
3803
| + var otherArgs = Array.prototype.slice.call( arguments, 1 ); |
| |
3804
| + if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) { |
| |
3805
| + return $.datepicker[ "_" + options + "Datepicker" ]. |
| |
3806
| + apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); |
| |
3807
| + } |
| |
3808
| + if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) { |
| |
3809
| + return $.datepicker[ "_" + options + "Datepicker" ]. |
| |
3810
| + apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) ); |
| |
3811
| + } |
| |
3812
| + return this.each( function() { |
| |
3813
| + typeof options === "string" ? |
| |
3814
| + $.datepicker[ "_" + options + "Datepicker" ]. |
| |
3815
| + apply( $.datepicker, [ this ].concat( otherArgs ) ) : |
| |
3816
| + $.datepicker._attachDatepicker( this, options ); |
| |
3817
| + } ); |
| |
3818
| +}; |
| |
3819
| + |
| |
3820
| +$.datepicker = new Datepicker(); // singleton instance |
| |
3821
| +$.datepicker.initialized = false; |
| |
3822
| +$.datepicker.uuid = new Date().getTime(); |
| |
3823
| +$.datepicker.version = "1.12.1"; |
| |
3824
| + |
| |
3825
| +var widgetsDatepicker = $.datepicker; |
| |
3826
| + |
| |
3827
| + |
| |
3828
| + |
| |
3829
| + |
| |
3830
| +})); |
0
| \ No newline at end of file |
3831
| \ No newline at end of file |