4
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5
* Dual licensed under the MIT or GPL Version 2 licenses.
6
* http://jquery.org/license
8
* http://docs.jquery.com/UI
10
(function( $, undefined ) {
12
// prevent duplicate loading
13
// this is only a problem because we proxy existing functions
14
// and we don't want to double proxy them
29
COMMAND_LEFT: 91, // COMMAND
40
MENU: 93, // COMMAND_RIGHT
55
WINDOWS: 91 // COMMAND
61
propAttr: $.fn.prop || $.fn.attr,
64
focus: function( delay, fn ) {
65
return typeof delay === "number" ?
66
this.each(function() {
68
setTimeout(function() {
75
this._focus.apply( this, arguments );
78
scrollParent: function() {
80
if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
81
scrollParent = this.parents().filter(function() {
82
return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
85
scrollParent = this.parents().filter(function() {
86
return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
90
return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
93
zIndex: function( zIndex ) {
94
if ( zIndex !== undefined ) {
95
return this.css( "zIndex", zIndex );
99
var elem = $( this[ 0 ] ), position, value;
100
while ( elem.length && elem[ 0 ] !== document ) {
101
// Ignore z-index if position is set to a value where z-index is ignored by the browser
102
// This makes behavior of this function consistent across browsers
103
// WebKit always returns auto if the element is positioned
104
position = elem.css( "position" );
105
if ( position === "absolute" || position === "relative" || position === "fixed" ) {
106
// IE returns 0 when zIndex is not specified
107
// other browsers return a string
108
// we ignore the case of nested elements with an explicit value of 0
109
// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
110
value = parseInt( elem.css( "zIndex" ), 10 );
111
if ( !isNaN( value ) && value !== 0 ) {
115
elem = elem.parent();
122
disableSelection: function() {
123
return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
124
".ui-disableSelection", function( event ) {
125
event.preventDefault();
129
enableSelection: function() {
130
return this.unbind( ".ui-disableSelection" );
134
$.each( [ "Width", "Height" ], function( i, name ) {
135
var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
136
type = name.toLowerCase(),
138
innerWidth: $.fn.innerWidth,
139
innerHeight: $.fn.innerHeight,
140
outerWidth: $.fn.outerWidth,
141
outerHeight: $.fn.outerHeight
144
function reduce( elem, size, border, margin ) {
145
$.each( side, function() {
146
size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0;
148
size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0;
151
size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0;
157
$.fn[ "inner" + name ] = function( size ) {
158
if ( size === undefined ) {
159
return orig[ "inner" + name ].call( this );
162
return this.each(function() {
163
$( this ).css( type, reduce( this, size ) + "px" );
167
$.fn[ "outer" + name] = function( size, margin ) {
168
if ( typeof size !== "number" ) {
169
return orig[ "outer" + name ].call( this, size );
172
return this.each(function() {
173
$( this).css( type, reduce( this, size, true, margin ) + "px" );
179
function focusable( element, isTabIndexNotNaN ) {
180
var nodeName = element.nodeName.toLowerCase();
181
if ( "area" === nodeName ) {
182
var map = element.parentNode,
185
if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
188
img = $( "img[usemap=#" + mapName + "]" )[0];
189
return !!img && visible( img );
191
return ( /input|select|textarea|button|object/.test( nodeName )
194
? element.href || isTabIndexNotNaN
196
// the element and all of its ancestors must be visible
197
&& visible( element );
200
function visible( element ) {
201
return !$( element ).parents().andSelf().filter(function() {
202
return $.curCSS( this, "visibility" ) === "hidden" ||
203
$.expr.filters.hidden( this );
207
$.extend( $.expr[ ":" ], {
208
data: function( elem, i, match ) {
209
return !!$.data( elem, match[ 3 ] );
212
focusable: function( element ) {
213
return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
216
tabbable: function( element ) {
217
var tabIndex = $.attr( element, "tabindex" ),
218
isTabIndexNaN = isNaN( tabIndex );
219
return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
225
var body = document.body,
226
div = body.appendChild( div = document.createElement( "div" ) );
228
// access offsetHeight before setting the style to prevent a layout bug
229
// in IE 9 which causes the elemnt to continue to take up space even
230
// after it is removed from the DOM (#8026)
233
$.extend( div.style, {
240
$.support.minHeight = div.offsetHeight === 100;
241
$.support.selectstart = "onselectstart" in div;
243
// set display to none to avoid a layout bug in IE
244
// http://dev.jquery.com/ticket/4014
245
body.removeChild( div ).style.display = "none";
254
// $.ui.plugin is deprecated. Use the proxy pattern instead.
256
add: function( module, option, set ) {
257
var proto = $.ui[ module ].prototype;
258
for ( var i in set ) {
259
proto.plugins[ i ] = proto.plugins[ i ] || [];
260
proto.plugins[ i ].push( [ option, set[ i ] ] );
263
call: function( instance, name, args ) {
264
var set = instance.plugins[ name ];
265
if ( !set || !instance.element[ 0 ].parentNode ) {
269
for ( var i = 0; i < set.length; i++ ) {
270
if ( instance.options[ set[ i ][ 0 ] ] ) {
271
set[ i ][ 1 ].apply( instance.element, args );
277
// will be deprecated when we switch to jQuery 1.4 - use jQuery.contains()
278
contains: function( a, b ) {
279
return document.compareDocumentPosition ?
280
a.compareDocumentPosition( b ) & 16 :
281
a !== b && a.contains( b );
284
// only used by resizable
285
hasScroll: function( el, a ) {
287
//If overflow is hidden, the element might have extra content, but the user wants to hide it
288
if ( $( el ).css( "overflow" ) === "hidden") {
292
var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
295
if ( el[ scroll ] > 0 ) {
299
// TODO: determine which cases actually cause this to happen
300
// if the element doesn't have the scroll set, see if it's possible to
303
has = ( el[ scroll ] > 0 );
308
// these are odd functions, fix the API or move into individual plugins
309
isOverAxis: function( x, reference, size ) {
310
//Determines when x coordinate is over "b" element axis
311
return ( x > reference ) && ( x < ( reference + size ) );
313
isOver: function( y, x, top, left, height, width ) {
314
//Determines when x, y coordinates is over "b" element
315
return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
321
* jQuery UI Widget 1.8.18
323
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
324
* Dual licensed under the MIT or GPL Version 2 licenses.
325
* http://jquery.org/license
327
* http://docs.jquery.com/UI/Widget
329
(function( $, undefined ) {
333
var _cleanData = $.cleanData;
334
$.cleanData = function( elems ) {
335
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
337
$( elem ).triggerHandler( "remove" );
338
// http://bugs.jquery.com/ticket/8235
344
var _remove = $.fn.remove;
345
$.fn.remove = function( selector, keepData ) {
346
return this.each(function() {
348
if ( !selector || $.filter( selector, [ this ] ).length ) {
349
$( "*", this ).add( [ this ] ).each(function() {
351
$( this ).triggerHandler( "remove" );
352
// http://bugs.jquery.com/ticket/8235
357
return _remove.call( $(this), selector, keepData );
362
$.widget = function( name, base, prototype ) {
363
var namespace = name.split( "." )[ 0 ],
365
name = name.split( "." )[ 1 ];
366
fullName = namespace + "-" + name;
373
// create selector for plugin
374
$.expr[ ":" ][ fullName ] = function( elem ) {
375
return !!$.data( elem, name );
378
$[ namespace ] = $[ namespace ] || {};
379
$[ namespace ][ name ] = function( options, element ) {
380
// allow instantiation without initializing for simple inheritance
381
if ( arguments.length ) {
382
this._createWidget( options, element );
386
var basePrototype = new base();
387
// we need to make the options hash a property directly on the new instance
388
// otherwise we'll modify the options hash on the prototype that we're
390
// $.each( basePrototype, function( key, val ) {
391
// if ( $.isPlainObject(val) ) {
392
// basePrototype[ key ] = $.extend( {}, val );
395
basePrototype.options = $.extend( true, {}, basePrototype.options );
396
$[ namespace ][ name ].prototype = $.extend( true, basePrototype, {
397
namespace: namespace,
399
widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,
400
widgetBaseClass: fullName
403
$.widget.bridge( name, $[ namespace ][ name ] );
406
$.widget.bridge = function( name, object ) {
407
$.fn[ name ] = function( options ) {
408
var isMethodCall = typeof options === "string",
409
args = Array.prototype.slice.call( arguments, 1 ),
412
// allow multiple hashes to be passed on init
413
options = !isMethodCall && args.length ?
414
$.extend.apply( null, [ true, options ].concat(args) ) :
417
// prevent calls to internal methods
418
if ( isMethodCall && options.charAt( 0 ) === "_" ) {
422
if ( isMethodCall ) {
423
this.each(function() {
424
var instance = $.data( this, name ),
425
methodValue = instance && $.isFunction( instance[options] ) ?
426
instance[ options ].apply( instance, args ) :
428
// TODO: add this back in 1.9 and use $.error() (see #5972)
429
// if ( !instance ) {
430
// throw "cannot call methods on " + name + " prior to initialization; " +
431
// "attempted to call method '" + options + "'";
433
// if ( !$.isFunction( instance[options] ) ) {
434
// throw "no such method '" + options + "' for " + name + " widget instance";
436
// var methodValue = instance[ options ].apply( instance, args );
437
if ( methodValue !== instance && methodValue !== undefined ) {
438
returnValue = methodValue;
443
this.each(function() {
444
var instance = $.data( this, name );
446
instance.option( options || {} )._init();
448
$.data( this, name, new object( options, this ) );
457
$.Widget = function( options, element ) {
458
// allow instantiation without initializing for simple inheritance
459
if ( arguments.length ) {
460
this._createWidget( options, element );
464
$.Widget.prototype = {
465
widgetName: "widget",
466
widgetEventPrefix: "",
470
_createWidget: function( options, element ) {
471
// $.widget.bridge stores the plugin instance, but we do it anyway
472
// so that it's stored even before the _create function runs
473
$.data( element, this.widgetName, this );
474
this.element = $( element );
475
this.options = $.extend( true, {},
477
this._getCreateOptions(),
481
this.element.bind( "remove." + this.widgetName, function() {
486
this._trigger( "create" );
489
_getCreateOptions: function() {
490
return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
492
_create: function() {},
493
_init: function() {},
495
destroy: function() {
497
.unbind( "." + this.widgetName )
498
.removeData( this.widgetName );
500
.unbind( "." + this.widgetName )
501
.removeAttr( "aria-disabled" )
503
this.widgetBaseClass + "-disabled " +
504
"ui-state-disabled" );
511
option: function( key, value ) {
514
if ( arguments.length === 0 ) {
515
// don't return a reference to the internal hash
516
return $.extend( {}, this.options );
519
if (typeof key === "string" ) {
520
if ( value === undefined ) {
521
return this.options[ key ];
524
options[ key ] = value;
527
this._setOptions( options );
531
_setOptions: function( options ) {
533
$.each( options, function( key, value ) {
534
self._setOption( key, value );
539
_setOption: function( key, value ) {
540
this.options[ key ] = value;
542
if ( key === "disabled" ) {
544
[ value ? "addClass" : "removeClass"](
545
this.widgetBaseClass + "-disabled" + " " +
546
"ui-state-disabled" )
547
.attr( "aria-disabled", value );
554
return this._setOption( "disabled", false );
556
disable: function() {
557
return this._setOption( "disabled", true );
560
_trigger: function( type, event, data ) {
562
callback = this.options[ type ];
565
event = $.Event( event );
566
event.type = ( type === this.widgetEventPrefix ?
568
this.widgetEventPrefix + type ).toLowerCase();
569
// the original event may come from any element
570
// so we need to reset the target on the new event
571
event.target = this.element[ 0 ];
573
// copy original event properties over to the new event
574
orig = event.originalEvent;
576
for ( prop in orig ) {
577
if ( !( prop in event ) ) {
578
event[ prop ] = orig[ prop ];
583
this.element.trigger( event, data );
585
return !( $.isFunction(callback) &&
586
callback.call( this.element[0], event, data ) === false ||
587
event.isDefaultPrevented() );
593
* jQuery UI Mouse 1.8.18
595
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
596
* Dual licensed under the MIT or GPL Version 2 licenses.
597
* http://jquery.org/license
599
* http://docs.jquery.com/UI/Mouse
602
* jquery.ui.widget.js
604
(function( $, undefined ) {
606
var mouseHandled = false;
607
$( document ).mouseup( function( e ) {
608
mouseHandled = false;
611
$.widget("ui.mouse", {
613
cancel: ':input,option',
617
_mouseInit: function() {
621
.bind('mousedown.'+this.widgetName, function(event) {
622
return self._mouseDown(event);
624
.bind('click.'+this.widgetName, function(event) {
625
if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) {
626
$.removeData(event.target, self.widgetName + '.preventClickEvent');
627
event.stopImmediatePropagation();
632
this.started = false;
635
// TODO: make sure destroying one instance of mouse doesn't mess with
636
// other instances of mouse
637
_mouseDestroy: function() {
638
this.element.unbind('.'+this.widgetName);
641
_mouseDown: function(event) {
642
// don't let more than one widget handle mouseStart
643
if( mouseHandled ) { return };
645
// we may have missed mouseup (out of window)
646
(this._mouseStarted && this._mouseUp(event));
648
this._mouseDownEvent = event;
651
btnIsLeft = (event.which == 1),
652
// event.target.nodeName works around a bug in IE 8 with
653
// disabled inputs (#7620)
654
elIsCancel = (typeof this.options.cancel == "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
655
if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
659
this.mouseDelayMet = !this.options.delay;
660
if (!this.mouseDelayMet) {
661
this._mouseDelayTimer = setTimeout(function() {
662
self.mouseDelayMet = true;
663
}, this.options.delay);
666
if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
667
this._mouseStarted = (this._mouseStart(event) !== false);
668
if (!this._mouseStarted) {
669
event.preventDefault();
674
// Click event may never have fired (Gecko & Opera)
675
if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) {
676
$.removeData(event.target, this.widgetName + '.preventClickEvent');
679
// these delegates are required to keep context
680
this._mouseMoveDelegate = function(event) {
681
return self._mouseMove(event);
683
this._mouseUpDelegate = function(event) {
684
return self._mouseUp(event);
687
.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
688
.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
690
event.preventDefault();
696
_mouseMove: function(event) {
697
// IE mouseup check - mouseup happened when mouse was out of window
698
if ($.browser.msie && !(document.documentMode >= 9) && !event.button) {
699
return this._mouseUp(event);
702
if (this._mouseStarted) {
703
this._mouseDrag(event);
704
return event.preventDefault();
707
if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
709
(this._mouseStart(this._mouseDownEvent, event) !== false);
710
(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
713
return !this._mouseStarted;
716
_mouseUp: function(event) {
718
.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
719
.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
721
if (this._mouseStarted) {
722
this._mouseStarted = false;
724
if (event.target == this._mouseDownEvent.target) {
725
$.data(event.target, this.widgetName + '.preventClickEvent', true);
728
this._mouseStop(event);
734
_mouseDistanceMet: function(event) {
736
Math.abs(this._mouseDownEvent.pageX - event.pageX),
737
Math.abs(this._mouseDownEvent.pageY - event.pageY)
738
) >= this.options.distance
742
_mouseDelayMet: function(event) {
743
return this.mouseDelayMet;
746
// These are placeholder methods, to be overriden by extending plugin
747
_mouseStart: function(event) {},
748
_mouseDrag: function(event) {},
749
_mouseStop: function(event) {},
750
_mouseCapture: function(event) { return true; }
755
* jQuery UI Draggable 1.8.18
757
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
758
* Dual licensed under the MIT or GPL Version 2 licenses.
759
* http://jquery.org/license
761
* http://docs.jquery.com/UI/Draggables
766
* jquery.ui.widget.js
768
(function( $, undefined ) {
770
$.widget("ui.draggable", $.ui.mouse, {
771
widgetEventPrefix: "drag",
776
connectToSortable: false,
785
refreshPositions: false,
790
scrollSensitivity: 20,
798
_create: function() {
800
if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
801
this.element[0].style.position = 'relative';
803
(this.options.addClasses && this.element.addClass("ui-draggable"));
804
(this.options.disabled && this.element.addClass("ui-draggable-disabled"));
810
destroy: function() {
811
if(!this.element.data('draggable')) return;
813
.removeData("draggable")
814
.unbind(".draggable")
815
.removeClass("ui-draggable"
816
+ " ui-draggable-dragging"
817
+ " ui-draggable-disabled");
818
this._mouseDestroy();
823
_mouseCapture: function(event) {
825
var o = this.options;
827
// among others, prevent a drag on a resizable-handle
828
if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
831
//Quit if we're not on a valid handle
832
this.handle = this._getHandle(event);
837
$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
838
$('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
840
width: this.offsetWidth+"px", height: this.offsetHeight+"px",
841
position: "absolute", opacity: "0.001", zIndex: 1000
843
.css($(this).offset())
852
_mouseStart: function(event) {
854
var o = this.options;
856
//Create and append the visible helper
857
this.helper = this._createHelper(event);
859
//Cache the helper size
860
this._cacheHelperProportions();
862
//If ddmanager is used for droppables, set the global draggable
864
$.ui.ddmanager.current = this;
867
* - Position generation -
868
* This block generates everything position related - it's the core of draggables.
871
//Cache the margins of the original element
872
this._cacheMargins();
874
//Store the helper's css position
875
this.cssPosition = this.helper.css("position");
876
this.scrollParent = this.helper.scrollParent();
878
//The element's absolute position on the page minus margins
879
this.offset = this.positionAbs = this.element.offset();
881
top: this.offset.top - this.margins.top,
882
left: this.offset.left - this.margins.left
885
$.extend(this.offset, {
886
click: { //Where the click happened, relative to the element
887
left: event.pageX - this.offset.left,
888
top: event.pageY - this.offset.top
890
parent: this._getParentOffset(),
891
relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
894
//Generate the original position
895
this.originalPosition = this.position = this._generatePosition(event);
896
this.originalPageX = event.pageX;
897
this.originalPageY = event.pageY;
899
//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
900
(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
902
//Set a containment if given in the options
904
this._setContainment();
906
//Trigger event + callbacks
907
if(this._trigger("start", event) === false) {
912
//Recache the helper size
913
this._cacheHelperProportions();
915
//Prepare the droppable offsets
916
if ($.ui.ddmanager && !o.dropBehaviour)
917
$.ui.ddmanager.prepareOffsets(this, event);
919
this.helper.addClass("ui-draggable-dragging");
920
this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
922
//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
923
if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event);
928
_mouseDrag: function(event, noPropagation) {
930
//Compute the helpers position
931
this.position = this._generatePosition(event);
932
this.positionAbs = this._convertPositionTo("absolute");
934
//Call plugins and callbacks and use the resulting position if something is returned
935
if (!noPropagation) {
936
var ui = this._uiHash();
937
if(this._trigger('drag', event, ui) === false) {
941
this.position = ui.position;
944
if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
945
if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
946
if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
951
_mouseStop: function(event) {
953
//If we are using droppables, inform the manager about the drop
955
if ($.ui.ddmanager && !this.options.dropBehaviour)
956
dropped = $.ui.ddmanager.drop(this, event);
958
//if a drop comes from outside (a sortable)
960
dropped = this.dropped;
961
this.dropped = false;
964
//if the original element is removed, don't bother to continue if helper is set to "original"
965
if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original")
968
if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
970
$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
971
if(self._trigger("stop", event) !== false) {
976
if(this._trigger("stop", event) !== false) {
984
_mouseUp: function(event) {
985
if (this.options.iframeFix === true) {
986
$("div.ui-draggable-iframeFix").each(function() {
987
this.parentNode.removeChild(this);
988
}); //Remove frame helpers
991
//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
992
if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
994
return $.ui.mouse.prototype._mouseUp.call(this, event);
999
if(this.helper.is(".ui-draggable-dragging")) {
1009
_getHandle: function(event) {
1011
var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
1012
$(this.options.handle, this.element)
1016
if(this == event.target) handle = true;
1023
_createHelper: function(event) {
1025
var o = this.options;
1026
var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element);
1028
if(!helper.parents('body').length)
1029
helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
1031
if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
1032
helper.css("position", "absolute");
1038
_adjustOffsetFromHelper: function(obj) {
1039
if (typeof obj == 'string') {
1040
obj = obj.split(' ');
1042
if ($.isArray(obj)) {
1043
obj = {left: +obj[0], top: +obj[1] || 0};
1045
if ('left' in obj) {
1046
this.offset.click.left = obj.left + this.margins.left;
1048
if ('right' in obj) {
1049
this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1052
this.offset.click.top = obj.top + this.margins.top;
1054
if ('bottom' in obj) {
1055
this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1059
_getParentOffset: function() {
1061
//Get the offsetParent and cache its position
1062
this.offsetParent = this.helper.offsetParent();
1063
var po = this.offsetParent.offset();
1065
// This is a special case where we need to modify a offset calculated on start, since the following happened:
1066
// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1067
// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1068
// the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1069
if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
1070
po.left += this.scrollParent.scrollLeft();
1071
po.top += this.scrollParent.scrollTop();
1074
if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1075
|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
1076
po = { top: 0, left: 0 };
1079
top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1080
left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1085
_getRelativeOffset: function() {
1087
if(this.cssPosition == "relative") {
1088
var p = this.element.position();
1090
top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1091
left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1094
return { top: 0, left: 0 };
1099
_cacheMargins: function() {
1101
left: (parseInt(this.element.css("marginLeft"),10) || 0),
1102
top: (parseInt(this.element.css("marginTop"),10) || 0),
1103
right: (parseInt(this.element.css("marginRight"),10) || 0),
1104
bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1108
_cacheHelperProportions: function() {
1109
this.helperProportions = {
1110
width: this.helper.outerWidth(),
1111
height: this.helper.outerHeight()
1115
_setContainment: function() {
1117
var o = this.options;
1118
if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
1119
if(o.containment == 'document' || o.containment == 'window') this.containment = [
1120
o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1121
o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1122
(o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
1123
(o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1126
if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
1127
var c = $(o.containment);
1128
var ce = c[0]; if(!ce) return;
1129
var co = c.offset();
1130
var over = ($(ce).css("overflow") != 'hidden');
1132
this.containment = [
1133
(parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0),
1134
(parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0),
1135
(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right,
1136
(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom
1138
this.relative_container = c;
1140
} else if(o.containment.constructor == Array) {
1141
this.containment = o.containment;
1146
_convertPositionTo: function(d, pos) {
1148
if(!pos) pos = this.position;
1149
var mod = d == "absolute" ? 1 : -1;
1150
var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1154
pos.top // The absolute mouse position
1155
+ this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
1156
+ this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
1157
- ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1160
pos.left // The absolute mouse position
1161
+ this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
1162
+ this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
1163
- ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1169
_generatePosition: function(event) {
1171
var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1172
var pageX = event.pageX;
1173
var pageY = event.pageY;
1176
* - Position constraining -
1177
* Constrain the position to a mix of grid, containment.
1180
if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1182
if(this.containment) {
1183
if (this.relative_container){
1184
var co = this.relative_container.offset();
1185
containment = [ this.containment[0] + co.left,
1186
this.containment[1] + co.top,
1187
this.containment[2] + co.left,
1188
this.containment[3] + co.top ];
1191
containment = this.containment;
1194
if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left;
1195
if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top;
1196
if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left;
1197
if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top;
1201
//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1202
var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1203
pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
1205
var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1206
pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
1213
pageY // The absolute mouse position
1214
- this.offset.click.top // Click offset (relative to the element)
1215
- this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
1216
- this.offset.parent.top // The offsetParent's offset without borders (offset + border)
1217
+ ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1220
pageX // The absolute mouse position
1221
- this.offset.click.left // Click offset (relative to the element)
1222
- this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
1223
- this.offset.parent.left // The offsetParent's offset without borders (offset + border)
1224
+ ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1230
_clear: function() {
1231
this.helper.removeClass("ui-draggable-dragging");
1232
if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
1233
//if($.ui.ddmanager) $.ui.ddmanager.current = null;
1235
this.cancelHelperRemoval = false;
1238
// From now on bulk stuff - mainly helpers
1240
_trigger: function(type, event, ui) {
1241
ui = ui || this._uiHash();
1242
$.ui.plugin.call(this, type, [event, ui]);
1243
if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
1244
return $.Widget.prototype._trigger.call(this, type, event, ui);
1249
_uiHash: function(event) {
1251
helper: this.helper,
1252
position: this.position,
1253
originalPosition: this.originalPosition,
1254
offset: this.positionAbs
1260
$.extend($.ui.draggable, {
1264
$.ui.plugin.add("draggable", "connectToSortable", {
1265
start: function(event, ui) {
1267
var inst = $(this).data("draggable"), o = inst.options,
1268
uiSortable = $.extend({}, ui, { item: inst.element });
1269
inst.sortables = [];
1270
$(o.connectToSortable).each(function() {
1271
var sortable = $.data(this, 'sortable');
1272
if (sortable && !sortable.options.disabled) {
1273
inst.sortables.push({
1275
shouldRevert: sortable.options.revert
1277
sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
1278
sortable._trigger("activate", event, uiSortable);
1283
stop: function(event, ui) {
1285
//If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1286
var inst = $(this).data("draggable"),
1287
uiSortable = $.extend({}, ui, { item: inst.element });
1289
$.each(inst.sortables, function() {
1290
if(this.instance.isOver) {
1292
this.instance.isOver = 0;
1294
inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1295
this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1297
//The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
1298
if(this.shouldRevert) this.instance.options.revert = true;
1300
//Trigger the stop of the sortable
1301
this.instance._mouseStop(event);
1303
this.instance.options.helper = this.instance.options._helper;
1305
//If the helper has been the original item, restore properties in the sortable
1306
if(inst.options.helper == 'original')
1307
this.instance.currentItem.css({ top: 'auto', left: 'auto' });
1310
this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1311
this.instance._trigger("deactivate", event, uiSortable);
1317
drag: function(event, ui) {
1319
var inst = $(this).data("draggable"), self = this;
1321
var checkPos = function(o) {
1322
var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
1323
var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
1324
var itemHeight = o.height, itemWidth = o.width;
1325
var itemTop = o.top, itemLeft = o.left;
1327
return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
1330
$.each(inst.sortables, function(i) {
1332
//Copy over some variables to allow calling the sortable's native _intersectsWith
1333
this.instance.positionAbs = inst.positionAbs;
1334
this.instance.helperProportions = inst.helperProportions;
1335
this.instance.offset.click = inst.offset.click;
1337
if(this.instance._intersectsWith(this.instance.containerCache)) {
1339
//If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1340
if(!this.instance.isOver) {
1342
this.instance.isOver = 1;
1343
//Now we fake the start of dragging for the sortable instance,
1344
//by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1345
//We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
1346
this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true);
1347
this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1348
this.instance.options.helper = function() { return ui.helper[0]; };
1350
event.target = this.instance.currentItem[0];
1351
this.instance._mouseCapture(event, true);
1352
this.instance._mouseStart(event, true, true);
1354
//Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1355
this.instance.offset.click.top = inst.offset.click.top;
1356
this.instance.offset.click.left = inst.offset.click.left;
1357
this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1358
this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1360
inst._trigger("toSortable", event);
1361
inst.dropped = this.instance.element; //draggable revert needs that
1362
//hack so receive/update callbacks work (mostly)
1363
inst.currentItem = inst.element;
1364
this.instance.fromOutside = inst;
1368
//Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
1369
if(this.instance.currentItem) this.instance._mouseDrag(event);
1373
//If it doesn't intersect with the sortable, and it intersected before,
1374
//we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1375
if(this.instance.isOver) {
1377
this.instance.isOver = 0;
1378
this.instance.cancelHelperRemoval = true;
1380
//Prevent reverting on this forced stop
1381
this.instance.options.revert = false;
1383
// The out event needs to be triggered independently
1384
this.instance._trigger('out', event, this.instance._uiHash(this.instance));
1386
this.instance._mouseStop(event, true);
1387
this.instance.options.helper = this.instance.options._helper;
1389
//Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1390
this.instance.currentItem.remove();
1391
if(this.instance.placeholder) this.instance.placeholder.remove();
1393
inst._trigger("fromSortable", event);
1394
inst.dropped = false; //draggable revert needs that
1404
$.ui.plugin.add("draggable", "cursor", {
1405
start: function(event, ui) {
1406
var t = $('body'), o = $(this).data('draggable').options;
1407
if (t.css("cursor")) o._cursor = t.css("cursor");
1408
t.css("cursor", o.cursor);
1410
stop: function(event, ui) {
1411
var o = $(this).data('draggable').options;
1412
if (o._cursor) $('body').css("cursor", o._cursor);
1416
$.ui.plugin.add("draggable", "opacity", {
1417
start: function(event, ui) {
1418
var t = $(ui.helper), o = $(this).data('draggable').options;
1419
if(t.css("opacity")) o._opacity = t.css("opacity");
1420
t.css('opacity', o.opacity);
1422
stop: function(event, ui) {
1423
var o = $(this).data('draggable').options;
1424
if(o._opacity) $(ui.helper).css('opacity', o._opacity);
1428
$.ui.plugin.add("draggable", "scroll", {
1429
start: function(event, ui) {
1430
var i = $(this).data("draggable");
1431
if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
1433
drag: function(event, ui) {
1435
var i = $(this).data("draggable"), o = i.options, scrolled = false;
1437
if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
1439
if(!o.axis || o.axis != 'x') {
1440
if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
1441
i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1442
else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
1443
i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1446
if(!o.axis || o.axis != 'y') {
1447
if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
1448
i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1449
else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
1450
i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1455
if(!o.axis || o.axis != 'x') {
1456
if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
1457
scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1458
else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
1459
scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1462
if(!o.axis || o.axis != 'y') {
1463
if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
1464
scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1465
else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
1466
scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1471
if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
1472
$.ui.ddmanager.prepareOffsets(i, event);
1477
$.ui.plugin.add("draggable", "snap", {
1478
start: function(event, ui) {
1480
var i = $(this).data("draggable"), o = i.options;
1481
i.snapElements = [];
1483
$(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
1484
var $t = $(this); var $o = $t.offset();
1485
if(this != i.element[0]) i.snapElements.push({
1487
width: $t.outerWidth(), height: $t.outerHeight(),
1488
top: $o.top, left: $o.left
1493
drag: function(event, ui) {
1495
var inst = $(this).data("draggable"), o = inst.options;
1496
var d = o.snapTolerance;
1498
var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1499
y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1501
for (var i = inst.snapElements.length - 1; i >= 0; i--){
1503
var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
1504
t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
1506
//Yes, I know, this is insane ;)
1507
if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {
1508
if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1509
inst.snapElements[i].snapping = false;
1513
if(o.snapMode != 'inner') {
1514
var ts = Math.abs(t - y2) <= d;
1515
var bs = Math.abs(b - y1) <= d;
1516
var ls = Math.abs(l - x2) <= d;
1517
var rs = Math.abs(r - x1) <= d;
1518
if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1519
if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1520
if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1521
if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1524
var first = (ts || bs || ls || rs);
1526
if(o.snapMode != 'outer') {
1527
var ts = Math.abs(t - y1) <= d;
1528
var bs = Math.abs(b - y2) <= d;
1529
var ls = Math.abs(l - x1) <= d;
1530
var rs = Math.abs(r - x2) <= d;
1531
if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1532
if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1533
if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1534
if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1537
if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
1538
(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1539
inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1546
$.ui.plugin.add("draggable", "stack", {
1547
start: function(event, ui) {
1549
var o = $(this).data("draggable").options;
1551
var group = $.makeArray($(o.stack)).sort(function(a,b) {
1552
return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1554
if (!group.length) { return; }
1556
var min = parseInt(group[0].style.zIndex) || 0;
1557
$(group).each(function(i) {
1558
this.style.zIndex = min + i;
1561
this[0].style.zIndex = min + group.length;
1566
$.ui.plugin.add("draggable", "zIndex", {
1567
start: function(event, ui) {
1568
var t = $(ui.helper), o = $(this).data("draggable").options;
1569
if(t.css("zIndex")) o._zIndex = t.css("zIndex");
1570
t.css('zIndex', o.zIndex);
1572
stop: function(event, ui) {
1573
var o = $(this).data("draggable").options;
1574
if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
1580
* jQuery UI Droppable 1.8.18
1582
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
1583
* Dual licensed under the MIT or GPL Version 2 licenses.
1584
* http://jquery.org/license
1586
* http://docs.jquery.com/UI/Droppables
1590
* jquery.ui.widget.js
1591
* jquery.ui.mouse.js
1592
* jquery.ui.draggable.js
1594
(function( $, undefined ) {
1596
$.widget("ui.droppable", {
1597
widgetEventPrefix: "drop",
1605
tolerance: 'intersect'
1607
_create: function() {
1609
var o = this.options, accept = o.accept;
1610
this.isover = 0; this.isout = 1;
1612
this.accept = $.isFunction(accept) ? accept : function(d) {
1613
return d.is(accept);
1616
//Store the droppable's proportions
1617
this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };
1619
// Add the reference and positions to the manager
1620
$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1621
$.ui.ddmanager.droppables[o.scope].push(this);
1623
(o.addClasses && this.element.addClass("ui-droppable"));
1627
destroy: function() {
1628
var drop = $.ui.ddmanager.droppables[this.options.scope];
1629
for ( var i = 0; i < drop.length; i++ )
1630
if ( drop[i] == this )
1634
.removeClass("ui-droppable ui-droppable-disabled")
1635
.removeData("droppable")
1636
.unbind(".droppable");
1641
_setOption: function(key, value) {
1643
if(key == 'accept') {
1644
this.accept = $.isFunction(value) ? value : function(d) {
1648
$.Widget.prototype._setOption.apply(this, arguments);
1651
_activate: function(event) {
1652
var draggable = $.ui.ddmanager.current;
1653
if(this.options.activeClass) this.element.addClass(this.options.activeClass);
1654
(draggable && this._trigger('activate', event, this.ui(draggable)));
1657
_deactivate: function(event) {
1658
var draggable = $.ui.ddmanager.current;
1659
if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1660
(draggable && this._trigger('deactivate', event, this.ui(draggable)));
1663
_over: function(event) {
1665
var draggable = $.ui.ddmanager.current;
1666
if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1668
if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1669
if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);
1670
this._trigger('over', event, this.ui(draggable));
1675
_out: function(event) {
1677
var draggable = $.ui.ddmanager.current;
1678
if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element
1680
if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1681
if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1682
this._trigger('out', event, this.ui(draggable));
1687
_drop: function(event,custom) {
1689
var draggable = custom || $.ui.ddmanager.current;
1690
if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element
1692
var childrenIntersection = false;
1693
this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
1694
var inst = $.data(this, 'droppable');
1697
&& !inst.options.disabled
1698
&& inst.options.scope == draggable.options.scope
1699
&& inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))
1700
&& $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
1701
) { childrenIntersection = true; return false; }
1703
if(childrenIntersection) return false;
1705
if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1706
if(this.options.activeClass) this.element.removeClass(this.options.activeClass);
1707
if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);
1708
this._trigger('drop', event, this.ui(draggable));
1709
return this.element;
1718
draggable: (c.currentItem || c.element),
1720
position: c.position,
1721
offset: c.positionAbs
1727
$.extend($.ui.droppable, {
1731
$.ui.intersect = function(draggable, droppable, toleranceMode) {
1733
if (!droppable.offset) return false;
1735
var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,
1736
y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;
1737
var l = droppable.offset.left, r = l + droppable.proportions.width,
1738
t = droppable.offset.top, b = t + droppable.proportions.height;
1740
switch (toleranceMode) {
1742
return (l <= x1 && x2 <= r
1743
&& t <= y1 && y2 <= b);
1746
return (l < x1 + (draggable.helperProportions.width / 2) // Right Half
1747
&& x2 - (draggable.helperProportions.width / 2) < r // Left Half
1748
&& t < y1 + (draggable.helperProportions.height / 2) // Bottom Half
1749
&& y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
1752
var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),
1753
draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),
1754
isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);
1759
(y1 >= t && y1 <= b) || // Top edge touching
1760
(y2 >= t && y2 <= b) || // Bottom edge touching
1761
(y1 < t && y2 > b) // Surrounded vertically
1763
(x1 >= l && x1 <= r) || // Left edge touching
1764
(x2 >= l && x2 <= r) || // Right edge touching
1765
(x1 < l && x2 > r) // Surrounded horizontally
1776
This manager tracks offsets of draggables and droppables
1780
droppables: { 'default': [] },
1781
prepareOffsets: function(t, event) {
1783
var m = $.ui.ddmanager.droppables[t.options.scope] || [];
1784
var type = event ? event.type : null; // workaround for #2317
1785
var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();
1787
droppablesLoop: for (var i = 0; i < m.length; i++) {
1789
if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted
1790
for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item
1791
m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
1793
if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
1795
m[i].offset = m[i].element.offset();
1796
m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
1801
drop: function(draggable, event) {
1803
var dropped = false;
1804
$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
1806
if(!this.options) return;
1807
if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))
1808
dropped = this._drop.call(this, event) || dropped;
1810
if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
1811
this.isout = 1; this.isover = 0;
1812
this._deactivate.call(this, event);
1819
dragStart: function( draggable, event ) {
1820
//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
1821
draggable.element.parents( ":not(body,html)" ).bind( "scroll.droppable", function() {
1822
if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
1825
drag: function(draggable, event) {
1827
//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
1828
if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);
1830
//Run through all droppables and check their positions based on specific tolerance options
1831
$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
1833
if(this.options.disabled || this.greedyChild || !this.visible) return;
1834
var intersects = $.ui.intersect(draggable, this, this.options.tolerance);
1836
var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);
1840
if (this.options.greedy) {
1841
var parent = this.element.parents(':data(droppable):eq(0)');
1842
if (parent.length) {
1843
parentInstance = $.data(parent[0], 'droppable');
1844
parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
1848
// we just moved into a greedy child
1849
if (parentInstance && c == 'isover') {
1850
parentInstance['isover'] = 0;
1851
parentInstance['isout'] = 1;
1852
parentInstance._out.call(parentInstance, event);
1855
this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;
1856
this[c == "isover" ? "_over" : "_out"].call(this, event);
1858
// we just moved out of a greedy child
1859
if (parentInstance && c == 'isout') {
1860
parentInstance['isout'] = 0;
1861
parentInstance['isover'] = 1;
1862
parentInstance._over.call(parentInstance, event);
1867
dragStop: function( draggable, event ) {
1868
draggable.element.parents( ":not(body,html)" ).unbind( "scroll.droppable" );
1869
//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
1870
if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
1876
* jQuery UI Resizable 1.8.18
1878
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
1879
* Dual licensed under the MIT or GPL Version 2 licenses.
1880
* http://jquery.org/license
1882
* http://docs.jquery.com/UI/Resizables
1886
* jquery.ui.mouse.js
1887
* jquery.ui.widget.js
1889
(function( $, undefined ) {
1891
$.widget("ui.resizable", $.ui.mouse, {
1892
widgetEventPrefix: "resize",
1896
animateDuration: "slow",
1897
animateEasing: "swing",
1911
_create: function() {
1913
var self = this, o = this.options;
1914
this.element.addClass("ui-resizable");
1917
_aspectRatio: !!(o.aspectRatio),
1918
aspectRatio: o.aspectRatio,
1919
originalElement: this.element,
1920
_proportionallyResizeElements: [],
1921
_helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
1924
//Wrap the element if it cannot hold child nodes
1925
if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
1927
//Create a wrapper element and set the wrapper to the new current internal element
1929
$('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
1930
position: this.element.css('position'),
1931
width: this.element.outerWidth(),
1932
height: this.element.outerHeight(),
1933
top: this.element.css('top'),
1934
left: this.element.css('left')
1938
//Overwrite the original this.element
1939
this.element = this.element.parent().data(
1940
"resizable", this.element.data('resizable')
1943
this.elementIsWrapper = true;
1945
//Move margins to the wrapper
1946
this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
1947
this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
1949
//Prevent Safari textarea resize
1950
this.originalResizeStyle = this.originalElement.css('resize');
1951
this.originalElement.css('resize', 'none');
1953
//Push the actual element to our proportionallyResize internal array
1954
this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
1956
// avoid IE jump (hard set the margin)
1957
this.originalElement.css({ margin: this.originalElement.css('margin') });
1959
// fix handlers offset
1960
this._proportionallyResize();
1964
this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' });
1965
if(this.handles.constructor == String) {
1967
if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
1968
var n = this.handles.split(","); this.handles = {};
1970
for(var i = 0; i < n.length; i++) {
1972
var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
1973
var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
1975
// increase zIndex of sw, se, ne, nw axis
1976
//TODO : this modifies original option
1977
if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
1979
//TODO : What's going on here?
1980
if ('se' == handle) {
1981
axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
1984
//Insert into internal handles object and append to element
1985
this.handles[handle] = '.ui-resizable-'+handle;
1986
this.element.append(axis);
1991
this._renderAxis = function(target) {
1993
target = target || this.element;
1995
for(var i in this.handles) {
1997
if(this.handles[i].constructor == String)
1998
this.handles[i] = $(this.handles[i], this.element).show();
2000
//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2001
if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2003
var axis = $(this.handles[i], this.element), padWrapper = 0;
2005
//Checking the correct pad and border
2006
padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2008
//The padding type i have to apply...
2009
var padPos = [ 'padding',
2010
/ne|nw|n/.test(i) ? 'Top' :
2011
/se|sw|s/.test(i) ? 'Bottom' :
2012
/^e$/.test(i) ? 'Right' : 'Left' ].join("");
2014
target.css(padPos, padWrapper);
2016
this._proportionallyResize();
2020
//TODO: What's that good for? There's not anything to be executed left
2021
if(!$(this.handles[i]).length)
2027
//TODO: make renderAxis a prototype function
2028
this._renderAxis(this.element);
2030
this._handles = $('.ui-resizable-handle', this.element)
2031
.disableSelection();
2033
//Matching axis name
2034
this._handles.mouseover(function() {
2035
if (!self.resizing) {
2037
var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2038
//Axis, default = se
2039
self.axis = axis && axis[1] ? axis[1] : 'se';
2043
//If we want to auto hide the elements
2045
this._handles.hide();
2047
.addClass("ui-resizable-autohide")
2049
if (o.disabled) return;
2050
$(this).removeClass("ui-resizable-autohide");
2051
self._handles.show();
2054
if (o.disabled) return;
2055
if (!self.resizing) {
2056
$(this).addClass("ui-resizable-autohide");
2057
self._handles.hide();
2062
//Initialize the mouse interaction
2067
destroy: function() {
2069
this._mouseDestroy();
2071
var _destroy = function(exp) {
2072
$(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2073
.removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
2076
//TODO: Unwrap at same DOM position
2077
if (this.elementIsWrapper) {
2078
_destroy(this.element);
2079
var wrapper = this.element;
2081
this.originalElement.css({
2082
position: wrapper.css('position'),
2083
width: wrapper.outerWidth(),
2084
height: wrapper.outerHeight(),
2085
top: wrapper.css('top'),
2086
left: wrapper.css('left')
2091
this.originalElement.css('resize', this.originalResizeStyle);
2092
_destroy(this.originalElement);
2097
_mouseCapture: function(event) {
2099
for (var i in this.handles) {
2100
if ($(this.handles[i])[0] == event.target) {
2105
return !this.options.disabled && handle;
2108
_mouseStart: function(event) {
2110
var o = this.options, iniPos = this.element.position(), el = this.element;
2112
this.resizing = true;
2113
this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
2115
// bugfix for http://dev.jquery.com/ticket/1749
2116
if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
2117
el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
2120
this._renderProxy();
2122
var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
2124
if (o.containment) {
2125
curleft += $(o.containment).scrollLeft() || 0;
2126
curtop += $(o.containment).scrollTop() || 0;
2129
//Store needed variables
2130
this.offset = this.helper.offset();
2131
this.position = { left: curleft, top: curtop };
2132
this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2133
this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2134
this.originalPosition = { left: curleft, top: curtop };
2135
this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2136
this.originalMousePosition = { left: event.pageX, top: event.pageY };
2139
this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2141
var cursor = $('.ui-resizable-' + this.axis).css('cursor');
2142
$('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
2144
el.addClass("ui-resizable-resizing");
2145
this._propagate("start", event);
2149
_mouseDrag: function(event) {
2151
//Increase performance, avoid regex
2152
var el = this.helper, o = this.options, props = {},
2153
self = this, smp = this.originalMousePosition, a = this.axis;
2155
var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
2156
var trigger = this._change[a];
2157
if (!trigger) return false;
2159
// Calculate the attrs that will be change
2160
var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
2162
// Put this in the mouseDrag handler since the user can start pressing shift while resizing
2163
this._updateVirtualBoundaries(event.shiftKey);
2164
if (this._aspectRatio || event.shiftKey)
2165
data = this._updateRatio(data, event);
2167
data = this._respectSize(data, event);
2169
// plugins callbacks need to be called first
2170
this._propagate("resize", event);
2173
top: this.position.top + "px", left: this.position.left + "px",
2174
width: this.size.width + "px", height: this.size.height + "px"
2177
if (!this._helper && this._proportionallyResizeElements.length)
2178
this._proportionallyResize();
2180
this._updateCache(data);
2182
// calling the user callback at the end
2183
this._trigger('resize', event, this.ui());
2188
_mouseStop: function(event) {
2190
this.resizing = false;
2191
var o = this.options, self = this;
2194
var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2195
soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2196
soffsetw = ista ? 0 : self.sizeDiff.width;
2198
var s = { width: (self.helper.width() - soffsetw), height: (self.helper.height() - soffseth) },
2199
left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2200
top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2203
this.element.css($.extend(s, { top: top, left: left }));
2205
self.helper.height(self.size.height);
2206
self.helper.width(self.size.width);
2208
if (this._helper && !o.animate) this._proportionallyResize();
2211
$('body').css('cursor', 'auto');
2213
this.element.removeClass("ui-resizable-resizing");
2215
this._propagate("stop", event);
2217
if (this._helper) this.helper.remove();
2222
_updateVirtualBoundaries: function(forceAspectRatio) {
2223
var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b;
2226
minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2227
maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2228
minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2229
maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2232
if(this._aspectRatio || forceAspectRatio) {
2233
// We want to create an enclosing box whose aspect ration is the requested one
2234
// First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2235
pMinWidth = b.minHeight * this.aspectRatio;
2236
pMinHeight = b.minWidth / this.aspectRatio;
2237
pMaxWidth = b.maxHeight * this.aspectRatio;
2238
pMaxHeight = b.maxWidth / this.aspectRatio;
2240
if(pMinWidth > b.minWidth) b.minWidth = pMinWidth;
2241
if(pMinHeight > b.minHeight) b.minHeight = pMinHeight;
2242
if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth;
2243
if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight;
2245
this._vBoundaries = b;
2248
_updateCache: function(data) {
2249
var o = this.options;
2250
this.offset = this.helper.offset();
2251
if (isNumber(data.left)) this.position.left = data.left;
2252
if (isNumber(data.top)) this.position.top = data.top;
2253
if (isNumber(data.height)) this.size.height = data.height;
2254
if (isNumber(data.width)) this.size.width = data.width;
2257
_updateRatio: function(data, event) {
2259
var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
2261
if (isNumber(data.height)) data.width = (data.height * this.aspectRatio);
2262
else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio);
2265
data.left = cpos.left + (csize.width - data.width);
2269
data.top = cpos.top + (csize.height - data.height);
2270
data.left = cpos.left + (csize.width - data.width);
2276
_respectSize: function(data, event) {
2278
var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
2279
ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2280
isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
2282
if (isminw) data.width = o.minWidth;
2283
if (isminh) data.height = o.minHeight;
2284
if (ismaxw) data.width = o.maxWidth;
2285
if (ismaxh) data.height = o.maxHeight;
2287
var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
2288
var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2290
if (isminw && cw) data.left = dw - o.minWidth;
2291
if (ismaxw && cw) data.left = dw - o.maxWidth;
2292
if (isminh && ch) data.top = dh - o.minHeight;
2293
if (ismaxh && ch) data.top = dh - o.maxHeight;
2295
// fixing jump error on top/left - bug #2330
2296
var isNotwh = !data.width && !data.height;
2297
if (isNotwh && !data.left && data.top) data.top = null;
2298
else if (isNotwh && !data.top && data.left) data.left = null;
2303
_proportionallyResize: function() {
2305
var o = this.options;
2306
if (!this._proportionallyResizeElements.length) return;
2307
var element = this.helper || this.element;
2309
for (var i=0; i < this._proportionallyResizeElements.length; i++) {
2311
var prel = this._proportionallyResizeElements[i];
2313
if (!this.borderDif) {
2314
var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
2315
p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
2317
this.borderDif = $.map(b, function(v, i) {
2318
var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
2319
return border + padding;
2323
if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
2327
height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2328
width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2335
_renderProxy: function() {
2337
var el = this.element, o = this.options;
2338
this.elementOffset = el.offset();
2342
this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
2344
// fix ie6 offset TODO: This seems broken
2345
var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
2346
pxyoffset = ( ie6 ? 2 : -1 );
2348
this.helper.addClass(this._helper).css({
2349
width: this.element.outerWidth() + pxyoffset,
2350
height: this.element.outerHeight() + pxyoffset,
2351
position: 'absolute',
2352
left: this.elementOffset.left - ie6offset +'px',
2353
top: this.elementOffset.top - ie6offset +'px',
2354
zIndex: ++o.zIndex //TODO: Don't modify option
2359
.disableSelection();
2362
this.helper = this.element;
2368
e: function(event, dx, dy) {
2369
return { width: this.originalSize.width + dx };
2371
w: function(event, dx, dy) {
2372
var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2373
return { left: sp.left + dx, width: cs.width - dx };
2375
n: function(event, dx, dy) {
2376
var o = this.options, cs = this.originalSize, sp = this.originalPosition;
2377
return { top: sp.top + dy, height: cs.height - dy };
2379
s: function(event, dx, dy) {
2380
return { height: this.originalSize.height + dy };
2382
se: function(event, dx, dy) {
2383
return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2385
sw: function(event, dx, dy) {
2386
return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2388
ne: function(event, dx, dy) {
2389
return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2391
nw: function(event, dx, dy) {
2392
return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2396
_propagate: function(n, event) {
2397
$.ui.plugin.call(this, n, [event, this.ui()]);
2398
(n != "resize" && this._trigger(n, event, this.ui()));
2405
originalElement: this.originalElement,
2406
element: this.element,
2407
helper: this.helper,
2408
position: this.position,
2410
originalSize: this.originalSize,
2411
originalPosition: this.originalPosition
2417
$.extend($.ui.resizable, {
2422
* Resizable Extensions
2425
$.ui.plugin.add("resizable", "alsoResize", {
2427
start: function (event, ui) {
2428
var self = $(this).data("resizable"), o = self.options;
2430
var _store = function (exp) {
2431
$(exp).each(function() {
2433
el.data("resizable-alsoresize", {
2434
width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
2435
left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10)
2440
if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
2441
if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
2442
else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
2444
_store(o.alsoResize);
2448
resize: function (event, ui) {
2449
var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
2452
height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
2453
top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
2456
_alsoResize = function (exp, c) {
2457
$(exp).each(function() {
2458
var el = $(this), start = $(this).data("resizable-alsoresize"), style = {},
2459
css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left'];
2461
$.each(css, function (i, prop) {
2462
var sum = (start[prop]||0) + (delta[prop]||0);
2463
if (sum && sum >= 0)
2464
style[prop] = sum || null;
2471
if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
2472
$.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
2474
_alsoResize(o.alsoResize);
2478
stop: function (event, ui) {
2479
$(this).removeData("resizable-alsoresize");
2483
$.ui.plugin.add("resizable", "animate", {
2485
stop: function(event, ui) {
2486
var self = $(this).data("resizable"), o = self.options;
2488
var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2489
soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
2490
soffsetw = ista ? 0 : self.sizeDiff.width;
2492
var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
2493
left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
2494
top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
2496
self.element.animate(
2497
$.extend(style, top && left ? { top: top, left: left } : {}), {
2498
duration: o.animateDuration,
2499
easing: o.animateEasing,
2503
width: parseInt(self.element.css('width'), 10),
2504
height: parseInt(self.element.css('height'), 10),
2505
top: parseInt(self.element.css('top'), 10),
2506
left: parseInt(self.element.css('left'), 10)
2509
if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
2511
// propagating resize, and updating values for each animation step
2512
self._updateCache(data);
2513
self._propagate("resize", event);
2522
$.ui.plugin.add("resizable", "containment", {
2524
start: function(event, ui) {
2525
var self = $(this).data("resizable"), o = self.options, el = self.element;
2526
var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2529
self.containerElement = $(ce);
2531
if (/document/.test(oc) || oc == document) {
2532
self.containerOffset = { left: 0, top: 0 };
2533
self.containerPosition = { left: 0, top: 0 };
2536
element: $(document), left: 0, top: 0,
2537
width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
2541
// i'm a node, so compute top, left, right, bottom
2543
var element = $(ce), p = [];
2544
$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
2546
self.containerOffset = element.offset();
2547
self.containerPosition = element.position();
2548
self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
2550
var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width,
2551
width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
2554
element: ce, left: co.left, top: co.top, width: width, height: height
2559
resize: function(event, ui) {
2560
var self = $(this).data("resizable"), o = self.options,
2561
ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
2562
pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
2564
if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
2566
if (cp.left < (self._helper ? co.left : 0)) {
2567
self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
2568
if (pRatio) self.size.height = self.size.width / o.aspectRatio;
2569
self.position.left = o.helper ? co.left : 0;
2572
if (cp.top < (self._helper ? co.top : 0)) {
2573
self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
2574
if (pRatio) self.size.width = self.size.height * o.aspectRatio;
2575
self.position.top = self._helper ? co.top : 0;
2578
self.offset.left = self.parentData.left+self.position.left;
2579
self.offset.top = self.parentData.top+self.position.top;
2581
var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
2582
hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
2584
var isParent = self.containerElement.get(0) == self.element.parent().get(0),
2585
isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
2587
if(isParent && isOffsetRelative) woset -= self.parentData.left;
2589
if (woset + self.size.width >= self.parentData.width) {
2590
self.size.width = self.parentData.width - woset;
2591
if (pRatio) self.size.height = self.size.width / self.aspectRatio;
2594
if (hoset + self.size.height >= self.parentData.height) {
2595
self.size.height = self.parentData.height - hoset;
2596
if (pRatio) self.size.width = self.size.height * self.aspectRatio;
2600
stop: function(event, ui){
2601
var self = $(this).data("resizable"), o = self.options, cp = self.position,
2602
co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
2604
var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
2606
if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
2607
$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2609
if (self._helper && !o.animate && (/static/).test(ce.css('position')))
2610
$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
2615
$.ui.plugin.add("resizable", "ghost", {
2617
start: function(event, ui) {
2619
var self = $(this).data("resizable"), o = self.options, cs = self.size;
2621
self.ghost = self.originalElement.clone();
2623
.css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
2624
.addClass('ui-resizable-ghost')
2625
.addClass(typeof o.ghost == 'string' ? o.ghost : '');
2627
self.ghost.appendTo(self.helper);
2631
resize: function(event, ui){
2632
var self = $(this).data("resizable"), o = self.options;
2633
if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
2636
stop: function(event, ui){
2637
var self = $(this).data("resizable"), o = self.options;
2638
if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
2643
$.ui.plugin.add("resizable", "grid", {
2645
resize: function(event, ui) {
2646
var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
2647
o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
2648
var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
2650
if (/^(se|s|e)$/.test(a)) {
2651
self.size.width = os.width + ox;
2652
self.size.height = os.height + oy;
2654
else if (/^(ne)$/.test(a)) {
2655
self.size.width = os.width + ox;
2656
self.size.height = os.height + oy;
2657
self.position.top = op.top - oy;
2659
else if (/^(sw)$/.test(a)) {
2660
self.size.width = os.width + ox;
2661
self.size.height = os.height + oy;
2662
self.position.left = op.left - ox;
2665
self.size.width = os.width + ox;
2666
self.size.height = os.height + oy;
2667
self.position.top = op.top - oy;
2668
self.position.left = op.left - ox;
2674
var num = function(v) {
2675
return parseInt(v, 10) || 0;
2678
var isNumber = function(value) {
2679
return !isNaN(parseInt(value, 10));
2684
* jQuery UI Selectable 1.8.18
2686
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
2687
* Dual licensed under the MIT or GPL Version 2 licenses.
2688
* http://jquery.org/license
2690
* http://docs.jquery.com/UI/Selectables
2694
* jquery.ui.mouse.js
2695
* jquery.ui.widget.js
2697
(function( $, undefined ) {
2699
$.widget("ui.selectable", $.ui.mouse, {
2707
_create: function() {
2710
this.element.addClass("ui-selectable");
2712
this.dragged = false;
2714
// cache selectee children based on filter
2716
this.refresh = function() {
2717
selectees = $(self.options.filter, self.element[0]);
2718
selectees.addClass("ui-selectee");
2719
selectees.each(function() {
2720
var $this = $(this);
2721
var pos = $this.offset();
2722
$.data(this, "selectable-item", {
2727
right: pos.left + $this.outerWidth(),
2728
bottom: pos.top + $this.outerHeight(),
2729
startselected: false,
2730
selected: $this.hasClass('ui-selected'),
2731
selecting: $this.hasClass('ui-selecting'),
2732
unselecting: $this.hasClass('ui-unselecting')
2738
this.selectees = selectees.addClass("ui-selectee");
2742
this.helper = $("<div class='ui-selectable-helper'></div>");
2745
destroy: function() {
2747
.removeClass("ui-selectee")
2748
.removeData("selectable-item");
2750
.removeClass("ui-selectable ui-selectable-disabled")
2751
.removeData("selectable")
2752
.unbind(".selectable");
2753
this._mouseDestroy();
2758
_mouseStart: function(event) {
2761
this.opos = [event.pageX, event.pageY];
2763
if (this.options.disabled)
2766
var options = this.options;
2768
this.selectees = $(options.filter, this.element[0]);
2770
this._trigger("start", event);
2772
$(options.appendTo).append(this.helper);
2773
// position helper (lasso)
2775
"left": event.clientX,
2776
"top": event.clientY,
2781
if (options.autoRefresh) {
2785
this.selectees.filter('.ui-selected').each(function() {
2786
var selectee = $.data(this, "selectable-item");
2787
selectee.startselected = true;
2788
if (!event.metaKey && !event.ctrlKey) {
2789
selectee.$element.removeClass('ui-selected');
2790
selectee.selected = false;
2791
selectee.$element.addClass('ui-unselecting');
2792
selectee.unselecting = true;
2793
// selectable UNSELECTING callback
2794
self._trigger("unselecting", event, {
2795
unselecting: selectee.element
2800
$(event.target).parents().andSelf().each(function() {
2801
var selectee = $.data(this, "selectable-item");
2803
var doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass('ui-selected');
2805
.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
2806
.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
2807
selectee.unselecting = !doSelect;
2808
selectee.selecting = doSelect;
2809
selectee.selected = doSelect;
2810
// selectable (UN)SELECTING callback
2812
self._trigger("selecting", event, {
2813
selecting: selectee.element
2816
self._trigger("unselecting", event, {
2817
unselecting: selectee.element
2826
_mouseDrag: function(event) {
2828
this.dragged = true;
2830
if (this.options.disabled)
2833
var options = this.options;
2835
var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
2836
if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
2837
if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
2838
this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
2840
this.selectees.each(function() {
2841
var selectee = $.data(this, "selectable-item");
2842
//prevent helper from being selected if appendTo: selectable
2843
if (!selectee || selectee.element == self.element[0])
2846
if (options.tolerance == 'touch') {
2847
hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
2848
} else if (options.tolerance == 'fit') {
2849
hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
2854
if (selectee.selected) {
2855
selectee.$element.removeClass('ui-selected');
2856
selectee.selected = false;
2858
if (selectee.unselecting) {
2859
selectee.$element.removeClass('ui-unselecting');
2860
selectee.unselecting = false;
2862
if (!selectee.selecting) {
2863
selectee.$element.addClass('ui-selecting');
2864
selectee.selecting = true;
2865
// selectable SELECTING callback
2866
self._trigger("selecting", event, {
2867
selecting: selectee.element
2872
if (selectee.selecting) {
2873
if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
2874
selectee.$element.removeClass('ui-selecting');
2875
selectee.selecting = false;
2876
selectee.$element.addClass('ui-selected');
2877
selectee.selected = true;
2879
selectee.$element.removeClass('ui-selecting');
2880
selectee.selecting = false;
2881
if (selectee.startselected) {
2882
selectee.$element.addClass('ui-unselecting');
2883
selectee.unselecting = true;
2885
// selectable UNSELECTING callback
2886
self._trigger("unselecting", event, {
2887
unselecting: selectee.element
2891
if (selectee.selected) {
2892
if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
2893
selectee.$element.removeClass('ui-selected');
2894
selectee.selected = false;
2896
selectee.$element.addClass('ui-unselecting');
2897
selectee.unselecting = true;
2898
// selectable UNSELECTING callback
2899
self._trigger("unselecting", event, {
2900
unselecting: selectee.element
2910
_mouseStop: function(event) {
2913
this.dragged = false;
2915
var options = this.options;
2917
$('.ui-unselecting', this.element[0]).each(function() {
2918
var selectee = $.data(this, "selectable-item");
2919
selectee.$element.removeClass('ui-unselecting');
2920
selectee.unselecting = false;
2921
selectee.startselected = false;
2922
self._trigger("unselected", event, {
2923
unselected: selectee.element
2926
$('.ui-selecting', this.element[0]).each(function() {
2927
var selectee = $.data(this, "selectable-item");
2928
selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
2929
selectee.selecting = false;
2930
selectee.selected = true;
2931
selectee.startselected = true;
2932
self._trigger("selected", event, {
2933
selected: selectee.element
2936
this._trigger("stop", event);
2938
this.helper.remove();
2945
$.extend($.ui.selectable, {
2951
* jQuery UI Sortable 1.8.18
2953
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
2954
* Dual licensed under the MIT or GPL Version 2 licenses.
2955
* http://jquery.org/license
2957
* http://docs.jquery.com/UI/Sortables
2961
* jquery.ui.mouse.js
2962
* jquery.ui.widget.js
2964
(function( $, undefined ) {
2966
$.widget("ui.sortable", $.ui.mouse, {
2967
widgetEventPrefix: "sort",
2977
forcePlaceholderSize: false,
2978
forceHelperSize: false,
2987
scrollSensitivity: 20,
2990
tolerance: "intersect",
2993
_create: function() {
2995
var o = this.options;
2996
this.containerCache = {};
2997
this.element.addClass("ui-sortable");
3002
//Let's determine if the items are being displayed horizontally
3003
this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false;
3005
//Let's determine the parent's offset
3006
this.offset = this.element.offset();
3008
//Initialize mouse events for interaction
3016
destroy: function() {
3017
$.Widget.prototype.destroy.call( this );
3019
.removeClass("ui-sortable ui-sortable-disabled");
3020
this._mouseDestroy();
3022
for ( var i = this.items.length - 1; i >= 0; i-- )
3023
this.items[i].item.removeData(this.widgetName + "-item");
3028
_setOption: function(key, value){
3029
if ( key === "disabled" ) {
3030
this.options[ key ] = value;
3033
[ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" );
3035
// Don't call widget base _setOption for disable as it adds ui-state-disabled class
3036
$.Widget.prototype._setOption.apply(this, arguments);
3040
_mouseCapture: function(event, overrideHandle) {
3043
if (this.reverting) {
3047
if(this.options.disabled || this.options.type == 'static') return false;
3049
//We have to refresh the items data once first
3050
this._refreshItems(event);
3052
//Find out if the clicked node (or one of its parents) is a actual item in this.items
3053
var currentItem = null, self = this, nodes = $(event.target).parents().each(function() {
3054
if($.data(this, that.widgetName + '-item') == self) {
3055
currentItem = $(this);
3059
if($.data(event.target, that.widgetName + '-item') == self) currentItem = $(event.target);
3061
if(!currentItem) return false;
3062
if(this.options.handle && !overrideHandle) {
3063
var validHandle = false;
3065
$(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; });
3066
if(!validHandle) return false;
3069
this.currentItem = currentItem;
3070
this._removeCurrentsFromItems();
3075
_mouseStart: function(event, overrideHandle, noActivation) {
3077
var o = this.options, self = this;
3078
this.currentContainer = this;
3080
//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3081
this.refreshPositions();
3083
//Create and append the visible helper
3084
this.helper = this._createHelper(event);
3086
//Cache the helper size
3087
this._cacheHelperProportions();
3090
* - Position generation -
3091
* This block generates everything position related - it's the core of draggables.
3094
//Cache the margins of the original element
3095
this._cacheMargins();
3097
//Get the next scrolling parent
3098
this.scrollParent = this.helper.scrollParent();
3100
//The element's absolute position on the page minus margins
3101
this.offset = this.currentItem.offset();
3103
top: this.offset.top - this.margins.top,
3104
left: this.offset.left - this.margins.left
3107
// Only after we got the offset, we can change the helper's position to absolute
3108
// TODO: Still need to figure out a way to make relative sorting possible
3109
this.helper.css("position", "absolute");
3110
this.cssPosition = this.helper.css("position");
3112
$.extend(this.offset, {
3113
click: { //Where the click happened, relative to the element
3114
left: event.pageX - this.offset.left,
3115
top: event.pageY - this.offset.top
3117
parent: this._getParentOffset(),
3118
relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3121
//Generate the original position
3122
this.originalPosition = this._generatePosition(event);
3123
this.originalPageX = event.pageX;
3124
this.originalPageY = event.pageY;
3126
//Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3127
(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3129
//Cache the former DOM position
3130
this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3132
//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
3133
if(this.helper[0] != this.currentItem[0]) {
3134
this.currentItem.hide();
3137
//Create the placeholder
3138
this._createPlaceholder();
3140
//Set a containment if given in the options
3142
this._setContainment();
3144
if(o.cursor) { // cursor option
3145
if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor");
3146
$('body').css("cursor", o.cursor);
3149
if(o.opacity) { // opacity option
3150
if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity");
3151
this.helper.css("opacity", o.opacity);
3154
if(o.zIndex) { // zIndex option
3155
if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex");
3156
this.helper.css("zIndex", o.zIndex);
3160
if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML')
3161
this.overflowOffset = this.scrollParent.offset();
3164
this._trigger("start", event, this._uiHash());
3166
//Recache the helper size
3167
if(!this._preserveHelperProportions)
3168
this._cacheHelperProportions();
3171
//Post 'activate' events to possible containers
3173
for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); }
3176
//Prepare possible droppables
3178
$.ui.ddmanager.current = this;
3180
if ($.ui.ddmanager && !o.dropBehaviour)
3181
$.ui.ddmanager.prepareOffsets(this, event);
3183
this.dragging = true;
3185
this.helper.addClass("ui-sortable-helper");
3186
this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3191
_mouseDrag: function(event) {
3193
//Compute the helpers position
3194
this.position = this._generatePosition(event);
3195
this.positionAbs = this._convertPositionTo("absolute");
3197
if (!this.lastPositionAbs) {
3198
this.lastPositionAbs = this.positionAbs;
3202
if(this.options.scroll) {
3203
var o = this.options, scrolled = false;
3204
if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
3206
if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
3207
this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3208
else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
3209
this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3211
if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
3212
this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3213
else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
3214
this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3218
if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
3219
scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3220
else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
3221
scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3223
if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
3224
scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3225
else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
3226
scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3230
if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
3231
$.ui.ddmanager.prepareOffsets(this, event);
3234
//Regenerate the absolute position used for position checks
3235
this.positionAbs = this._convertPositionTo("absolute");
3237
//Set the helper position
3238
if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
3239
if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
3242
for (var i = this.items.length - 1; i >= 0; i--) {
3244
//Cache variables and intersection, continue if no intersection
3245
var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
3246
if (!intersection) continue;
3248
if(itemElement != this.currentItem[0] //cannot intersect with itself
3249
&& this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
3250
&& !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
3251
&& (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
3252
//&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
3255
this.direction = intersection == 1 ? "down" : "up";
3257
if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
3258
this._rearrange(event, item);
3263
this._trigger("change", event, this._uiHash());
3268
//Post events to containers
3269
this._contactContainers(event);
3271
//Interconnect with droppables
3272
if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
3275
this._trigger('sort', event, this._uiHash());
3277
this.lastPositionAbs = this.positionAbs;
3282
_mouseStop: function(event, noPropagation) {
3286
//If we are using droppables, inform the manager about the drop
3287
if ($.ui.ddmanager && !this.options.dropBehaviour)
3288
$.ui.ddmanager.drop(this, event);
3290
if(this.options.revert) {
3292
var cur = self.placeholder.offset();
3294
self.reverting = true;
3296
$(this.helper).animate({
3297
left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft),
3298
top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop)
3299
}, parseInt(this.options.revert, 10) || 500, function() {
3303
this._clear(event, noPropagation);
3310
cancel: function() {
3316
this._mouseUp({ target: null });
3318
if(this.options.helper == "original")
3319
this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3321
this.currentItem.show();
3323
//Post deactivating events to containers
3324
for (var i = this.containers.length - 1; i >= 0; i--){
3325
this.containers[i]._trigger("deactivate", null, self._uiHash(this));
3326
if(this.containers[i].containerCache.over) {
3327
this.containers[i]._trigger("out", null, self._uiHash(this));
3328
this.containers[i].containerCache.over = 0;
3334
if (this.placeholder) {
3335
//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3336
if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3337
if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove();
3346
if(this.domPosition.prev) {
3347
$(this.domPosition.prev).after(this.currentItem);
3349
$(this.domPosition.parent).prepend(this.currentItem);
3357
serialize: function(o) {
3359
var items = this._getItemsAsjQuery(o && o.connected);
3360
var str = []; o = o || {};
3362
$(items).each(function() {
3363
var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
3364
if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2]));
3367
if(!str.length && o.key) {
3368
str.push(o.key + '=');
3371
return str.join('&');
3375
toArray: function(o) {
3377
var items = this._getItemsAsjQuery(o && o.connected);
3378
var ret = []; o = o || {};
3380
items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); });
3385
/* Be careful with the following core functions */
3386
_intersectsWith: function(item) {
3388
var x1 = this.positionAbs.left,
3389
x2 = x1 + this.helperProportions.width,
3390
y1 = this.positionAbs.top,
3391
y2 = y1 + this.helperProportions.height;
3396
b = t + item.height;
3398
var dyClick = this.offset.click.top,
3399
dxClick = this.offset.click.left;
3401
var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r;
3403
if( this.options.tolerance == "pointer"
3404
|| this.options.forcePointerForContainers
3405
|| (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height'])
3407
return isOverElement;
3410
return (l < x1 + (this.helperProportions.width / 2) // Right Half
3411
&& x2 - (this.helperProportions.width / 2) < r // Left Half
3412
&& t < y1 + (this.helperProportions.height / 2) // Bottom Half
3413
&& y2 - (this.helperProportions.height / 2) < b ); // Top Half
3418
_intersectsWithPointer: function(item) {
3420
var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
3421
isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
3422
isOverElement = isOverElementHeight && isOverElementWidth,
3423
verticalDirection = this._getDragVerticalDirection(),
3424
horizontalDirection = this._getDragHorizontalDirection();
3429
return this.floating ?
3430
( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 )
3431
: ( verticalDirection && (verticalDirection == "down" ? 2 : 1) );
3435
_intersectsWithSides: function(item) {
3437
var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
3438
isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
3439
verticalDirection = this._getDragVerticalDirection(),
3440
horizontalDirection = this._getDragHorizontalDirection();
3442
if (this.floating && horizontalDirection) {
3443
return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf));
3445
return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf));
3450
_getDragVerticalDirection: function() {
3451
var delta = this.positionAbs.top - this.lastPositionAbs.top;
3452
return delta != 0 && (delta > 0 ? "down" : "up");
3455
_getDragHorizontalDirection: function() {
3456
var delta = this.positionAbs.left - this.lastPositionAbs.left;
3457
return delta != 0 && (delta > 0 ? "right" : "left");
3460
refresh: function(event) {
3461
this._refreshItems(event);
3462
this.refreshPositions();
3466
_connectWith: function() {
3467
var options = this.options;
3468
return options.connectWith.constructor == String
3469
? [options.connectWith]
3470
: options.connectWith;
3473
_getItemsAsjQuery: function(connected) {
3478
var connectWith = this._connectWith();
3480
if(connectWith && connected) {
3481
for (var i = connectWith.length - 1; i >= 0; i--){
3482
var cur = $(connectWith[i]);
3483
for (var j = cur.length - 1; j >= 0; j--){
3484
var inst = $.data(cur[j], this.widgetName);
3485
if(inst && inst != this && !inst.options.disabled) {
3486
queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]);
3492
queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]);
3494
for (var i = queries.length - 1; i >= 0; i--){
3495
queries[i][0].each(function() {
3504
_removeCurrentsFromItems: function() {
3506
var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
3508
for (var i=0; i < this.items.length; i++) {
3510
for (var j=0; j < list.length; j++) {
3511
if(list[j] == this.items[i].item[0])
3512
this.items.splice(i,1);
3519
_refreshItems: function(event) {
3522
this.containers = [this];
3523
var items = this.items;
3525
var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]];
3526
var connectWith = this._connectWith();
3528
if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
3529
for (var i = connectWith.length - 1; i >= 0; i--){
3530
var cur = $(connectWith[i]);
3531
for (var j = cur.length - 1; j >= 0; j--){
3532
var inst = $.data(cur[j], this.widgetName);
3533
if(inst && inst != this && !inst.options.disabled) {
3534
queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
3535
this.containers.push(inst);
3541
for (var i = queries.length - 1; i >= 0; i--) {
3542
var targetData = queries[i][1];
3543
var _queries = queries[i][0];
3545
for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) {
3546
var item = $(_queries[j]);
3548
item.data(this.widgetName + '-item', targetData); // Data for target checking (mouse manager)
3552
instance: targetData,
3553
width: 0, height: 0,
3561
refreshPositions: function(fast) {
3563
//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
3564
if(this.offsetParent && this.helper) {
3565
this.offset.parent = this._getParentOffset();
3568
for (var i = this.items.length - 1; i >= 0; i--){
3569
var item = this.items[i];
3571
//We ignore calculating positions of all connected containers when we're not over them
3572
if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
3575
var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
3578
item.width = t.outerWidth();
3579
item.height = t.outerHeight();
3587
if(this.options.custom && this.options.custom.refreshContainers) {
3588
this.options.custom.refreshContainers.call(this);
3590
for (var i = this.containers.length - 1; i >= 0; i--){
3591
var p = this.containers[i].element.offset();
3592
this.containers[i].containerCache.left = p.left;
3593
this.containers[i].containerCache.top = p.top;
3594
this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
3595
this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
3602
_createPlaceholder: function(that) {
3604
var self = that || this, o = self.options;
3606
if(!o.placeholder || o.placeholder.constructor == String) {
3607
var className = o.placeholder;
3609
element: function() {
3611
var el = $(document.createElement(self.currentItem[0].nodeName))
3612
.addClass(className || self.currentItem[0].className+" ui-sortable-placeholder")
3613
.removeClass("ui-sortable-helper")[0];
3616
el.style.visibility = "hidden";
3620
update: function(container, p) {
3622
// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
3623
// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
3624
if(className && !o.forcePlaceholderSize) return;
3626
//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
3627
if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); };
3628
if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); };
3633
//Create the placeholder
3634
self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem));
3636
//Append it after the actual current item
3637
self.currentItem.after(self.placeholder);
3639
//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
3640
o.placeholder.update(self, self.placeholder);
3644
_contactContainers: function(event) {
3646
// get innermost container that intersects with item
3647
var innermostContainer = null, innermostIndex = null;
3650
for (var i = this.containers.length - 1; i >= 0; i--){
3652
// never consider a container that's located within the item itself
3653
if($.ui.contains(this.currentItem[0], this.containers[i].element[0]))
3656
if(this._intersectsWith(this.containers[i].containerCache)) {
3658
// if we've already found a container and it's more "inner" than this, then continue
3659
if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0]))
3662
innermostContainer = this.containers[i];
3666
// container doesn't intersect. trigger "out" event if necessary
3667
if(this.containers[i].containerCache.over) {
3668
this.containers[i]._trigger("out", event, this._uiHash(this));
3669
this.containers[i].containerCache.over = 0;
3675
// if no intersecting containers found, return
3676
if(!innermostContainer) return;
3678
// move the item into the container if it's not there already
3679
if(this.containers.length === 1) {
3680
this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3681
this.containers[innermostIndex].containerCache.over = 1;
3682
} else if(this.currentContainer != this.containers[innermostIndex]) {
3684
//When entering a new container, we will find the item with the least distance and append our item near it
3685
var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top'];
3686
for (var j = this.items.length - 1; j >= 0; j--) {
3687
if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue;
3688
var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top'];
3689
if(Math.abs(cur - base) < dist) {
3690
dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
3694
if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled
3697
this.currentContainer = this.containers[innermostIndex];
3698
itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
3699
this._trigger("change", event, this._uiHash());
3700
this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
3702
//Update the placeholder
3703
this.options.placeholder.update(this.currentContainer, this.placeholder);
3705
this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
3706
this.containers[innermostIndex].containerCache.over = 1;
3712
_createHelper: function(event) {
3714
var o = this.options;
3715
var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem);
3717
if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already
3718
$(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
3720
if(helper[0] == this.currentItem[0])
3721
this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
3723
if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width());
3724
if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height());
3730
_adjustOffsetFromHelper: function(obj) {
3731
if (typeof obj == 'string') {
3732
obj = obj.split(' ');
3734
if ($.isArray(obj)) {
3735
obj = {left: +obj[0], top: +obj[1] || 0};
3737
if ('left' in obj) {
3738
this.offset.click.left = obj.left + this.margins.left;
3740
if ('right' in obj) {
3741
this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
3744
this.offset.click.top = obj.top + this.margins.top;
3746
if ('bottom' in obj) {
3747
this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
3751
_getParentOffset: function() {
3754
//Get the offsetParent and cache its position
3755
this.offsetParent = this.helper.offsetParent();
3756
var po = this.offsetParent.offset();
3758
// This is a special case where we need to modify a offset calculated on start, since the following happened:
3759
// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
3760
// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
3761
// the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
3762
if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
3763
po.left += this.scrollParent.scrollLeft();
3764
po.top += this.scrollParent.scrollTop();
3767
if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
3768
|| (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
3769
po = { top: 0, left: 0 };
3772
top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
3773
left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
3778
_getRelativeOffset: function() {
3780
if(this.cssPosition == "relative") {
3781
var p = this.currentItem.position();
3783
top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
3784
left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
3787
return { top: 0, left: 0 };
3792
_cacheMargins: function() {
3794
left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
3795
top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
3799
_cacheHelperProportions: function() {
3800
this.helperProportions = {
3801
width: this.helper.outerWidth(),
3802
height: this.helper.outerHeight()
3806
_setContainment: function() {
3808
var o = this.options;
3809
if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
3810
if(o.containment == 'document' || o.containment == 'window') this.containment = [
3811
0 - this.offset.relative.left - this.offset.parent.left,
3812
0 - this.offset.relative.top - this.offset.parent.top,
3813
$(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
3814
($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
3817
if(!(/^(document|window|parent)$/).test(o.containment)) {
3818
var ce = $(o.containment)[0];
3819
var co = $(o.containment).offset();
3820
var over = ($(ce).css("overflow") != 'hidden');
3822
this.containment = [
3823
co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
3824
co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
3825
co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
3826
co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
3832
_convertPositionTo: function(d, pos) {
3834
if(!pos) pos = this.position;
3835
var mod = d == "absolute" ? 1 : -1;
3836
var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
3840
pos.top // The absolute mouse position
3841
+ this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
3842
+ this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
3843
- ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
3846
pos.left // The absolute mouse position
3847
+ this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
3848
+ this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
3849
- ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
3855
_generatePosition: function(event) {
3857
var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
3859
// This is another very weird special case that only happens for relative elements:
3860
// 1. If the css position is relative
3861
// 2. and the scroll parent is the document or similar to the offset parent
3862
// we have to refresh the relative offset during the scroll so there are no jumps
3863
if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
3864
this.offset.relative = this._getRelativeOffset();
3867
var pageX = event.pageX;
3868
var pageY = event.pageY;
3871
* - Position constraining -
3872
* Constrain the position to a mix of grid, containment.
3875
if(this.originalPosition) { //If we are not dragging yet, we won't check for options
3877
if(this.containment) {
3878
if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
3879
if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
3880
if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
3881
if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
3885
var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
3886
pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
3888
var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
3889
pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
3896
pageY // The absolute mouse position
3897
- this.offset.click.top // Click offset (relative to the element)
3898
- this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
3899
- this.offset.parent.top // The offsetParent's offset without borders (offset + border)
3900
+ ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
3903
pageX // The absolute mouse position
3904
- this.offset.click.left // Click offset (relative to the element)
3905
- this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
3906
- this.offset.parent.left // The offsetParent's offset without borders (offset + border)
3907
+ ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
3913
_rearrange: function(event, i, a, hardRefresh) {
3915
a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling));
3917
//Various things done here to improve the performance:
3918
// 1. we create a setTimeout, that calls refreshPositions
3919
// 2. on the instance, we have a counter variable, that get's higher after every append
3920
// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
3921
// 4. this lets only the last addition to the timeout stack through
3922
this.counter = this.counter ? ++this.counter : 1;
3923
var self = this, counter = this.counter;
3925
window.setTimeout(function() {
3926
if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
3931
_clear: function(event, noPropagation) {
3933
this.reverting = false;
3934
// We delay all events that have to be triggered to after the point where the placeholder has been removed and
3935
// everything else normalized again
3936
var delayedTriggers = [], self = this;
3938
// We first have to update the dom position of the actual currentItem
3939
// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
3940
if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem);
3941
this._noFinalSort = null;
3943
if(this.helper[0] == this.currentItem[0]) {
3944
for(var i in this._storedCSS) {
3945
if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = '';
3947
this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3949
this.currentItem.show();
3952
if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
3953
if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
3954
if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
3955
if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
3956
for (var i = this.containers.length - 1; i >= 0; i--){
3957
if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
3958
delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
3959
delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
3964
//Post events to containers
3965
for (var i = this.containers.length - 1; i >= 0; i--){
3966
if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
3967
if(this.containers[i].containerCache.over) {
3968
delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i]));
3969
this.containers[i].containerCache.over = 0;
3973
//Do what was originally in plugins
3974
if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor
3975
if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity
3976
if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index
3978
this.dragging = false;
3979
if(this.cancelHelperRemoval) {
3980
if(!noPropagation) {
3981
this._trigger("beforeStop", event, this._uiHash());
3982
for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
3983
this._trigger("stop", event, this._uiHash());
3988
if(!noPropagation) this._trigger("beforeStop", event, this._uiHash());
3990
//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3991
this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3993
if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null;
3995
if(!noPropagation) {
3996
for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events
3997
this._trigger("stop", event, this._uiHash());
4000
this.fromOutside = false;
4005
_trigger: function() {
4006
if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4011
_uiHash: function(inst) {
4012
var self = inst || this;
4014
helper: self.helper,
4015
placeholder: self.placeholder || $([]),
4016
position: self.position,
4017
originalPosition: self.originalPosition,
4018
offset: self.positionAbs,
4019
item: self.currentItem,
4020
sender: inst ? inst.element : null
4026
$.extend($.ui.sortable, {
4032
* jQuery UI Effects 1.8.18
4034
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4035
* Dual licensed under the MIT or GPL Version 2 licenses.
4036
* http://jquery.org/license
4038
* http://docs.jquery.com/UI/Effects/
4040
;jQuery.effects || (function($, undefined) {
4046
/******************************************************************************/
4047
/****************************** COLOR ANIMATIONS ******************************/
4048
/******************************************************************************/
4050
// override the animation for color styles
4051
$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
4052
'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
4054
$.fx.step[attr] = function(fx) {
4055
if (!fx.colorInit) {
4056
fx.start = getColor(fx.elem, attr);
4057
fx.end = getRGB(fx.end);
4058
fx.colorInit = true;
4061
fx.elem.style[attr] = 'rgb(' +
4062
Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
4063
Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
4064
Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
4068
// Color Conversion functions from highlightFade
4069
// By Blair Mitchelmore
4070
// http://jquery.offput.ca/highlightFade/
4072
// Parse strings looking for color tuples [255,255,255]
4073
function getRGB(color) {
4076
// Check if we're already dealing with an array of colors
4077
if ( color && color.constructor == Array && color.length == 3 )
4080
// Look for rgb(num,num,num)
4081
if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
4082
return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
4084
// Look for rgb(num%,num%,num%)
4085
if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
4086
return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
4089
if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
4090
return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
4093
if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
4094
return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
4096
// Look for rgba(0, 0, 0, 0) == transparent in Safari 3
4097
if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
4098
return colors['transparent'];
4100
// Otherwise, we're most likely dealing with a named color
4101
return colors[$.trim(color).toLowerCase()];
4104
function getColor(elem, attr) {
4108
color = $.curCSS(elem, attr);
4110
// Keep going until we find an element that has color, or we hit the body
4111
if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
4114
attr = "backgroundColor";
4115
} while ( elem = elem.parentNode );
4117
return getRGB(color);
4120
// Some named colors to work with
4121
// From Interface by Stefan Petre
4122
// http://interface.eyecon.ro/
4126
azure:[240,255,255],
4127
beige:[245,245,220],
4133
darkcyan:[0,139,139],
4134
darkgrey:[169,169,169],
4135
darkgreen:[0,100,0],
4136
darkkhaki:[189,183,107],
4137
darkmagenta:[139,0,139],
4138
darkolivegreen:[85,107,47],
4139
darkorange:[255,140,0],
4140
darkorchid:[153,50,204],
4142
darksalmon:[233,150,122],
4143
darkviolet:[148,0,211],
4144
fuchsia:[255,0,255],
4148
khaki:[240,230,140],
4149
lightblue:[173,216,230],
4150
lightcyan:[224,255,255],
4151
lightgreen:[144,238,144],
4152
lightgrey:[211,211,211],
4153
lightpink:[255,182,193],
4154
lightyellow:[255,255,224],
4156
magenta:[255,0,255],
4165
silver:[192,192,192],
4166
white:[255,255,255],
4168
transparent: [255,255,255]
4173
/******************************************************************************/
4174
/****************************** CLASS ANIMATIONS ******************************/
4175
/******************************************************************************/
4177
var classAnimationActions = ['add', 'remove', 'toggle'],
4190
function getElementStyles() {
4191
var style = document.defaultView
4192
? document.defaultView.getComputedStyle(this, null)
4193
: this.currentStyle,
4198
// webkit enumerates style porperties
4199
if (style && style.length && style[0] && style[style[0]]) {
4200
var len = style.length;
4203
if (typeof style[key] == 'string') {
4204
camelCase = key.replace(/\-(\w)/g, function(all, letter){
4205
return letter.toUpperCase();
4207
newStyle[camelCase] = style[key];
4211
for (key in style) {
4212
if (typeof style[key] === 'string') {
4213
newStyle[key] = style[key];
4221
function filterStyles(styles) {
4223
for (name in styles) {
4224
value = styles[name];
4226
// ignore null and undefined values
4228
// ignore functions (when does this occur?)
4229
$.isFunction(value) ||
4230
// shorthand styles that need to be expanded
4231
name in shorthandStyles ||
4232
// ignore scrollbars (break in IE)
4233
(/scrollbar/).test(name) ||
4235
// only colors or values that can be converted to numbers
4236
(!(/color/i).test(name) && isNaN(parseFloat(value)))
4238
delete styles[name];
4245
function styleDifference(oldStyle, newStyle) {
4246
var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
4249
for (name in newStyle) {
4250
if (oldStyle[name] != newStyle[name]) {
4251
diff[name] = newStyle[name];
4258
$.effects.animateClass = function(value, duration, easing, callback) {
4259
if ($.isFunction(easing)) {
4264
return this.queue(function() {
4266
originalStyleAttr = that.attr('style') || ' ',
4267
originalStyle = filterStyles(getElementStyles.call(this)),
4269
className = that.attr('class');
4271
$.each(classAnimationActions, function(i, action) {
4272
if (value[action]) {
4273
that[action + 'Class'](value[action]);
4276
newStyle = filterStyles(getElementStyles.call(this));
4277
that.attr('class', className);
4279
that.animate(styleDifference(originalStyle, newStyle), {
4283
complete: function() {
4284
$.each(classAnimationActions, function(i, action) {
4285
if (value[action]) { that[action + 'Class'](value[action]); }
4287
// work around bug in IE by clearing the cssText before setting it
4288
if (typeof that.attr('style') == 'object') {
4289
that.attr('style').cssText = '';
4290
that.attr('style').cssText = originalStyleAttr;
4292
that.attr('style', originalStyleAttr);
4294
if (callback) { callback.apply(this, arguments); }
4302
_addClass: $.fn.addClass,
4303
addClass: function(classNames, speed, easing, callback) {
4304
return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
4307
_removeClass: $.fn.removeClass,
4308
removeClass: function(classNames,speed,easing,callback) {
4309
return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
4312
_toggleClass: $.fn.toggleClass,
4313
toggleClass: function(classNames, force, speed, easing, callback) {
4314
if ( typeof force == "boolean" || force === undefined ) {
4316
// without speed parameter;
4317
return this._toggleClass(classNames, force);
4319
return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
4322
// without switch parameter;
4323
return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
4327
switchClass: function(remove,add,speed,easing,callback) {
4328
return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
4334
/******************************************************************************/
4335
/*********************************** EFFECTS **********************************/
4336
/******************************************************************************/
4338
$.extend($.effects, {
4341
// Saves a set of properties in a data storage
4342
save: function(element, set) {
4343
for(var i=0; i < set.length; i++) {
4344
if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
4348
// Restores a set of previously saved properties from a data storage
4349
restore: function(element, set) {
4350
for(var i=0; i < set.length; i++) {
4351
if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
4355
setMode: function(el, mode) {
4356
if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
4360
getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
4361
// this should be a little more flexible in the future to handle a string & hash
4363
switch (origin[0]) {
4364
case 'top': y = 0; break;
4365
case 'middle': y = 0.5; break;
4366
case 'bottom': y = 1; break;
4367
default: y = origin[0] / original.height;
4369
switch (origin[1]) {
4370
case 'left': x = 0; break;
4371
case 'center': x = 0.5; break;
4372
case 'right': x = 1; break;
4373
default: x = origin[1] / original.width;
4375
return {x: x, y: y};
4378
// Wraps the element around a wrapper that copies position properties
4379
createWrapper: function(element) {
4381
// if the element is already wrapped, return it
4382
if (element.parent().is('.ui-effects-wrapper')) {
4383
return element.parent();
4388
width: element.outerWidth(true),
4389
height: element.outerHeight(true),
4390
'float': element.css('float')
4392
wrapper = $('<div></div>')
4393
.addClass('ui-effects-wrapper')
4396
background: 'transparent',
4401
active = document.activeElement;
4403
element.wrap(wrapper);
4405
// Fixes #7595 - Elements lose focus when wrapped.
4406
if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
4407
$( active ).focus();
4410
wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
4412
// transfer positioning properties to the wrapper
4413
if (element.css('position') == 'static') {
4414
wrapper.css({ position: 'relative' });
4415
element.css({ position: 'relative' });
4418
position: element.css('position'),
4419
zIndex: element.css('z-index')
4421
$.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
4422
props[pos] = element.css(pos);
4423
if (isNaN(parseInt(props[pos], 10))) {
4424
props[pos] = 'auto';
4427
element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' });
4430
return wrapper.css(props).show();
4433
removeWrapper: function(element) {
4435
active = document.activeElement;
4437
if (element.parent().is('.ui-effects-wrapper')) {
4438
parent = element.parent().replaceWith(element);
4439
// Fixes #7595 - Elements lose focus when wrapped.
4440
if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
4441
$( active ).focus();
4449
setTransition: function(element, list, factor, value) {
4450
value = value || {};
4451
$.each(list, function(i, x){
4452
unit = element.cssUnit(x);
4453
if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
4460
function _normalizeArguments(effect, options, speed, callback) {
4461
// shift params for method overloading
4462
if (typeof effect == 'object') {
4466
effect = options.effect;
4468
if ($.isFunction(options)) {
4473
if (typeof options == 'number' || $.fx.speeds[options]) {
4478
if ($.isFunction(speed)) {
4483
options = options || {};
4485
speed = speed || options.duration;
4486
speed = $.fx.off ? 0 : typeof speed == 'number'
4487
? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default;
4489
callback = callback || options.complete;
4491
return [effect, options, speed, callback];
4494
function standardSpeed( speed ) {
4495
// valid standard speeds
4496
if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
4500
// invalid strings - treat as "normal" speed
4501
if ( typeof speed === "string" && !$.effects[ speed ] ) {
4509
effect: function(effect, options, speed, callback) {
4510
var args = _normalizeArguments.apply(this, arguments),
4511
// TODO: make effects take actual parameters instead of a hash
4517
mode = args2.options.mode,
4518
effectMethod = $.effects[effect];
4520
if ( $.fx.off || !effectMethod ) {
4521
// delegate to the original method (e.g., .show()) if possible
4523
return this[ mode ]( args2.duration, args2.callback );
4525
return this.each(function() {
4526
if ( args2.callback ) {
4527
args2.callback.call( this );
4533
return effectMethod.call(this, args2);
4537
show: function(speed) {
4538
if ( standardSpeed( speed ) ) {
4539
return this._show.apply(this, arguments);
4541
var args = _normalizeArguments.apply(this, arguments);
4542
args[1].mode = 'show';
4543
return this.effect.apply(this, args);
4548
hide: function(speed) {
4549
if ( standardSpeed( speed ) ) {
4550
return this._hide.apply(this, arguments);
4552
var args = _normalizeArguments.apply(this, arguments);
4553
args[1].mode = 'hide';
4554
return this.effect.apply(this, args);
4558
// jQuery core overloads toggle and creates _toggle
4559
__toggle: $.fn.toggle,
4560
toggle: function(speed) {
4561
if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
4562
return this.__toggle.apply(this, arguments);
4564
var args = _normalizeArguments.apply(this, arguments);
4565
args[1].mode = 'toggle';
4566
return this.effect.apply(this, args);
4571
cssUnit: function(key) {
4572
var style = this.css(key), val = [];
4573
$.each( ['em','px','%','pt'], function(i, unit){
4574
if(style.indexOf(unit) > 0)
4575
val = [parseFloat(style), unit];
4583
/******************************************************************************/
4584
/*********************************** EASING ***********************************/
4585
/******************************************************************************/
4588
* jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
4590
* Uses the built in easing capabilities added In jQuery 1.1
4591
* to offer multiple easing options
4593
* TERMS OF USE - jQuery Easing
4595
* Open source under the BSD License.
4597
* Copyright 2008 George McGinley Smith
4598
* All rights reserved.
4600
* Redistribution and use in source and binary forms, with or without modification,
4601
* are permitted provided that the following conditions are met:
4603
* Redistributions of source code must retain the above copyright notice, this list of
4604
* conditions and the following disclaimer.
4605
* Redistributions in binary form must reproduce the above copyright notice, this list
4606
* of conditions and the following disclaimer in the documentation and/or other materials
4607
* provided with the distribution.
4609
* Neither the name of the author nor the names of contributors may be used to endorse
4610
* or promote products derived from this software without specific prior written permission.
4612
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
4613
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
4614
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
4615
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
4616
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4617
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
4618
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4619
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4620
* OF THE POSSIBILITY OF SUCH DAMAGE.
4624
// t: current time, b: begInnIng value, c: change In value, d: duration
4625
$.easing.jswing = $.easing.swing;
4630
swing: function (x, t, b, c, d) {
4631
//alert($.easing.default);
4632
return $.easing[$.easing.def](x, t, b, c, d);
4634
easeInQuad: function (x, t, b, c, d) {
4635
return c*(t/=d)*t + b;
4637
easeOutQuad: function (x, t, b, c, d) {
4638
return -c *(t/=d)*(t-2) + b;
4640
easeInOutQuad: function (x, t, b, c, d) {
4641
if ((t/=d/2) < 1) return c/2*t*t + b;
4642
return -c/2 * ((--t)*(t-2) - 1) + b;
4644
easeInCubic: function (x, t, b, c, d) {
4645
return c*(t/=d)*t*t + b;
4647
easeOutCubic: function (x, t, b, c, d) {
4648
return c*((t=t/d-1)*t*t + 1) + b;
4650
easeInOutCubic: function (x, t, b, c, d) {
4651
if ((t/=d/2) < 1) return c/2*t*t*t + b;
4652
return c/2*((t-=2)*t*t + 2) + b;
4654
easeInQuart: function (x, t, b, c, d) {
4655
return c*(t/=d)*t*t*t + b;
4657
easeOutQuart: function (x, t, b, c, d) {
4658
return -c * ((t=t/d-1)*t*t*t - 1) + b;
4660
easeInOutQuart: function (x, t, b, c, d) {
4661
if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
4662
return -c/2 * ((t-=2)*t*t*t - 2) + b;
4664
easeInQuint: function (x, t, b, c, d) {
4665
return c*(t/=d)*t*t*t*t + b;
4667
easeOutQuint: function (x, t, b, c, d) {
4668
return c*((t=t/d-1)*t*t*t*t + 1) + b;
4670
easeInOutQuint: function (x, t, b, c, d) {
4671
if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
4672
return c/2*((t-=2)*t*t*t*t + 2) + b;
4674
easeInSine: function (x, t, b, c, d) {
4675
return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
4677
easeOutSine: function (x, t, b, c, d) {
4678
return c * Math.sin(t/d * (Math.PI/2)) + b;
4680
easeInOutSine: function (x, t, b, c, d) {
4681
return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
4683
easeInExpo: function (x, t, b, c, d) {
4684
return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
4686
easeOutExpo: function (x, t, b, c, d) {
4687
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
4689
easeInOutExpo: function (x, t, b, c, d) {
4691
if (t==d) return b+c;
4692
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
4693
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
4695
easeInCirc: function (x, t, b, c, d) {
4696
return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
4698
easeOutCirc: function (x, t, b, c, d) {
4699
return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
4701
easeInOutCirc: function (x, t, b, c, d) {
4702
if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
4703
return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
4705
easeInElastic: function (x, t, b, c, d) {
4706
var s=1.70158;var p=0;var a=c;
4707
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
4708
if (a < Math.abs(c)) { a=c; var s=p/4; }
4709
else var s = p/(2*Math.PI) * Math.asin (c/a);
4710
return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
4712
easeOutElastic: function (x, t, b, c, d) {
4713
var s=1.70158;var p=0;var a=c;
4714
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
4715
if (a < Math.abs(c)) { a=c; var s=p/4; }
4716
else var s = p/(2*Math.PI) * Math.asin (c/a);
4717
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
4719
easeInOutElastic: function (x, t, b, c, d) {
4720
var s=1.70158;var p=0;var a=c;
4721
if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
4722
if (a < Math.abs(c)) { a=c; var s=p/4; }
4723
else var s = p/(2*Math.PI) * Math.asin (c/a);
4724
if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
4725
return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
4727
easeInBack: function (x, t, b, c, d, s) {
4728
if (s == undefined) s = 1.70158;
4729
return c*(t/=d)*t*((s+1)*t - s) + b;
4731
easeOutBack: function (x, t, b, c, d, s) {
4732
if (s == undefined) s = 1.70158;
4733
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
4735
easeInOutBack: function (x, t, b, c, d, s) {
4736
if (s == undefined) s = 1.70158;
4737
if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
4738
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
4740
easeInBounce: function (x, t, b, c, d) {
4741
return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
4743
easeOutBounce: function (x, t, b, c, d) {
4744
if ((t/=d) < (1/2.75)) {
4745
return c*(7.5625*t*t) + b;
4746
} else if (t < (2/2.75)) {
4747
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
4748
} else if (t < (2.5/2.75)) {
4749
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
4751
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
4754
easeInOutBounce: function (x, t, b, c, d) {
4755
if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
4756
return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
4762
* TERMS OF USE - EASING EQUATIONS
4764
* Open source under the BSD License.
4766
* Copyright 2001 Robert Penner
4767
* All rights reserved.
4769
* Redistribution and use in source and binary forms, with or without modification,
4770
* are permitted provided that the following conditions are met:
4772
* Redistributions of source code must retain the above copyright notice, this list of
4773
* conditions and the following disclaimer.
4774
* Redistributions in binary form must reproduce the above copyright notice, this list
4775
* of conditions and the following disclaimer in the documentation and/or other materials
4776
* provided with the distribution.
4778
* Neither the name of the author nor the names of contributors may be used to endorse
4779
* or promote products derived from this software without specific prior written permission.
4781
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
4782
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
4783
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
4784
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
4785
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
4786
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
4787
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
4788
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4789
* OF THE POSSIBILITY OF SUCH DAMAGE.
4795
* jQuery UI Effects Blind 1.8.18
4797
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4798
* Dual licensed under the MIT or GPL Version 2 licenses.
4799
* http://jquery.org/license
4801
* http://docs.jquery.com/UI/Effects/Blind
4804
* jquery.effects.core.js
4806
(function( $, undefined ) {
4808
$.effects.blind = function(o) {
4810
return this.queue(function() {
4813
var el = $(this), props = ['position','top','bottom','left','right'];
4816
var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
4817
var direction = o.options.direction || 'vertical'; // Default direction
4820
$.effects.save(el, props); el.show(); // Save & Show
4821
var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
4822
var ref = (direction == 'vertical') ? 'height' : 'width';
4823
var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width();
4824
if(mode == 'show') wrapper.css(ref, 0); // Shift
4828
animation[ref] = mode == 'show' ? distance : 0;
4831
wrapper.animate(animation, o.duration, o.options.easing, function() {
4832
if(mode == 'hide') el.hide(); // Hide
4833
$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4834
if(o.callback) o.callback.apply(el[0], arguments); // Callback
4844
* jQuery UI Effects Bounce 1.8.18
4846
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4847
* Dual licensed under the MIT or GPL Version 2 licenses.
4848
* http://jquery.org/license
4850
* http://docs.jquery.com/UI/Effects/Bounce
4853
* jquery.effects.core.js
4855
(function( $, undefined ) {
4857
$.effects.bounce = function(o) {
4859
return this.queue(function() {
4862
var el = $(this), props = ['position','top','bottom','left','right'];
4865
var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
4866
var direction = o.options.direction || 'up'; // Default direction
4867
var distance = o.options.distance || 20; // Default distance
4868
var times = o.options.times || 5; // Default # of times
4869
var speed = o.duration || 250; // Default speed per bounce
4870
if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE
4873
$.effects.save(el, props); el.show(); // Save & Show
4874
$.effects.createWrapper(el); // Create Wrapper
4875
var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
4876
var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
4877
var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3);
4878
if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
4879
if (mode == 'hide') distance = distance / (times * 2);
4880
if (mode != 'hide') times--;
4883
if (mode == 'show') { // Show Bounce
4884
var animation = {opacity: 1};
4885
animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
4886
el.animate(animation, speed / 2, o.options.easing);
4887
distance = distance / 2;
4890
for (var i = 0; i < times; i++) { // Bounces
4891
var animation1 = {}, animation2 = {};
4892
animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
4893
animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
4894
el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing);
4895
distance = (mode == 'hide') ? distance * 2 : distance / 2;
4897
if (mode == 'hide') { // Last Bounce
4898
var animation = {opacity: 0};
4899
animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
4900
el.animate(animation, speed / 2, o.options.easing, function(){
4902
$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4903
if(o.callback) o.callback.apply(this, arguments); // Callback
4906
var animation1 = {}, animation2 = {};
4907
animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
4908
animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance;
4909
el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){
4910
$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4911
if(o.callback) o.callback.apply(this, arguments); // Callback
4914
el.queue('fx', function() { el.dequeue(); });
4922
* jQuery UI Effects Clip 1.8.18
4924
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4925
* Dual licensed under the MIT or GPL Version 2 licenses.
4926
* http://jquery.org/license
4928
* http://docs.jquery.com/UI/Effects/Clip
4931
* jquery.effects.core.js
4933
(function( $, undefined ) {
4935
$.effects.clip = function(o) {
4937
return this.queue(function() {
4940
var el = $(this), props = ['position','top','bottom','left','right','height','width'];
4943
var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
4944
var direction = o.options.direction || 'vertical'; // Default direction
4947
$.effects.save(el, props); el.show(); // Save & Show
4948
var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
4949
var animate = el[0].tagName == 'IMG' ? wrapper : el;
4951
size: (direction == 'vertical') ? 'height' : 'width',
4952
position: (direction == 'vertical') ? 'top' : 'left'
4954
var distance = (direction == 'vertical') ? animate.height() : animate.width();
4955
if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift
4959
animation[ref.size] = mode == 'show' ? distance : 0;
4960
animation[ref.position] = mode == 'show' ? 0 : distance / 2;
4963
animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
4964
if(mode == 'hide') el.hide(); // Hide
4965
$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
4966
if(o.callback) o.callback.apply(el[0], arguments); // Callback
4976
* jQuery UI Effects Drop 1.8.18
4978
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
4979
* Dual licensed under the MIT or GPL Version 2 licenses.
4980
* http://jquery.org/license
4982
* http://docs.jquery.com/UI/Effects/Drop
4985
* jquery.effects.core.js
4987
(function( $, undefined ) {
4989
$.effects.drop = function(o) {
4991
return this.queue(function() {
4994
var el = $(this), props = ['position','top','bottom','left','right','opacity'];
4997
var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
4998
var direction = o.options.direction || 'left'; // Default Direction
5001
$.effects.save(el, props); el.show(); // Save & Show
5002
$.effects.createWrapper(el); // Create Wrapper
5003
var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
5004
var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
5005
var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2);
5006
if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift
5009
var animation = {opacity: mode == 'show' ? 1 : 0};
5010
animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
5013
el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
5014
if(mode == 'hide') el.hide(); // Hide
5015
$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
5016
if(o.callback) o.callback.apply(this, arguments); // Callback
5026
* jQuery UI Effects Explode 1.8.18
5028
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5029
* Dual licensed under the MIT or GPL Version 2 licenses.
5030
* http://jquery.org/license
5032
* http://docs.jquery.com/UI/Effects/Explode
5035
* jquery.effects.core.js
5037
(function( $, undefined ) {
5039
$.effects.explode = function(o) {
5041
return this.queue(function() {
5043
var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
5044
var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3;
5046
o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode;
5047
var el = $(this).show().css('visibility', 'hidden');
5048
var offset = el.offset();
5050
//Substract the margins - not fixing the problem yet.
5051
offset.top -= parseInt(el.css("marginTop"),10) || 0;
5052
offset.left -= parseInt(el.css("marginLeft"),10) || 0;
5054
var width = el.outerWidth(true);
5055
var height = el.outerHeight(true);
5057
for(var i=0;i<rows;i++) { // =
5058
for(var j=0;j<cells;j++) { // ||
5062
.wrap('<div></div>')
5064
position: 'absolute',
5065
visibility: 'visible',
5066
left: -j*(width/cells),
5067
top: -i*(height/rows)
5070
.addClass('ui-effects-explode')
5072
position: 'absolute',
5075
height: height/rows,
5076
left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0),
5077
top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0),
5078
opacity: o.options.mode == 'show' ? 0 : 1
5080
left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)),
5081
top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)),
5082
opacity: o.options.mode == 'show' ? 1 : 0
5083
}, o.duration || 500);
5087
// Set a timeout, to call the callback approx. when the other animations have finished
5088
setTimeout(function() {
5090
o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide();
5091
if(o.callback) o.callback.apply(el[0]); // Callback
5094
$('div.ui-effects-explode').remove();
5096
}, o.duration || 500);
5105
* jQuery UI Effects Fade 1.8.18
5107
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5108
* Dual licensed under the MIT or GPL Version 2 licenses.
5109
* http://jquery.org/license
5111
* http://docs.jquery.com/UI/Effects/Fade
5114
* jquery.effects.core.js
5116
(function( $, undefined ) {
5118
$.effects.fade = function(o) {
5119
return this.queue(function() {
5121
mode = $.effects.setMode(elem, o.options.mode || 'hide');
5123
elem.animate({ opacity: mode }, {
5125
duration: o.duration,
5126
easing: o.options.easing,
5127
complete: function() {
5128
(o.callback && o.callback.apply(this, arguments));
5137
* jQuery UI Effects Fold 1.8.18
5139
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5140
* Dual licensed under the MIT or GPL Version 2 licenses.
5141
* http://jquery.org/license
5143
* http://docs.jquery.com/UI/Effects/Fold
5146
* jquery.effects.core.js
5148
(function( $, undefined ) {
5150
$.effects.fold = function(o) {
5152
return this.queue(function() {
5155
var el = $(this), props = ['position','top','bottom','left','right'];
5158
var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode
5159
var size = o.options.size || 15; // Default fold size
5160
var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value
5161
var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2;
5164
$.effects.save(el, props); el.show(); // Save & Show
5165
var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
5166
var widthFirst = ((mode == 'show') != horizFirst);
5167
var ref = widthFirst ? ['width', 'height'] : ['height', 'width'];
5168
var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()];
5169
var percent = /([0-9]+)%/.exec(size);
5170
if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1];
5171
if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift
5174
var animation1 = {}, animation2 = {};
5175
animation1[ref[0]] = mode == 'show' ? distance[0] : size;
5176
animation2[ref[1]] = mode == 'show' ? distance[1] : 0;
5179
wrapper.animate(animation1, duration, o.options.easing)
5180
.animate(animation2, duration, o.options.easing, function() {
5181
if(mode == 'hide') el.hide(); // Hide
5182
$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
5183
if(o.callback) o.callback.apply(el[0], arguments); // Callback
5193
* jQuery UI Effects Highlight 1.8.18
5195
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5196
* Dual licensed under the MIT or GPL Version 2 licenses.
5197
* http://jquery.org/license
5199
* http://docs.jquery.com/UI/Effects/Highlight
5202
* jquery.effects.core.js
5204
(function( $, undefined ) {
5206
$.effects.highlight = function(o) {
5207
return this.queue(function() {
5209
props = ['backgroundImage', 'backgroundColor', 'opacity'],
5210
mode = $.effects.setMode(elem, o.options.mode || 'show'),
5212
backgroundColor: elem.css('backgroundColor')
5215
if (mode == 'hide') {
5216
animation.opacity = 0;
5219
$.effects.save(elem, props);
5223
backgroundImage: 'none',
5224
backgroundColor: o.options.color || '#ffff99'
5226
.animate(animation, {
5228
duration: o.duration,
5229
easing: o.options.easing,
5230
complete: function() {
5231
(mode == 'hide' && elem.hide());
5232
$.effects.restore(elem, props);
5233
(mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
5234
(o.callback && o.callback.apply(this, arguments));
5243
* jQuery UI Effects Pulsate 1.8.18
5245
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5246
* Dual licensed under the MIT or GPL Version 2 licenses.
5247
* http://jquery.org/license
5249
* http://docs.jquery.com/UI/Effects/Pulsate
5252
* jquery.effects.core.js
5254
(function( $, undefined ) {
5256
$.effects.pulsate = function(o) {
5257
return this.queue(function() {
5259
mode = $.effects.setMode(elem, o.options.mode || 'show');
5260
times = ((o.options.times || 5) * 2) - 1;
5261
duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2,
5262
isVisible = elem.is(':visible'),
5266
elem.css('opacity', 0).show();
5270
if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) {
5274
for (var i = 0; i < times; i++) {
5275
elem.animate({ opacity: animateTo }, duration, o.options.easing);
5276
animateTo = (animateTo + 1) % 2;
5279
elem.animate({ opacity: animateTo }, duration, o.options.easing, function() {
5280
if (animateTo == 0) {
5283
(o.callback && o.callback.apply(this, arguments));
5287
.queue('fx', function() { elem.dequeue(); })
5294
* jQuery UI Effects Scale 1.8.18
5296
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5297
* Dual licensed under the MIT or GPL Version 2 licenses.
5298
* http://jquery.org/license
5300
* http://docs.jquery.com/UI/Effects/Scale
5303
* jquery.effects.core.js
5305
(function( $, undefined ) {
5307
$.effects.puff = function(o) {
5308
return this.queue(function() {
5310
mode = $.effects.setMode(elem, o.options.mode || 'hide'),
5311
percent = parseInt(o.options.percent, 10) || 150,
5312
factor = percent / 100,
5313
original = { height: elem.height(), width: elem.width() };
5315
$.extend(o.options, {
5318
percent: mode == 'hide' ? percent : 100,
5319
from: mode == 'hide'
5322
height: original.height * factor,
5323
width: original.width * factor
5327
elem.effect('scale', o.options, o.duration, o.callback);
5332
$.effects.scale = function(o) {
5334
return this.queue(function() {
5340
var options = $.extend(true, {}, o.options);
5341
var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
5342
var percent = parseInt(o.options.percent,10) || (parseInt(o.options.percent,10) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent
5343
var direction = o.options.direction || 'both'; // Set default axis
5344
var origin = o.options.origin; // The origin of the scaling
5345
if (mode != 'effect') { // Set default origin and restore for show/hide
5346
options.origin = origin || ['middle','center'];
5347
options.restore = true;
5349
var original = {height: el.height(), width: el.width()}; // Save original
5350
el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state
5353
var factor = { // Set scaling factor
5354
y: direction != 'horizontal' ? (percent / 100) : 1,
5355
x: direction != 'vertical' ? (percent / 100) : 1
5357
el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state
5359
if (o.options.fade) { // Fade option to support puff
5360
if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;};
5361
if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;};
5365
options.from = el.from; options.to = el.to; options.mode = mode;
5368
el.effect('size', options, o.duration, o.callback);
5374
$.effects.size = function(o) {
5376
return this.queue(function() {
5379
var el = $(this), props = ['position','top','bottom','left','right','width','height','overflow','opacity'];
5380
var props1 = ['position','top','bottom','left','right','overflow','opacity']; // Always restore
5381
var props2 = ['width','height','overflow']; // Copy for children
5382
var cProps = ['fontSize'];
5383
var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
5384
var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
5387
var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
5388
var restore = o.options.restore || false; // Default restore
5389
var scale = o.options.scale || 'both'; // Default scale mode
5390
var origin = o.options.origin; // The origin of the sizing
5391
var original = {height: el.height(), width: el.width()}; // Save original
5392
el.from = o.options.from || original; // Default from state
5393
el.to = o.options.to || original; // Default to state
5395
if (origin) { // Calculate baseline shifts
5396
var baseline = $.effects.getBaseline(origin, original);
5397
el.from.top = (original.height - el.from.height) * baseline.y;
5398
el.from.left = (original.width - el.from.width) * baseline.x;
5399
el.to.top = (original.height - el.to.height) * baseline.y;
5400
el.to.left = (original.width - el.to.width) * baseline.x;
5402
var factor = { // Set scaling factor
5403
from: {y: el.from.height / original.height, x: el.from.width / original.width},
5404
to: {y: el.to.height / original.height, x: el.to.width / original.width}
5406
if (scale == 'box' || scale == 'both') { // Scale the css box
5407
if (factor.from.y != factor.to.y) { // Vertical props scaling
5408
props = props.concat(vProps);
5409
el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from);
5410
el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to);
5412
if (factor.from.x != factor.to.x) { // Horizontal props scaling
5413
props = props.concat(hProps);
5414
el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from);
5415
el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to);
5418
if (scale == 'content' || scale == 'both') { // Scale the content
5419
if (factor.from.y != factor.to.y) { // Vertical props scaling
5420
props = props.concat(cProps);
5421
el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from);
5422
el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to);
5425
$.effects.save(el, restore ? props : props1); el.show(); // Save & Show
5426
$.effects.createWrapper(el); // Create Wrapper
5427
el.css('overflow','hidden').css(el.from); // Shift
5430
if (scale == 'content' || scale == 'both') { // Scale the children
5431
vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size
5432
hProps = hProps.concat(['marginLeft','marginRight']); // Add margins
5433
props2 = props.concat(vProps).concat(hProps); // Concat
5434
el.find("*[width]").each(function(){
5436
if (restore) $.effects.save(child, props2);
5437
var c_original = {height: child.height(), width: child.width()}; // Save original
5438
child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x};
5439
child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x};
5440
if (factor.from.y != factor.to.y) { // Vertical props scaling
5441
child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from);
5442
child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to);
5444
if (factor.from.x != factor.to.x) { // Horizontal props scaling
5445
child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from);
5446
child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to);
5448
child.css(child.from); // Shift children
5449
child.animate(child.to, o.duration, o.options.easing, function(){
5450
if (restore) $.effects.restore(child, props2); // Restore children
5451
}); // Animate children
5456
el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
5457
if (el.to.opacity === 0) {
5458
el.css('opacity', el.from.opacity);
5460
if(mode == 'hide') el.hide(); // Hide
5461
$.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore
5462
if(o.callback) o.callback.apply(this, arguments); // Callback
5472
* jQuery UI Effects Shake 1.8.18
5474
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5475
* Dual licensed under the MIT or GPL Version 2 licenses.
5476
* http://jquery.org/license
5478
* http://docs.jquery.com/UI/Effects/Shake
5481
* jquery.effects.core.js
5483
(function( $, undefined ) {
5485
$.effects.shake = function(o) {
5487
return this.queue(function() {
5490
var el = $(this), props = ['position','top','bottom','left','right'];
5493
var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode
5494
var direction = o.options.direction || 'left'; // Default direction
5495
var distance = o.options.distance || 20; // Default distance
5496
var times = o.options.times || 3; // Default # of times
5497
var speed = o.duration || o.options.duration || 140; // Default speed per shake
5500
$.effects.save(el, props); el.show(); // Save & Show
5501
$.effects.createWrapper(el); // Create Wrapper
5502
var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
5503
var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
5506
var animation = {}, animation1 = {}, animation2 = {};
5507
animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance;
5508
animation1[ref] = (motion == 'pos' ? '+=' : '-=') + distance * 2;
5509
animation2[ref] = (motion == 'pos' ? '-=' : '+=') + distance * 2;
5512
el.animate(animation, speed, o.options.easing);
5513
for (var i = 1; i < times; i++) { // Shakes
5514
el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing);
5516
el.animate(animation1, speed, o.options.easing).
5517
animate(animation, speed / 2, o.options.easing, function(){ // Last shake
5518
$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
5519
if(o.callback) o.callback.apply(this, arguments); // Callback
5521
el.queue('fx', function() { el.dequeue(); });
5529
* jQuery UI Effects Slide 1.8.18
5531
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5532
* Dual licensed under the MIT or GPL Version 2 licenses.
5533
* http://jquery.org/license
5535
* http://docs.jquery.com/UI/Effects/Slide
5538
* jquery.effects.core.js
5540
(function( $, undefined ) {
5542
$.effects.slide = function(o) {
5544
return this.queue(function() {
5547
var el = $(this), props = ['position','top','bottom','left','right'];
5550
var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode
5551
var direction = o.options.direction || 'left'; // Default Direction
5554
$.effects.save(el, props); el.show(); // Save & Show
5555
$.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper
5556
var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left';
5557
var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg';
5558
var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true}));
5559
if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift
5563
animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance;
5566
el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() {
5567
if(mode == 'hide') el.hide(); // Hide
5568
$.effects.restore(el, props); $.effects.removeWrapper(el); // Restore
5569
if(o.callback) o.callback.apply(this, arguments); // Callback
5579
* jQuery UI Effects Transfer 1.8.18
5581
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5582
* Dual licensed under the MIT or GPL Version 2 licenses.
5583
* http://jquery.org/license
5585
* http://docs.jquery.com/UI/Effects/Transfer
5588
* jquery.effects.core.js
5590
(function( $, undefined ) {
5592
$.effects.transfer = function(o) {
5593
return this.queue(function() {
5595
target = $(o.options.to),
5596
endPosition = target.offset(),
5598
top: endPosition.top,
5599
left: endPosition.left,
5600
height: target.innerHeight(),
5601
width: target.innerWidth()
5603
startPosition = elem.offset(),
5604
transfer = $('<div class="ui-effects-transfer"></div>')
5605
.appendTo(document.body)
5606
.addClass(o.options.className)
5608
top: startPosition.top,
5609
left: startPosition.left,
5610
height: elem.innerHeight(),
5611
width: elem.innerWidth(),
5612
position: 'absolute'
5614
.animate(animation, o.duration, o.options.easing, function() {
5616
(o.callback && o.callback.apply(elem[0], arguments));
5624
* jQuery UI Accordion 1.8.18
5626
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
5627
* Dual licensed under the MIT or GPL Version 2 licenses.
5628
* http://jquery.org/license
5630
* http://docs.jquery.com/UI/Accordion
5634
* jquery.ui.widget.js
5636
(function( $, undefined ) {
5638
$.widget( "ui.accordion", {
5647
header: "> li > :first-child,> :not(li):even",
5649
header: "ui-icon-triangle-1-e",
5650
headerSelected: "ui-icon-triangle-1-s"
5653
navigationFilter: function() {
5654
return this.href.toLowerCase() === location.href.toLowerCase();
5658
_create: function() {
5660
options = self.options;
5665
.addClass( "ui-accordion ui-widget ui-helper-reset" )
5666
// in lack of child-selectors in CSS
5667
// we need to mark top-LIs in a UL-accordion for some IE-fix
5669
.addClass( "ui-accordion-li-fix" );
5671
self.headers = self.element.find( options.header )
5672
.addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" )
5673
.bind( "mouseenter.accordion", function() {
5674
if ( options.disabled ) {
5677
$( this ).addClass( "ui-state-hover" );
5679
.bind( "mouseleave.accordion", function() {
5680
if ( options.disabled ) {
5683
$( this ).removeClass( "ui-state-hover" );
5685
.bind( "focus.accordion", function() {
5686
if ( options.disabled ) {
5689
$( this ).addClass( "ui-state-focus" );
5691
.bind( "blur.accordion", function() {
5692
if ( options.disabled ) {
5695
$( this ).removeClass( "ui-state-focus" );
5699
.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" );
5701
if ( options.navigation ) {
5702
var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 );
5703
if ( current.length ) {
5704
var header = current.closest( ".ui-accordion-header" );
5705
if ( header.length ) {
5706
// anchor within header
5707
self.active = header;
5709
// anchor within content
5710
self.active = current.closest( ".ui-accordion-content" ).prev();
5715
self.active = self._findActive( self.active || options.active )
5716
.addClass( "ui-state-default ui-state-active" )
5717
.toggleClass( "ui-corner-all" )
5718
.toggleClass( "ui-corner-top" );
5719
self.active.next().addClass( "ui-accordion-content-active" );
5721
self._createIcons();
5725
self.element.attr( "role", "tablist" );
5728
.attr( "role", "tab" )
5729
.bind( "keydown.accordion", function( event ) {
5730
return self._keydown( event );
5733
.attr( "role", "tabpanel" );
5736
.not( self.active || "" )
5738
"aria-expanded": "false",
5739
"aria-selected": "false",
5745
// make sure at least one header is in the tab order
5746
if ( !self.active.length ) {
5747
self.headers.eq( 0 ).attr( "tabIndex", 0 );
5751
"aria-expanded": "true",
5752
"aria-selected": "true",
5757
// only need links in tab order for Safari
5758
if ( !$.browser.safari ) {
5759
self.headers.find( "a" ).attr( "tabIndex", -1 );
5762
if ( options.event ) {
5763
self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) {
5764
self._clickHandler.call( self, event, this );
5765
event.preventDefault();
5770
_createIcons: function() {
5771
var options = this.options;
5772
if ( options.icons ) {
5773
$( "<span></span>" )
5774
.addClass( "ui-icon " + options.icons.header )
5775
.prependTo( this.headers );
5776
this.active.children( ".ui-icon" )
5777
.toggleClass(options.icons.header)
5778
.toggleClass(options.icons.headerSelected);
5779
this.element.addClass( "ui-accordion-icons" );
5783
_destroyIcons: function() {
5784
this.headers.children( ".ui-icon" ).remove();
5785
this.element.removeClass( "ui-accordion-icons" );
5788
destroy: function() {
5789
var options = this.options;
5792
.removeClass( "ui-accordion ui-widget ui-helper-reset" )
5793
.removeAttr( "role" );
5796
.unbind( ".accordion" )
5797
.removeClass( "ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
5798
.removeAttr( "role" )
5799
.removeAttr( "aria-expanded" )
5800
.removeAttr( "aria-selected" )
5801
.removeAttr( "tabIndex" );
5803
this.headers.find( "a" ).removeAttr( "tabIndex" );
5804
this._destroyIcons();
5805
var contents = this.headers.next()
5806
.css( "display", "" )
5807
.removeAttr( "role" )
5808
.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
5809
if ( options.autoHeight || options.fillHeight ) {
5810
contents.css( "height", "" );
5813
return $.Widget.prototype.destroy.call( this );
5816
_setOption: function( key, value ) {
5817
$.Widget.prototype._setOption.apply( this, arguments );
5819
if ( key == "active" ) {
5820
this.activate( value );
5822
if ( key == "icons" ) {
5823
this._destroyIcons();
5825
this._createIcons();
5828
// #5332 - opacity doesn't cascade to positioned elements in IE
5829
// so we need to add the disabled class to the headers and panels
5830
if ( key == "disabled" ) {
5831
this.headers.add(this.headers.next())
5832
[ value ? "addClass" : "removeClass" ](
5833
"ui-accordion-disabled ui-state-disabled" );
5837
_keydown: function( event ) {
5838
if ( this.options.disabled || event.altKey || event.ctrlKey ) {
5842
var keyCode = $.ui.keyCode,
5843
length = this.headers.length,
5844
currentIndex = this.headers.index( event.target ),
5847
switch ( event.keyCode ) {
5850
toFocus = this.headers[ ( currentIndex + 1 ) % length ];
5854
toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
5858
this._clickHandler( { target: event.target }, event.target );
5859
event.preventDefault();
5863
$( event.target ).attr( "tabIndex", -1 );
5864
$( toFocus ).attr( "tabIndex", 0 );
5872
resize: function() {
5873
var options = this.options,
5876
if ( options.fillSpace ) {
5877
if ( $.browser.msie ) {
5878
var defOverflow = this.element.parent().css( "overflow" );
5879
this.element.parent().css( "overflow", "hidden");
5881
maxHeight = this.element.parent().height();
5882
if ($.browser.msie) {
5883
this.element.parent().css( "overflow", defOverflow );
5886
this.headers.each(function() {
5887
maxHeight -= $( this ).outerHeight( true );
5892
$( this ).height( Math.max( 0, maxHeight -
5893
$( this ).innerHeight() + $( this ).height() ) );
5895
.css( "overflow", "auto" );
5896
} else if ( options.autoHeight ) {
5900
maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
5902
.height( maxHeight );
5908
activate: function( index ) {
5909
// TODO this gets called on init, changing the option without an explicit call for that
5910
this.options.active = index;
5911
// call clickHandler with custom event
5912
var active = this._findActive( index )[ 0 ];
5913
this._clickHandler( { target: active }, active );
5918
_findActive: function( selector ) {
5920
? typeof selector === "number"
5921
? this.headers.filter( ":eq(" + selector + ")" )
5922
: this.headers.not( this.headers.not( selector ) )
5923
: selector === false
5925
: this.headers.filter( ":eq(0)" );
5928
// TODO isn't event.target enough? why the separate target argument?
5929
_clickHandler: function( event, target ) {
5930
var options = this.options;
5931
if ( options.disabled ) {
5935
// called only when using activate(false) to close all parts programmatically
5936
if ( !event.target ) {
5937
if ( !options.collapsible ) {
5941
.removeClass( "ui-state-active ui-corner-top" )
5942
.addClass( "ui-state-default ui-corner-all" )
5943
.children( ".ui-icon" )
5944
.removeClass( options.icons.headerSelected )
5945
.addClass( options.icons.header );
5946
this.active.next().addClass( "ui-accordion-content-active" );
5947
var toHide = this.active.next(),
5951
oldHeader: options.active,
5952
newContent: $( [] ),
5955
toShow = ( this.active = $( [] ) );
5956
this._toggle( toShow, toHide, data );
5960
// get the click target
5961
var clicked = $( event.currentTarget || target ),
5962
clickedIsActive = clicked[0] === this.active[0];
5964
// TODO the option is changed, is that correct?
5965
// TODO if it is correct, shouldn't that happen after determining that the click is valid?
5966
options.active = options.collapsible && clickedIsActive ?
5968
this.headers.index( clicked );
5970
// if animations are still active, or the active header is the target, ignore click
5971
if ( this.running || ( !options.collapsible && clickedIsActive ) ) {
5975
// find elements to show and hide
5976
var active = this.active,
5977
toShow = clicked.next(),
5978
toHide = this.active.next(),
5981
newHeader: clickedIsActive && options.collapsible ? $([]) : clicked,
5982
oldHeader: this.active,
5983
newContent: clickedIsActive && options.collapsible ? $([]) : toShow,
5986
down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] );
5988
// when the call to ._toggle() comes after the class changes
5989
// it causes a very odd bug in IE 8 (see #6720)
5990
this.active = clickedIsActive ? $([]) : clicked;
5991
this._toggle( toShow, toHide, data, clickedIsActive, down );
5995
.removeClass( "ui-state-active ui-corner-top" )
5996
.addClass( "ui-state-default ui-corner-all" )
5997
.children( ".ui-icon" )
5998
.removeClass( options.icons.headerSelected )
5999
.addClass( options.icons.header );
6000
if ( !clickedIsActive ) {
6002
.removeClass( "ui-state-default ui-corner-all" )
6003
.addClass( "ui-state-active ui-corner-top" )
6004
.children( ".ui-icon" )
6005
.removeClass( options.icons.header )
6006
.addClass( options.icons.headerSelected );
6009
.addClass( "ui-accordion-content-active" );
6015
_toggle: function( toShow, toHide, data, clickedIsActive, down ) {
6017
options = self.options;
6019
self.toShow = toShow;
6020
self.toHide = toHide;
6023
var complete = function() {
6027
return self._completed.apply( self, arguments );
6030
// trigger changestart event
6031
self._trigger( "changestart", null, self.data );
6033
// count elements to animate
6034
self.running = toHide.size() === 0 ? toShow.size() : toHide.size();
6036
if ( options.animated ) {
6037
var animOptions = {};
6039
if ( options.collapsible && clickedIsActive ) {
6045
autoHeight: options.autoHeight || options.fillSpace
6053
autoHeight: options.autoHeight || options.fillSpace
6057
if ( !options.proxied ) {
6058
options.proxied = options.animated;
6061
if ( !options.proxiedDuration ) {
6062
options.proxiedDuration = options.duration;
6065
options.animated = $.isFunction( options.proxied ) ?
6066
options.proxied( animOptions ) :
6069
options.duration = $.isFunction( options.proxiedDuration ) ?
6070
options.proxiedDuration( animOptions ) :
6071
options.proxiedDuration;
6073
var animations = $.ui.accordion.animations,
6074
duration = options.duration,
6075
easing = options.animated;
6077
if ( easing && !animations[ easing ] && !$.easing[ easing ] ) {
6080
if ( !animations[ easing ] ) {
6081
animations[ easing ] = function( options ) {
6082
this.slide( options, {
6084
duration: duration || 700
6089
animations[ easing ]( animOptions );
6091
if ( options.collapsible && clickedIsActive ) {
6101
// TODO assert that the blur and focus triggers are really necessary, remove otherwise
6104
"aria-expanded": "false",
6105
"aria-selected": "false",
6111
"aria-expanded": "true",
6112
"aria-selected": "true",
6118
_completed: function( cancel ) {
6119
this.running = cancel ? 0 : --this.running;
6120
if ( this.running ) {
6124
if ( this.options.clearStyle ) {
6125
this.toShow.add( this.toHide ).css({
6131
// other classes are removed before the animation; this one needs to stay until completed
6132
this.toHide.removeClass( "ui-accordion-content-active" );
6133
// Work around for rendering bug in IE (#5421)
6134
if ( this.toHide.length ) {
6135
this.toHide.parent()[0].className = this.toHide.parent()[0].className;
6138
this._trigger( "change", null, this.data );
6142
$.extend( $.ui.accordion, {
6145
slide: function( options, additions ) {
6146
options = $.extend({
6149
}, options, additions );
6150
if ( !options.toHide.size() ) {
6151
options.toShow.animate({
6154
paddingBottom: "show"
6158
if ( !options.toShow.size() ) {
6159
options.toHide.animate({
6162
paddingBottom: "hide"
6166
var overflow = options.toShow.css( "overflow" ),
6170
fxAttrs = [ "height", "paddingTop", "paddingBottom" ],
6172
// fix width before calculating height of hidden element
6173
var s = options.toShow;
6174
originalWidth = s[0].style.width;
6175
s.width( s.parent().width()
6176
- parseFloat( s.css( "paddingLeft" ) )
6177
- parseFloat( s.css( "paddingRight" ) )
6178
- ( parseFloat( s.css( "borderLeftWidth" ) ) || 0 )
6179
- ( parseFloat( s.css( "borderRightWidth" ) ) || 0 ) );
6181
$.each( fxAttrs, function( i, prop ) {
6182
hideProps[ prop ] = "hide";
6184
var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ );
6185
showProps[ prop ] = {
6187
unit: parts[ 2 ] || "px"
6190
options.toShow.css({ height: 0, overflow: "hidden" }).show();
6192
.filter( ":hidden" )
6193
.each( options.complete )
6195
.filter( ":visible" )
6196
.animate( hideProps, {
6197
step: function( now, settings ) {
6198
// only calculate the percent when animating height
6199
// IE gets very inconsistent results when animating elements
6200
// with small values, which is common for padding
6201
if ( settings.prop == "height" ) {
6202
percentDone = ( settings.end - settings.start === 0 ) ? 0 :
6203
( settings.now - settings.start ) / ( settings.end - settings.start );
6206
options.toShow[ 0 ].style[ settings.prop ] =
6207
( percentDone * showProps[ settings.prop ].value )
6208
+ showProps[ settings.prop ].unit;
6210
duration: options.duration,
6211
easing: options.easing,
6212
complete: function() {
6213
if ( !options.autoHeight ) {
6214
options.toShow.css( "height", "" );
6216
options.toShow.css({
6217
width: originalWidth,
6224
bounceslide: function( options ) {
6225
this.slide( options, {
6226
easing: options.down ? "easeOutBounce" : "swing",
6227
duration: options.down ? 1000 : 200
6235
* jQuery UI Autocomplete 1.8.18
6237
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
6238
* Dual licensed under the MIT or GPL Version 2 licenses.
6239
* http://jquery.org/license
6241
* http://docs.jquery.com/UI/Autocomplete
6245
* jquery.ui.widget.js
6246
* jquery.ui.position.js
6248
(function( $, undefined ) {
6250
// used to prevent race conditions with remote data sources
6251
var requestIndex = 0;
6253
$.widget( "ui.autocomplete", {
6269
_create: function() {
6271
doc = this.element[ 0 ].ownerDocument,
6275
.addClass( "ui-autocomplete-input" )
6276
.attr( "autocomplete", "off" )
6277
// TODO verify these actually work as intended
6280
"aria-autocomplete": "list",
6281
"aria-haspopup": "true"
6283
.bind( "keydown.autocomplete", function( event ) {
6284
if ( self.options.disabled || self.element.propAttr( "readOnly" ) ) {
6288
suppressKeyPress = false;
6289
var keyCode = $.ui.keyCode;
6290
switch( event.keyCode ) {
6291
case keyCode.PAGE_UP:
6292
self._move( "previousPage", event );
6294
case keyCode.PAGE_DOWN:
6295
self._move( "nextPage", event );
6298
self._move( "previous", event );
6299
// prevent moving cursor to beginning of text field in some browsers
6300
event.preventDefault();
6303
self._move( "next", event );
6304
// prevent moving cursor to end of text field in some browsers
6305
event.preventDefault();
6308
case keyCode.NUMPAD_ENTER:
6309
// when menu is open and has focus
6310
if ( self.menu.active ) {
6311
// #6055 - Opera still allows the keypress to occur
6312
// which causes forms to submit
6313
suppressKeyPress = true;
6314
event.preventDefault();
6316
//passthrough - ENTER and TAB both select the current element
6318
if ( !self.menu.active ) {
6321
self.menu.select( event );
6323
case keyCode.ESCAPE:
6324
self.element.val( self.term );
6325
self.close( event );
6328
// keypress is triggered before the input value is changed
6329
clearTimeout( self.searching );
6330
self.searching = setTimeout(function() {
6331
// only search if the value has changed
6332
if ( self.term != self.element.val() ) {
6333
self.selectedItem = null;
6334
self.search( null, event );
6336
}, self.options.delay );
6340
.bind( "keypress.autocomplete", function( event ) {
6341
if ( suppressKeyPress ) {
6342
suppressKeyPress = false;
6343
event.preventDefault();
6346
.bind( "focus.autocomplete", function() {
6347
if ( self.options.disabled ) {
6351
self.selectedItem = null;
6352
self.previous = self.element.val();
6354
.bind( "blur.autocomplete", function( event ) {
6355
if ( self.options.disabled ) {
6359
clearTimeout( self.searching );
6360
// clicks on the menu (or a button to trigger a search) will cause a blur event
6361
self.closing = setTimeout(function() {
6362
self.close( event );
6363
self._change( event );
6367
this.response = function() {
6368
return self._response.apply( self, arguments );
6370
this.menu = $( "<ul></ul>" )
6371
.addClass( "ui-autocomplete" )
6372
.appendTo( $( this.options.appendTo || "body", doc )[0] )
6373
// prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
6374
.mousedown(function( event ) {
6375
// clicking on the scrollbar causes focus to shift to the body
6376
// but we can't detect a mouseup or a click immediately afterward
6377
// so we have to track the next mousedown and close the menu if
6378
// the user clicks somewhere outside of the autocomplete
6379
var menuElement = self.menu.element[ 0 ];
6380
if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6381
setTimeout(function() {
6382
$( document ).one( 'mousedown', function( event ) {
6383
if ( event.target !== self.element[ 0 ] &&
6384
event.target !== menuElement &&
6385
!$.ui.contains( menuElement, event.target ) ) {
6392
// use another timeout to make sure the blur-event-handler on the input was already triggered
6393
setTimeout(function() {
6394
clearTimeout( self.closing );
6398
focus: function( event, ui ) {
6399
var item = ui.item.data( "item.autocomplete" );
6400
if ( false !== self._trigger( "focus", event, { item: item } ) ) {
6401
// use value to match what will end up in the input, if it was a key event
6402
if ( /^key/.test(event.originalEvent.type) ) {
6403
self.element.val( item.value );
6407
selected: function( event, ui ) {
6408
var item = ui.item.data( "item.autocomplete" ),
6409
previous = self.previous;
6411
// only trigger when focus was lost (click on menu)
6412
if ( self.element[0] !== doc.activeElement ) {
6413
self.element.focus();
6414
self.previous = previous;
6415
// #6109 - IE triggers two focus events and the second
6416
// is asynchronous, so we need to reset the previous
6417
// term synchronously and asynchronously :-(
6418
setTimeout(function() {
6419
self.previous = previous;
6420
self.selectedItem = item;
6424
if ( false !== self._trigger( "select", event, { item: item } ) ) {
6425
self.element.val( item.value );
6427
// reset the term after the select event
6428
// this allows custom select handling to work properly
6429
self.term = self.element.val();
6431
self.close( event );
6432
self.selectedItem = item;
6434
blur: function( event, ui ) {
6435
// don't set the value of the text field if it's already correct
6436
// this prevents moving the cursor unnecessarily
6437
if ( self.menu.element.is(":visible") &&
6438
( self.element.val() !== self.term ) ) {
6439
self.element.val( self.term );
6443
.zIndex( this.element.zIndex() + 1 )
6444
// workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
6445
.css({ top: 0, left: 0 })
6448
if ( $.fn.bgiframe ) {
6449
this.menu.element.bgiframe();
6451
// turning off autocomplete prevents the browser from remembering the
6452
// value when navigating through history, so we re-enable autocomplete
6453
// if the page is unloaded before the widget is destroyed. #7790
6454
self.beforeunloadHandler = function() {
6455
self.element.removeAttr( "autocomplete" );
6457
$( window ).bind( "beforeunload", self.beforeunloadHandler );
6460
destroy: function() {
6462
.removeClass( "ui-autocomplete-input" )
6463
.removeAttr( "autocomplete" )
6464
.removeAttr( "role" )
6465
.removeAttr( "aria-autocomplete" )
6466
.removeAttr( "aria-haspopup" );
6467
this.menu.element.remove();
6468
$( window ).unbind( "beforeunload", this.beforeunloadHandler );
6469
$.Widget.prototype.destroy.call( this );
6472
_setOption: function( key, value ) {
6473
$.Widget.prototype._setOption.apply( this, arguments );
6474
if ( key === "source" ) {
6477
if ( key === "appendTo" ) {
6478
this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] )
6480
if ( key === "disabled" && value && this.xhr ) {
6485
_initSource: function() {
6489
if ( $.isArray(this.options.source) ) {
6490
array = this.options.source;
6491
this.source = function( request, response ) {
6492
response( $.ui.autocomplete.filter(array, request.term) );
6494
} else if ( typeof this.options.source === "string" ) {
6495
url = this.options.source;
6496
this.source = function( request, response ) {
6505
autocompleteRequest: ++requestIndex
6507
success: function( data, status ) {
6508
if ( this.autocompleteRequest === requestIndex ) {
6513
if ( this.autocompleteRequest === requestIndex ) {
6520
this.source = this.options.source;
6524
search: function( value, event ) {
6525
value = value != null ? value : this.element.val();
6527
// always save the actual value, not the one passed as an argument
6528
this.term = this.element.val();
6530
if ( value.length < this.options.minLength ) {
6531
return this.close( event );
6534
clearTimeout( this.closing );
6535
if ( this._trigger( "search", event ) === false ) {
6539
return this._search( value );
6542
_search: function( value ) {
6544
this.element.addClass( "ui-autocomplete-loading" );
6546
this.source( { term: value }, this.response );
6549
_response: function( content ) {
6550
if ( !this.options.disabled && content && content.length ) {
6551
content = this._normalize( content );
6552
this._suggest( content );
6553
this._trigger( "open" );
6558
if ( !this.pending ) {
6559
this.element.removeClass( "ui-autocomplete-loading" );
6563
close: function( event ) {
6564
clearTimeout( this.closing );
6565
if ( this.menu.element.is(":visible") ) {
6566
this.menu.element.hide();
6567
this.menu.deactivate();
6568
this._trigger( "close", event );
6572
_change: function( event ) {
6573
if ( this.previous !== this.element.val() ) {
6574
this._trigger( "change", event, { item: this.selectedItem } );
6578
_normalize: function( items ) {
6579
// assume all items have the right format when the first item is complete
6580
if ( items.length && items[0].label && items[0].value ) {
6583
return $.map( items, function(item) {
6584
if ( typeof item === "string" ) {
6591
label: item.label || item.value,
6592
value: item.value || item.label
6597
_suggest: function( items ) {
6598
var ul = this.menu.element
6600
.zIndex( this.element.zIndex() + 1 );
6601
this._renderMenu( ul, items );
6602
// TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
6603
this.menu.deactivate();
6604
this.menu.refresh();
6606
// size and position menu
6609
ul.position( $.extend({
6611
}, this.options.position ));
6613
if ( this.options.autoFocus ) {
6614
this.menu.next( new $.Event("mouseover") );
6618
_resizeMenu: function() {
6619
var ul = this.menu.element;
6620
ul.outerWidth( Math.max(
6621
// Firefox wraps long text (possibly a rounding bug)
6622
// so we add 1px to avoid the wrapping (#7513)
6623
ul.width( "" ).outerWidth() + 1,
6624
this.element.outerWidth()
6628
_renderMenu: function( ul, items ) {
6630
$.each( items, function( index, item ) {
6631
self._renderItem( ul, item );
6635
_renderItem: function( ul, item) {
6636
return $( "<li></li>" )
6637
.data( "item.autocomplete", item )
6638
.append( $( "<a></a>" ).text( item.label ) )
6642
_move: function( direction, event ) {
6643
if ( !this.menu.element.is(":visible") ) {
6644
this.search( null, event );
6647
if ( this.menu.first() && /^previous/.test(direction) ||
6648
this.menu.last() && /^next/.test(direction) ) {
6649
this.element.val( this.term );
6650
this.menu.deactivate();
6653
this.menu[ direction ]( event );
6656
widget: function() {
6657
return this.menu.element;
6661
$.extend( $.ui.autocomplete, {
6662
escapeRegex: function( value ) {
6663
return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
6665
filter: function(array, term) {
6666
var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
6667
return $.grep( array, function(value) {
6668
return matcher.test( value.label || value.value || value );
6676
* jQuery UI Menu (not officially released)
6678
* This widget isn't yet finished and the API is subject to change. We plan to finish
6679
* it for the next release. You're welcome to give it a try anyway and give us feedback,
6680
* as long as you're okay with migrating your code later on. We can help with that, too.
6682
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
6683
* Dual licensed under the MIT or GPL Version 2 licenses.
6684
* http://jquery.org/license
6686
* http://docs.jquery.com/UI/Menu
6690
* jquery.ui.widget.js
6694
$.widget("ui.menu", {
6695
_create: function() {
6698
.addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
6701
"aria-activedescendant": "ui-active-menuitem"
6703
.click(function( event ) {
6704
if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) {
6708
event.preventDefault();
6709
self.select( event );
6714
refresh: function() {
6717
// don't refresh list items that are already adapted
6718
var items = this.element.children("li:not(.ui-menu-item):has(a)")
6719
.addClass("ui-menu-item")
6720
.attr("role", "menuitem");
6723
.addClass("ui-corner-all")
6724
.attr("tabindex", -1)
6725
// mouseenter doesn't work with event delegation
6726
.mouseenter(function( event ) {
6727
self.activate( event, $(this).parent() );
6729
.mouseleave(function() {
6734
activate: function( event, item ) {
6736
if (this.hasScroll()) {
6737
var offset = item.offset().top - this.element.offset().top,
6738
scroll = this.element.scrollTop(),
6739
elementHeight = this.element.height();
6741
this.element.scrollTop( scroll + offset);
6742
} else if (offset >= elementHeight) {
6743
this.element.scrollTop( scroll + offset - elementHeight + item.height());
6746
this.active = item.eq(0)
6748
.addClass("ui-state-hover")
6749
.attr("id", "ui-active-menuitem")
6751
this._trigger("focus", event, { item: item });
6754
deactivate: function() {
6755
if (!this.active) { return; }
6757
this.active.children("a")
6758
.removeClass("ui-state-hover")
6760
this._trigger("blur");
6764
next: function(event) {
6765
this.move("next", ".ui-menu-item:first", event);
6768
previous: function(event) {
6769
this.move("prev", ".ui-menu-item:last", event);
6773
return this.active && !this.active.prevAll(".ui-menu-item").length;
6777
return this.active && !this.active.nextAll(".ui-menu-item").length;
6780
move: function(direction, edge, event) {
6782
this.activate(event, this.element.children(edge));
6785
var next = this.active[direction + "All"](".ui-menu-item").eq(0);
6787
this.activate(event, next);
6789
this.activate(event, this.element.children(edge));
6793
// TODO merge with previousPage
6794
nextPage: function(event) {
6795
if (this.hasScroll()) {
6796
// TODO merge with no-scroll-else
6797
if (!this.active || this.last()) {
6798
this.activate(event, this.element.children(".ui-menu-item:first"));
6801
var base = this.active.offset().top,
6802
height = this.element.height(),
6803
result = this.element.children(".ui-menu-item").filter(function() {
6804
var close = $(this).offset().top - base - height + $(this).height();
6805
// TODO improve approximation
6806
return close < 10 && close > -10;
6809
// TODO try to catch this earlier when scrollTop indicates the last page anyway
6810
if (!result.length) {
6811
result = this.element.children(".ui-menu-item:last");
6813
this.activate(event, result);
6815
this.activate(event, this.element.children(".ui-menu-item")
6816
.filter(!this.active || this.last() ? ":first" : ":last"));
6820
// TODO merge with nextPage
6821
previousPage: function(event) {
6822
if (this.hasScroll()) {
6823
// TODO merge with no-scroll-else
6824
if (!this.active || this.first()) {
6825
this.activate(event, this.element.children(".ui-menu-item:last"));
6829
var base = this.active.offset().top,
6830
height = this.element.height();
6831
result = this.element.children(".ui-menu-item").filter(function() {
6832
var close = $(this).offset().top - base + height - $(this).height();
6833
// TODO improve approximation
6834
return close < 10 && close > -10;
6837
// TODO try to catch this earlier when scrollTop indicates the last page anyway
6838
if (!result.length) {
6839
result = this.element.children(".ui-menu-item:first");
6841
this.activate(event, result);
6843
this.activate(event, this.element.children(".ui-menu-item")
6844
.filter(!this.active || this.first() ? ":last" : ":first"));
6848
hasScroll: function() {
6849
return this.element.height() < this.element[ $.fn.prop ? "prop" : "attr" ]("scrollHeight");
6852
select: function( event ) {
6853
this._trigger("selected", event, { item: this.active });
6859
* jQuery UI Button 1.8.18
6861
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
6862
* Dual licensed under the MIT or GPL Version 2 licenses.
6863
* http://jquery.org/license
6865
* http://docs.jquery.com/UI/Button
6869
* jquery.ui.widget.js
6871
(function( $, undefined ) {
6873
var lastActive, startXPos, startYPos, clickDragged,
6874
baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
6875
stateClasses = "ui-state-hover ui-state-active ",
6876
typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
6877
formResetHandler = function() {
6878
var buttons = $( this ).find( ":ui-button" );
6879
setTimeout(function() {
6880
buttons.button( "refresh" );
6883
radioGroup = function( radio ) {
6884
var name = radio.name,
6889
radios = $( form ).find( "[name='" + name + "']" );
6891
radios = $( "[name='" + name + "']", radio.ownerDocument )
6892
.filter(function() {
6900
$.widget( "ui.button", {
6910
_create: function() {
6911
this.element.closest( "form" )
6912
.unbind( "reset.button" )
6913
.bind( "reset.button", formResetHandler );
6915
if ( typeof this.options.disabled !== "boolean" ) {
6916
this.options.disabled = !!this.element.propAttr( "disabled" );
6918
this.element.propAttr( "disabled", this.options.disabled );
6921
this._determineButtonType();
6922
this.hasTitle = !!this.buttonElement.attr( "title" );
6925
options = this.options,
6926
toggleButton = this.type === "checkbox" || this.type === "radio",
6927
hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
6928
focusClass = "ui-state-focus";
6930
if ( options.label === null ) {
6931
options.label = this.buttonElement.html();
6935
.addClass( baseClasses )
6936
.attr( "role", "button" )
6937
.bind( "mouseenter.button", function() {
6938
if ( options.disabled ) {
6941
$( this ).addClass( "ui-state-hover" );
6942
if ( this === lastActive ) {
6943
$( this ).addClass( "ui-state-active" );
6946
.bind( "mouseleave.button", function() {
6947
if ( options.disabled ) {
6950
$( this ).removeClass( hoverClass );
6952
.bind( "click.button", function( event ) {
6953
if ( options.disabled ) {
6954
event.preventDefault();
6955
event.stopImmediatePropagation();
6960
.bind( "focus.button", function() {
6961
// no need to check disabled, focus won't be triggered anyway
6962
self.buttonElement.addClass( focusClass );
6964
.bind( "blur.button", function() {
6965
self.buttonElement.removeClass( focusClass );
6968
if ( toggleButton ) {
6969
this.element.bind( "change.button", function() {
6970
if ( clickDragged ) {
6975
// if mouse moves between mousedown and mouseup (drag) set clickDragged flag
6976
// prevents issue where button state changes but checkbox/radio checked state
6977
// does not in Firefox (see ticket #6970)
6979
.bind( "mousedown.button", function( event ) {
6980
if ( options.disabled ) {
6983
clickDragged = false;
6984
startXPos = event.pageX;
6985
startYPos = event.pageY;
6987
.bind( "mouseup.button", function( event ) {
6988
if ( options.disabled ) {
6991
if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
6992
clickDragged = true;
6997
if ( this.type === "checkbox" ) {
6998
this.buttonElement.bind( "click.button", function() {
6999
if ( options.disabled || clickDragged ) {
7002
$( this ).toggleClass( "ui-state-active" );
7003
self.buttonElement.attr( "aria-pressed", self.element[0].checked );
7005
} else if ( this.type === "radio" ) {
7006
this.buttonElement.bind( "click.button", function() {
7007
if ( options.disabled || clickDragged ) {
7010
$( this ).addClass( "ui-state-active" );
7011
self.buttonElement.attr( "aria-pressed", "true" );
7013
var radio = self.element[ 0 ];
7017
return $( this ).button( "widget" )[ 0 ];
7019
.removeClass( "ui-state-active" )
7020
.attr( "aria-pressed", "false" );
7024
.bind( "mousedown.button", function() {
7025
if ( options.disabled ) {
7028
$( this ).addClass( "ui-state-active" );
7030
$( document ).one( "mouseup", function() {
7034
.bind( "mouseup.button", function() {
7035
if ( options.disabled ) {
7038
$( this ).removeClass( "ui-state-active" );
7040
.bind( "keydown.button", function(event) {
7041
if ( options.disabled ) {
7044
if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
7045
$( this ).addClass( "ui-state-active" );
7048
.bind( "keyup.button", function() {
7049
$( this ).removeClass( "ui-state-active" );
7052
if ( this.buttonElement.is("a") ) {
7053
this.buttonElement.keyup(function(event) {
7054
if ( event.keyCode === $.ui.keyCode.SPACE ) {
7055
// TODO pass through original event correctly (just as 2nd argument doesn't work)
7062
// TODO: pull out $.Widget's handling for the disabled option into
7063
// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
7064
// be overridden by individual plugins
7065
this._setOption( "disabled", options.disabled );
7066
this._resetButton();
7069
_determineButtonType: function() {
7071
if ( this.element.is(":checkbox") ) {
7072
this.type = "checkbox";
7073
} else if ( this.element.is(":radio") ) {
7074
this.type = "radio";
7075
} else if ( this.element.is("input") ) {
7076
this.type = "input";
7078
this.type = "button";
7081
if ( this.type === "checkbox" || this.type === "radio" ) {
7082
// we don't search against the document in case the element
7083
// is disconnected from the DOM
7084
var ancestor = this.element.parents().filter(":last"),
7085
labelSelector = "label[for='" + this.element.attr("id") + "']";
7086
this.buttonElement = ancestor.find( labelSelector );
7087
if ( !this.buttonElement.length ) {
7088
ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7089
this.buttonElement = ancestor.filter( labelSelector );
7090
if ( !this.buttonElement.length ) {
7091
this.buttonElement = ancestor.find( labelSelector );
7094
this.element.addClass( "ui-helper-hidden-accessible" );
7096
var checked = this.element.is( ":checked" );
7098
this.buttonElement.addClass( "ui-state-active" );
7100
this.buttonElement.attr( "aria-pressed", checked );
7102
this.buttonElement = this.element;
7106
widget: function() {
7107
return this.buttonElement;
7110
destroy: function() {
7112
.removeClass( "ui-helper-hidden-accessible" );
7114
.removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
7115
.removeAttr( "role" )
7116
.removeAttr( "aria-pressed" )
7117
.html( this.buttonElement.find(".ui-button-text").html() );
7119
if ( !this.hasTitle ) {
7120
this.buttonElement.removeAttr( "title" );
7123
$.Widget.prototype.destroy.call( this );
7126
_setOption: function( key, value ) {
7127
$.Widget.prototype._setOption.apply( this, arguments );
7128
if ( key === "disabled" ) {
7130
this.element.propAttr( "disabled", true );
7132
this.element.propAttr( "disabled", false );
7136
this._resetButton();
7139
refresh: function() {
7140
var isDisabled = this.element.is( ":disabled" );
7141
if ( isDisabled !== this.options.disabled ) {
7142
this._setOption( "disabled", isDisabled );
7144
if ( this.type === "radio" ) {
7145
radioGroup( this.element[0] ).each(function() {
7146
if ( $( this ).is( ":checked" ) ) {
7147
$( this ).button( "widget" )
7148
.addClass( "ui-state-active" )
7149
.attr( "aria-pressed", "true" );
7151
$( this ).button( "widget" )
7152
.removeClass( "ui-state-active" )
7153
.attr( "aria-pressed", "false" );
7156
} else if ( this.type === "checkbox" ) {
7157
if ( this.element.is( ":checked" ) ) {
7159
.addClass( "ui-state-active" )
7160
.attr( "aria-pressed", "true" );
7163
.removeClass( "ui-state-active" )
7164
.attr( "aria-pressed", "false" );
7169
_resetButton: function() {
7170
if ( this.type === "input" ) {
7171
if ( this.options.label ) {
7172
this.element.val( this.options.label );
7176
var buttonElement = this.buttonElement.removeClass( typeClasses ),
7177
buttonText = $( "<span></span>", this.element[0].ownerDocument )
7178
.addClass( "ui-button-text" )
7179
.html( this.options.label )
7180
.appendTo( buttonElement.empty() )
7182
icons = this.options.icons,
7183
multipleIcons = icons.primary && icons.secondary,
7186
if ( icons.primary || icons.secondary ) {
7187
if ( this.options.text ) {
7188
buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7191
if ( icons.primary ) {
7192
buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7195
if ( icons.secondary ) {
7196
buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7199
if ( !this.options.text ) {
7200
buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7202
if ( !this.hasTitle ) {
7203
buttonElement.attr( "title", buttonText );
7207
buttonClasses.push( "ui-button-text-only" );
7209
buttonElement.addClass( buttonClasses.join( " " ) );
7213
$.widget( "ui.buttonset", {
7215
items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)"
7218
_create: function() {
7219
this.element.addClass( "ui-buttonset" );
7226
_setOption: function( key, value ) {
7227
if ( key === "disabled" ) {
7228
this.buttons.button( "option", key, value );
7231
$.Widget.prototype._setOption.apply( this, arguments );
7234
refresh: function() {
7235
var rtl = this.element.css( "direction" ) === "rtl";
7237
this.buttons = this.element.find( this.options.items )
7238
.filter( ":ui-button" )
7239
.button( "refresh" )
7241
.not( ":ui-button" )
7245
return $( this ).button( "widget" )[ 0 ];
7247
.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7249
.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
7252
.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
7257
destroy: function() {
7258
this.element.removeClass( "ui-buttonset" );
7261
return $( this ).button( "widget" )[ 0 ];
7263
.removeClass( "ui-corner-left ui-corner-right" )
7265
.button( "destroy" );
7267
$.Widget.prototype.destroy.call( this );
7273
* jQuery UI Datepicker 1.8.18
7275
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
7276
* Dual licensed under the MIT or GPL Version 2 licenses.
7277
* http://jquery.org/license
7279
* http://docs.jquery.com/UI/Datepicker
7284
(function( $, undefined ) {
7286
$.extend($.ui, { datepicker: { version: "1.8.18" } });
7288
var PROP_NAME = 'datepicker';
7289
var dpuuid = new Date().getTime();
7292
/* Date picker manager.
7293
Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7294
Settings for (groups of) date pickers are maintained in an instance object,
7295
allowing multiple different settings on the same page. */
7297
function Datepicker() {
7298
this.debug = false; // Change this to true to start debugging
7299
this._curInst = null; // The current instance in use
7300
this._keyEvent = false; // If the last event was a key event
7301
this._disabledInputs = []; // List of date picker inputs that have been disabled
7302
this._datepickerShowing = false; // True if the popup picker is showing , false if not
7303
this._inDialog = false; // True if showing within a "dialog", false if not
7304
this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division
7305
this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class
7306
this._appendClass = 'ui-datepicker-append'; // The name of the append marker class
7307
this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class
7308
this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class
7309
this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class
7310
this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
7311
this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class
7312
this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
7313
this.regional = []; // Available regional settings, indexed by language code
7314
this.regional[''] = { // Default regional settings
7315
closeText: 'Done', // Display text for close link
7316
prevText: 'Prev', // Display text for previous month link
7317
nextText: 'Next', // Display text for next month link
7318
currentText: 'Today', // Display text for current month link
7319
monthNames: ['January','February','March','April','May','June',
7320
'July','August','September','October','November','December'], // Names of months for drop-down and formatting
7321
monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
7322
dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
7323
dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
7324
dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
7325
weekHeader: 'Wk', // Column header for week of the year
7326
dateFormat: 'mm/dd/yy', // See format options on parseDate
7327
firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7328
isRTL: false, // True if right-to-left language, false if left-to-right
7329
showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7330
yearSuffix: '' // Additional text to append to the year in the month headers
7332
this._defaults = { // Global defaults for all the date picker instances
7333
showOn: 'focus', // 'focus' for popup on focus,
7334
// 'button' for trigger button, or 'both' for either
7335
showAnim: 'fadeIn', // Name of jQuery animation for popup
7336
showOptions: {}, // Options for enhanced animations
7337
defaultDate: null, // Used when field is blank: actual date,
7338
// +/-number for offset from today, null for today
7339
appendText: '', // Display text following the input box, e.g. showing the format
7340
buttonText: '...', // Text for trigger button
7341
buttonImage: '', // URL for trigger button image
7342
buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7343
hideIfNoPrevNext: false, // True to hide next/previous month links
7344
// if not applicable, false to just disable them
7345
navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7346
gotoCurrent: false, // True if today link goes back to current selection instead
7347
changeMonth: false, // True if month can be selected directly, false if only prev/next
7348
changeYear: false, // True if year can be selected directly, false if only prev/next
7349
yearRange: 'c-10:c+10', // Range of years to display in drop-down,
7350
// either relative to today's year (-nn:+nn), relative to currently displayed year
7351
// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7352
showOtherMonths: false, // True to show dates in other months, false to leave blank
7353
selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7354
showWeek: false, // True to show week of the year, false to not show it
7355
calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7356
// takes a Date and returns the number of the week for it
7357
shortYearCutoff: '+10', // Short year values < this are in the current century,
7358
// > this are in the previous century,
7359
// string value starting with '+' for current year + value
7360
minDate: null, // The earliest selectable date, or null for no limit
7361
maxDate: null, // The latest selectable date, or null for no limit
7362
duration: 'fast', // Duration of display/closure
7363
beforeShowDay: null, // Function that takes a date and returns an array with
7364
// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
7365
// [2] = cell title (optional), e.g. $.datepicker.noWeekends
7366
beforeShow: null, // Function that takes an input field and
7367
// returns a set of custom settings for the date picker
7368
onSelect: null, // Define a callback function when a date is selected
7369
onChangeMonthYear: null, // Define a callback function when the month or year is changed
7370
onClose: null, // Define a callback function when the datepicker is closed
7371
numberOfMonths: 1, // Number of months to show at a time
7372
showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7373
stepMonths: 1, // Number of months to step back/forward
7374
stepBigMonths: 12, // Number of months to step back/forward for the big links
7375
altField: '', // Selector for an alternate field to store selected dates into
7376
altFormat: '', // The date format to use for the alternate field
7377
constrainInput: true, // The input is constrained by the current date format
7378
showButtonPanel: false, // True to show button panel, false to not show it
7379
autoSize: false, // True to size the input for the date format, false to leave as is
7380
disabled: false // The initial disabled state
7382
$.extend(this._defaults, this.regional['']);
7383
this.dpDiv = bindHover($('<div id="' + this._mainDivId + '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
7386
$.extend(Datepicker.prototype, {
7387
/* Class name added to elements to indicate already configured with a date picker. */
7388
markerClassName: 'hasDatepicker',
7390
//Keep track of the maximum number of rows displayed (see #7043)
7393
/* Debug logging (if enabled). */
7396
console.log.apply('', arguments);
7399
// TODO rename to "widget" when switching to widget factory
7400
_widgetDatepicker: function() {
7404
/* Override the default settings for all instances of the date picker.
7405
@param settings object - the new settings to use as defaults (anonymous object)
7406
@return the manager object */
7407
setDefaults: function(settings) {
7408
extendRemove(this._defaults, settings || {});
7412
/* Attach the date picker to a jQuery selection.
7413
@param target element - the target input field or division or span
7414
@param settings object - the new settings to use for this date picker instance (anonymous) */
7415
_attachDatepicker: function(target, settings) {
7416
// check for settings on the control itself - in namespace 'date:'
7417
var inlineSettings = null;
7418
for (var attrName in this._defaults) {
7419
var attrValue = target.getAttribute('date:' + attrName);
7421
inlineSettings = inlineSettings || {};
7423
inlineSettings[attrName] = eval(attrValue);
7425
inlineSettings[attrName] = attrValue;
7429
var nodeName = target.nodeName.toLowerCase();
7430
var inline = (nodeName == 'div' || nodeName == 'span');
7433
target.id = 'dp' + this.uuid;
7435
var inst = this._newInst($(target), inline);
7436
inst.settings = $.extend({}, settings || {}, inlineSettings || {});
7437
if (nodeName == 'input') {
7438
this._connectDatepicker(target, inst);
7439
} else if (inline) {
7440
this._inlineDatepicker(target, inst);
7444
/* Create a new instance object. */
7445
_newInst: function(target, inline) {
7446
var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
7447
return {id: id, input: target, // associated target
7448
selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7449
drawMonth: 0, drawYear: 0, // month being drawn
7450
inline: inline, // is datepicker inline or not
7451
dpDiv: (!inline ? this.dpDiv : // presentation div
7452
bindHover($('<div class="' + this._inlineClass + ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
7455
/* Attach the date picker to an input field. */
7456
_connectDatepicker: function(target, inst) {
7457
var input = $(target);
7458
inst.append = $([]);
7459
inst.trigger = $([]);
7460
if (input.hasClass(this.markerClassName))
7462
this._attachments(input, inst);
7463
input.addClass(this.markerClassName).keydown(this._doKeyDown).
7464
keypress(this._doKeyPress).keyup(this._doKeyUp).
7465
bind("setData.datepicker", function(event, key, value) {
7466
inst.settings[key] = value;
7467
}).bind("getData.datepicker", function(event, key) {
7468
return this._get(inst, key);
7470
this._autoSize(inst);
7471
$.data(target, PROP_NAME, inst);
7472
//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7473
if( inst.settings.disabled ) {
7474
this._disableDatepicker( target );
7478
/* Make attachments based on settings. */
7479
_attachments: function(input, inst) {
7480
var appendText = this._get(inst, 'appendText');
7481
var isRTL = this._get(inst, 'isRTL');
7483
inst.append.remove();
7485
inst.append = $('<span class="' + this._appendClass + '">' + appendText + '</span>');
7486
input[isRTL ? 'before' : 'after'](inst.append);
7488
input.unbind('focus', this._showDatepicker);
7490
inst.trigger.remove();
7491
var showOn = this._get(inst, 'showOn');
7492
if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field
7493
input.focus(this._showDatepicker);
7494
if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
7495
var buttonText = this._get(inst, 'buttonText');
7496
var buttonImage = this._get(inst, 'buttonImage');
7497
inst.trigger = $(this._get(inst, 'buttonImageOnly') ?
7498
$('<img/>').addClass(this._triggerClass).
7499
attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7500
$('<button type="button"></button>').addClass(this._triggerClass).
7501
html(buttonImage == '' ? buttonText : $('<img/>').attr(
7502
{ src:buttonImage, alt:buttonText, title:buttonText })));
7503
input[isRTL ? 'before' : 'after'](inst.trigger);
7504
inst.trigger.click(function() {
7505
if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0])
7506
$.datepicker._hideDatepicker();
7507
else if ($.datepicker._datepickerShowing && $.datepicker._lastInput != input[0]) {
7508
$.datepicker._hideDatepicker();
7509
$.datepicker._showDatepicker(input[0]);
7511
$.datepicker._showDatepicker(input[0]);
7517
/* Apply the maximum length for the date format. */
7518
_autoSize: function(inst) {
7519
if (this._get(inst, 'autoSize') && !inst.inline) {
7520
var date = new Date(2009, 12 - 1, 20); // Ensure double digits
7521
var dateFormat = this._get(inst, 'dateFormat');
7522
if (dateFormat.match(/[DM]/)) {
7523
var findMax = function(names) {
7526
for (var i = 0; i < names.length; i++) {
7527
if (names[i].length > max) {
7528
max = names[i].length;
7534
date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7535
'monthNames' : 'monthNamesShort'))));
7536
date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7537
'dayNames' : 'dayNamesShort'))) + 20 - date.getDay());
7539
inst.input.attr('size', this._formatDate(inst, date).length);
7543
/* Attach an inline date picker to a div. */
7544
_inlineDatepicker: function(target, inst) {
7545
var divSpan = $(target);
7546
if (divSpan.hasClass(this.markerClassName))
7548
divSpan.addClass(this.markerClassName).append(inst.dpDiv).
7549
bind("setData.datepicker", function(event, key, value){
7550
inst.settings[key] = value;
7551
}).bind("getData.datepicker", function(event, key){
7552
return this._get(inst, key);
7554
$.data(target, PROP_NAME, inst);
7555
this._setDate(inst, this._getDefaultDate(inst), true);
7556
this._updateDatepicker(inst);
7557
this._updateAlternate(inst);
7558
//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7559
if( inst.settings.disabled ) {
7560
this._disableDatepicker( target );
7562
// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7563
// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7564
inst.dpDiv.css( "display", "block" );
7567
/* Pop-up the date picker in a "dialog" box.
7568
@param input element - ignored
7569
@param date string or Date - the initial date to display
7570
@param onSelect function - the function to call when a date is selected
7571
@param settings object - update the dialog date picker instance's settings (anonymous object)
7572
@param pos int[2] - coordinates for the dialog's position within the screen or
7573
event - with x/y coordinates or
7574
leave empty for default (screen centre)
7575
@return the manager object */
7576
_dialogDatepicker: function(input, date, onSelect, settings, pos) {
7577
var inst = this._dialogInst; // internal instance
7580
var id = 'dp' + this.uuid;
7581
this._dialogInput = $('<input type="text" id="' + id +
7582
'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');
7583
this._dialogInput.keydown(this._doKeyDown);
7584
$('body').append(this._dialogInput);
7585
inst = this._dialogInst = this._newInst(this._dialogInput, false);
7587
$.data(this._dialogInput[0], PROP_NAME, inst);
7589
extendRemove(inst.settings, settings || {});
7590
date = (date && date.constructor == Date ? this._formatDate(inst, date) : date);
7591
this._dialogInput.val(date);
7593
this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7595
var browserWidth = document.documentElement.clientWidth;
7596
var browserHeight = document.documentElement.clientHeight;
7597
var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7598
var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7599
this._pos = // should use actual width/height below
7600
[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7603
// move input on screen for focus, but hidden behind dialog
7604
this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px');
7605
inst.settings.onSelect = onSelect;
7606
this._inDialog = true;
7607
this.dpDiv.addClass(this._dialogClass);
7608
this._showDatepicker(this._dialogInput[0]);
7610
$.blockUI(this.dpDiv);
7611
$.data(this._dialogInput[0], PROP_NAME, inst);
7615
/* Detach a datepicker from its control.
7616
@param target element - the target input field or division or span */
7617
_destroyDatepicker: function(target) {
7618
var $target = $(target);
7619
var inst = $.data(target, PROP_NAME);
7620
if (!$target.hasClass(this.markerClassName)) {
7623
var nodeName = target.nodeName.toLowerCase();
7624
$.removeData(target, PROP_NAME);
7625
if (nodeName == 'input') {
7626
inst.append.remove();
7627
inst.trigger.remove();
7628
$target.removeClass(this.markerClassName).
7629
unbind('focus', this._showDatepicker).
7630
unbind('keydown', this._doKeyDown).
7631
unbind('keypress', this._doKeyPress).
7632
unbind('keyup', this._doKeyUp);
7633
} else if (nodeName == 'div' || nodeName == 'span')
7634
$target.removeClass(this.markerClassName).empty();
7637
/* Enable the date picker to a jQuery selection.
7638
@param target element - the target input field or division or span */
7639
_enableDatepicker: function(target) {
7640
var $target = $(target);
7641
var inst = $.data(target, PROP_NAME);
7642
if (!$target.hasClass(this.markerClassName)) {
7645
var nodeName = target.nodeName.toLowerCase();
7646
if (nodeName == 'input') {
7647
target.disabled = false;
7648
inst.trigger.filter('button').
7649
each(function() { this.disabled = false; }).end().
7650
filter('img').css({opacity: '1.0', cursor: ''});
7652
else if (nodeName == 'div' || nodeName == 'span') {
7653
var inline = $target.children('.' + this._inlineClass);
7654
inline.children().removeClass('ui-state-disabled');
7655
inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7656
removeAttr("disabled");
7658
this._disabledInputs = $.map(this._disabledInputs,
7659
function(value) { return (value == target ? null : value); }); // delete entry
7662
/* Disable the date picker to a jQuery selection.
7663
@param target element - the target input field or division or span */
7664
_disableDatepicker: function(target) {
7665
var $target = $(target);
7666
var inst = $.data(target, PROP_NAME);
7667
if (!$target.hasClass(this.markerClassName)) {
7670
var nodeName = target.nodeName.toLowerCase();
7671
if (nodeName == 'input') {
7672
target.disabled = true;
7673
inst.trigger.filter('button').
7674
each(function() { this.disabled = true; }).end().
7675
filter('img').css({opacity: '0.5', cursor: 'default'});
7677
else if (nodeName == 'div' || nodeName == 'span') {
7678
var inline = $target.children('.' + this._inlineClass);
7679
inline.children().addClass('ui-state-disabled');
7680
inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7681
attr("disabled", "disabled");
7683
this._disabledInputs = $.map(this._disabledInputs,
7684
function(value) { return (value == target ? null : value); }); // delete entry
7685
this._disabledInputs[this._disabledInputs.length] = target;
7688
/* Is the first field in a jQuery collection disabled as a datepicker?
7689
@param target element - the target input field or division or span
7690
@return boolean - true if disabled, false if enabled */
7691
_isDisabledDatepicker: function(target) {
7695
for (var i = 0; i < this._disabledInputs.length; i++) {
7696
if (this._disabledInputs[i] == target)
7702
/* Retrieve the instance data for the target control.
7703
@param target element - the target input field or division or span
7704
@return object - the associated instance data
7705
@throws error if a jQuery problem getting data */
7706
_getInst: function(target) {
7708
return $.data(target, PROP_NAME);
7711
throw 'Missing instance data for this datepicker';
7715
/* Update or retrieve the settings for a date picker attached to an input field or division.
7716
@param target element - the target input field or division or span
7717
@param name object - the new settings to update or
7718
string - the name of the setting to change or retrieve,
7719
when retrieving also 'all' for all instance settings or
7720
'defaults' for all global defaults
7721
@param value any - the new value for the setting
7722
(omit if above is an object or to retrieve a value) */
7723
_optionDatepicker: function(target, name, value) {
7724
var inst = this._getInst(target);
7725
if (arguments.length == 2 && typeof name == 'string') {
7726
return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) :
7727
(inst ? (name == 'all' ? $.extend({}, inst.settings) :
7728
this._get(inst, name)) : null));
7730
var settings = name || {};
7731
if (typeof name == 'string') {
7733
settings[name] = value;
7736
if (this._curInst == inst) {
7737
this._hideDatepicker();
7739
var date = this._getDateDatepicker(target, true);
7740
var minDate = this._getMinMaxDate(inst, 'min');
7741
var maxDate = this._getMinMaxDate(inst, 'max');
7742
extendRemove(inst.settings, settings);
7743
// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7744
if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined)
7745
inst.settings.minDate = this._formatDate(inst, minDate);
7746
if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined)
7747
inst.settings.maxDate = this._formatDate(inst, maxDate);
7748
this._attachments($(target), inst);
7749
this._autoSize(inst);
7750
this._setDate(inst, date);
7751
this._updateAlternate(inst);
7752
this._updateDatepicker(inst);
7756
// change method deprecated
7757
_changeDatepicker: function(target, name, value) {
7758
this._optionDatepicker(target, name, value);
7761
/* Redraw the date picker attached to an input field or division.
7762
@param target element - the target input field or division or span */
7763
_refreshDatepicker: function(target) {
7764
var inst = this._getInst(target);
7766
this._updateDatepicker(inst);
7770
/* Set the dates for a jQuery selection.
7771
@param target element - the target input field or division or span
7772
@param date Date - the new date */
7773
_setDateDatepicker: function(target, date) {
7774
var inst = this._getInst(target);
7776
this._setDate(inst, date);
7777
this._updateDatepicker(inst);
7778
this._updateAlternate(inst);
7782
/* Get the date(s) for the first entry in a jQuery selection.
7783
@param target element - the target input field or division or span
7784
@param noDefault boolean - true if no default date is to be used
7785
@return Date - the current date */
7786
_getDateDatepicker: function(target, noDefault) {
7787
var inst = this._getInst(target);
7788
if (inst && !inst.inline)
7789
this._setDateFromField(inst, noDefault);
7790
return (inst ? this._getDate(inst) : null);
7793
/* Handle keystrokes. */
7794
_doKeyDown: function(event) {
7795
var inst = $.datepicker._getInst(event.target);
7797
var isRTL = inst.dpDiv.is('.ui-datepicker-rtl');
7798
inst._keyEvent = true;
7799
if ($.datepicker._datepickerShowing)
7800
switch (event.keyCode) {
7801
case 9: $.datepicker._hideDatepicker();
7803
break; // hide on tab out
7804
case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' +
7805
$.datepicker._currentClass + ')', inst.dpDiv);
7807
$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
7808
var onSelect = $.datepicker._get(inst, 'onSelect');
7810
var dateStr = $.datepicker._formatDate(inst);
7812
// trigger custom callback
7813
onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
7816
$.datepicker._hideDatepicker();
7817
return false; // don't submit the form
7818
break; // select the value on enter
7819
case 27: $.datepicker._hideDatepicker();
7820
break; // hide on escape
7821
case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7822
-$.datepicker._get(inst, 'stepBigMonths') :
7823
-$.datepicker._get(inst, 'stepMonths')), 'M');
7824
break; // previous month/year on page up/+ ctrl
7825
case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7826
+$.datepicker._get(inst, 'stepBigMonths') :
7827
+$.datepicker._get(inst, 'stepMonths')), 'M');
7828
break; // next month/year on page down/+ ctrl
7829
case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target);
7830
handled = event.ctrlKey || event.metaKey;
7831
break; // clear on ctrl or command +end
7832
case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target);
7833
handled = event.ctrlKey || event.metaKey;
7834
break; // current on ctrl or command +home
7835
case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D');
7836
handled = event.ctrlKey || event.metaKey;
7837
// -1 day on ctrl or command +left
7838
if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7839
-$.datepicker._get(inst, 'stepBigMonths') :
7840
-$.datepicker._get(inst, 'stepMonths')), 'M');
7841
// next month/year on alt +left on Mac
7843
case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D');
7844
handled = event.ctrlKey || event.metaKey;
7845
break; // -1 week on ctrl or command +up
7846
case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D');
7847
handled = event.ctrlKey || event.metaKey;
7848
// +1 day on ctrl or command +right
7849
if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7850
+$.datepicker._get(inst, 'stepBigMonths') :
7851
+$.datepicker._get(inst, 'stepMonths')), 'M');
7852
// next month/year on alt +right
7854
case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D');
7855
handled = event.ctrlKey || event.metaKey;
7856
break; // +1 week on ctrl or command +down
7857
default: handled = false;
7859
else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home
7860
$.datepicker._showDatepicker(this);
7865
event.preventDefault();
7866
event.stopPropagation();
7870
/* Filter entered characters - based on date format. */
7871
_doKeyPress: function(event) {
7872
var inst = $.datepicker._getInst(event.target);
7873
if ($.datepicker._get(inst, 'constrainInput')) {
7874
var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat'));
7875
var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode);
7876
return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1);
7880
/* Synchronise manual entry and field/alternate field. */
7881
_doKeyUp: function(event) {
7882
var inst = $.datepicker._getInst(event.target);
7883
if (inst.input.val() != inst.lastVal) {
7885
var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
7886
(inst.input ? inst.input.val() : null),
7887
$.datepicker._getFormatConfig(inst));
7888
if (date) { // only if valid
7889
$.datepicker._setDateFromField(inst);
7890
$.datepicker._updateAlternate(inst);
7891
$.datepicker._updateDatepicker(inst);
7895
$.datepicker.log(event);
7901
/* Pop-up the date picker for a given input field.
7902
If false returned from beforeShow event handler do not show.
7903
@param input element - the input field attached to the date picker or
7904
event - if triggered by focus */
7905
_showDatepicker: function(input) {
7906
input = input.target || input;
7907
if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger
7908
input = $('input', input.parentNode)[0];
7909
if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here
7911
var inst = $.datepicker._getInst(input);
7912
if ($.datepicker._curInst && $.datepicker._curInst != inst) {
7913
$.datepicker._curInst.dpDiv.stop(true, true);
7914
if ( inst && $.datepicker._datepickerShowing ) {
7915
$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
7918
var beforeShow = $.datepicker._get(inst, 'beforeShow');
7919
var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
7920
if(beforeShowSettings === false){
7924
extendRemove(inst.settings, beforeShowSettings);
7925
inst.lastVal = null;
7926
$.datepicker._lastInput = input;
7927
$.datepicker._setDateFromField(inst);
7928
if ($.datepicker._inDialog) // hide cursor
7930
if (!$.datepicker._pos) { // position below input
7931
$.datepicker._pos = $.datepicker._findPos(input);
7932
$.datepicker._pos[1] += input.offsetHeight; // add the height
7934
var isFixed = false;
7935
$(input).parents().each(function() {
7936
isFixed |= $(this).css('position') == 'fixed';
7939
if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
7940
$.datepicker._pos[0] -= document.documentElement.scrollLeft;
7941
$.datepicker._pos[1] -= document.documentElement.scrollTop;
7943
var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
7944
$.datepicker._pos = null;
7945
//to avoid flashes on Firefox
7947
// determine sizing offscreen
7948
inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'});
7949
$.datepicker._updateDatepicker(inst);
7950
// fix width for dynamic number of date pickers
7951
// and adjust position before showing
7952
offset = $.datepicker._checkOffset(inst, offset, isFixed);
7953
inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
7954
'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none',
7955
left: offset.left + 'px', top: offset.top + 'px'});
7957
var showAnim = $.datepicker._get(inst, 'showAnim');
7958
var duration = $.datepicker._get(inst, 'duration');
7959
var postProcess = function() {
7960
var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7961
if( !! cover.length ){
7962
var borders = $.datepicker._getBorders(inst.dpDiv);
7963
cover.css({left: -borders[0], top: -borders[1],
7964
width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()});
7967
inst.dpDiv.zIndex($(input).zIndex()+1);
7968
$.datepicker._datepickerShowing = true;
7969
if ($.effects && $.effects[showAnim])
7970
inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
7972
inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess);
7973
if (!showAnim || !duration)
7975
if (inst.input.is(':visible') && !inst.input.is(':disabled'))
7977
$.datepicker._curInst = inst;
7981
/* Generate the date picker content. */
7982
_updateDatepicker: function(inst) {
7984
self.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7985
var borders = $.datepicker._getBorders(inst.dpDiv);
7986
instActive = inst; // for delegate hover events
7987
inst.dpDiv.empty().append(this._generateHTML(inst));
7988
var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only
7989
if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6
7990
cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()})
7992
inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover();
7993
var numMonths = this._getNumberOfMonths(inst);
7994
var cols = numMonths[1];
7996
inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
7998
inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em');
7999
inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') +
8000
'Class']('ui-datepicker-multi');
8001
inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') +
8002
'Class']('ui-datepicker-rtl');
8003
if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
8004
// #6694 - don't focus the input if it's already focused
8005
// this breaks the change event in IE
8006
inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement)
8008
// deffered render of the years select (to avoid flashes on Firefox)
8009
if( inst.yearshtml ){
8010
var origyearshtml = inst.yearshtml;
8011
setTimeout(function(){
8012
//assure that inst.yearshtml didn't change.
8013
if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8014
inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml);
8016
origyearshtml = inst.yearshtml = null;
8021
/* Retrieve the size of left and top borders for an element.
8022
@param elem (jQuery object) the element of interest
8023
@return (number[2]) the left and top borders */
8024
_getBorders: function(elem) {
8025
var convert = function(value) {
8026
return {thin: 1, medium: 2, thick: 3}[value] || value;
8028
return [parseFloat(convert(elem.css('border-left-width'))),
8029
parseFloat(convert(elem.css('border-top-width')))];
8032
/* Check positioning to remain on screen. */
8033
_checkOffset: function(inst, offset, isFixed) {
8034
var dpWidth = inst.dpDiv.outerWidth();
8035
var dpHeight = inst.dpDiv.outerHeight();
8036
var inputWidth = inst.input ? inst.input.outerWidth() : 0;
8037
var inputHeight = inst.input ? inst.input.outerHeight() : 0;
8038
var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft();
8039
var viewHeight = document.documentElement.clientHeight + $(document).scrollTop();
8041
offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0);
8042
offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0;
8043
offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8045
// now check if datepicker is showing outside window viewport - move to a better place if so.
8046
offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8047
Math.abs(offset.left + dpWidth - viewWidth) : 0);
8048
offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8049
Math.abs(dpHeight + inputHeight) : 0);
8054
/* Find an object's position on the screen. */
8055
_findPos: function(obj) {
8056
var inst = this._getInst(obj);
8057
var isRTL = this._get(inst, 'isRTL');
8058
while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) {
8059
obj = obj[isRTL ? 'previousSibling' : 'nextSibling'];
8061
var position = $(obj).offset();
8062
return [position.left, position.top];
8065
/* Hide the date picker from view.
8066
@param input element - the input field attached to the date picker */
8067
_hideDatepicker: function(input) {
8068
var inst = this._curInst;
8069
if (!inst || (input && inst != $.data(input, PROP_NAME)))
8071
if (this._datepickerShowing) {
8072
var showAnim = this._get(inst, 'showAnim');
8073
var duration = this._get(inst, 'duration');
8075
var postProcess = function() {
8076
$.datepicker._tidyDialog(inst);
8077
self._curInst = null;
8079
if ($.effects && $.effects[showAnim])
8080
inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess);
8082
inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' :
8083
(showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess);
8086
this._datepickerShowing = false;
8087
var onClose = this._get(inst, 'onClose');
8089
onClose.apply((inst.input ? inst.input[0] : null),
8090
[(inst.input ? inst.input.val() : ''), inst]);
8091
this._lastInput = null;
8092
if (this._inDialog) {
8093
this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' });
8096
$('body').append(this.dpDiv);
8099
this._inDialog = false;
8103
/* Tidy up after a dialog display. */
8104
_tidyDialog: function(inst) {
8105
inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar');
8108
/* Close date picker if clicked elsewhere. */
8109
_checkExternalClick: function(event) {
8110
if (!$.datepicker._curInst)
8113
var $target = $(event.target),
8114
inst = $.datepicker._getInst($target[0]);
8116
if ( ( ( $target[0].id != $.datepicker._mainDivId &&
8117
$target.parents('#' + $.datepicker._mainDivId).length == 0 &&
8118
!$target.hasClass($.datepicker.markerClassName) &&
8119
!$target.closest("." + $.datepicker._triggerClass).length &&
8120
$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
8121
( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) )
8122
$.datepicker._hideDatepicker();
8125
/* Adjust one of the date sub-fields. */
8126
_adjustDate: function(id, offset, period) {
8128
var inst = this._getInst(target[0]);
8129
if (this._isDisabledDatepicker(target[0])) {
8132
this._adjustInstDate(inst, offset +
8133
(period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
8135
this._updateDatepicker(inst);
8138
/* Action for current link. */
8139
_gotoToday: function(id) {
8141
var inst = this._getInst(target[0]);
8142
if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
8143
inst.selectedDay = inst.currentDay;
8144
inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8145
inst.drawYear = inst.selectedYear = inst.currentYear;
8148
var date = new Date();
8149
inst.selectedDay = date.getDate();
8150
inst.drawMonth = inst.selectedMonth = date.getMonth();
8151
inst.drawYear = inst.selectedYear = date.getFullYear();
8153
this._notifyChange(inst);
8154
this._adjustDate(target);
8157
/* Action for selecting a new month/year. */
8158
_selectMonthYear: function(id, select, period) {
8160
var inst = this._getInst(target[0]);
8161
inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
8162
inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
8163
parseInt(select.options[select.selectedIndex].value,10);
8164
this._notifyChange(inst);
8165
this._adjustDate(target);
8168
/* Action for selecting a day. */
8169
_selectDay: function(id, month, year, td) {
8171
if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8174
var inst = this._getInst(target[0]);
8175
inst.selectedDay = inst.currentDay = $('a', td).html();
8176
inst.selectedMonth = inst.currentMonth = month;
8177
inst.selectedYear = inst.currentYear = year;
8178
this._selectDate(id, this._formatDate(inst,
8179
inst.currentDay, inst.currentMonth, inst.currentYear));
8182
/* Erase the input field and hide the date picker. */
8183
_clearDate: function(id) {
8185
var inst = this._getInst(target[0]);
8186
this._selectDate(target, '');
8189
/* Update the input field with the selected date. */
8190
_selectDate: function(id, dateStr) {
8192
var inst = this._getInst(target[0]);
8193
dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
8195
inst.input.val(dateStr);
8196
this._updateAlternate(inst);
8197
var onSelect = this._get(inst, 'onSelect');
8199
onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
8200
else if (inst.input)
8201
inst.input.trigger('change'); // fire the change event
8203
this._updateDatepicker(inst);
8205
this._hideDatepicker();
8206
this._lastInput = inst.input[0];
8207
if (typeof(inst.input[0]) != 'object')
8208
inst.input.focus(); // restore focus
8209
this._lastInput = null;
8213
/* Update any alternate field to synchronise with the main field. */
8214
_updateAlternate: function(inst) {
8215
var altField = this._get(inst, 'altField');
8216
if (altField) { // update alternate field too
8217
var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat');
8218
var date = this._getDate(inst);
8219
var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
8220
$(altField).each(function() { $(this).val(dateStr); });
8224
/* Set as beforeShowDay function to prevent selection of weekends.
8225
@param date Date - the date to customise
8226
@return [boolean, string] - is this date selectable?, what is its CSS class? */
8227
noWeekends: function(date) {
8228
var day = date.getDay();
8229
return [(day > 0 && day < 6), ''];
8232
/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8233
@param date Date - the date to get the week for
8234
@return number - the number of the week within the year that contains this date */
8235
iso8601Week: function(date) {
8236
var checkDate = new Date(date.getTime());
8237
// Find Thursday of this week starting on Monday
8238
checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
8239
var time = checkDate.getTime();
8240
checkDate.setMonth(0); // Compare with Jan 1
8241
checkDate.setDate(1);
8242
return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
8245
/* Parse a string value into a date object.
8246
See formatDate below for the possible formats.
8248
@param format string - the expected format of the date
8249
@param value string - the date in the above format
8250
@param settings Object - attributes include:
8251
shortYearCutoff number - the cutoff year for determining the century (optional)
8252
dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
8253
dayNames string[7] - names of the days from Sunday (optional)
8254
monthNamesShort string[12] - abbreviated names of the months (optional)
8255
monthNames string[12] - names of the months (optional)
8256
@return Date - the extracted date value or null if value is blank */
8257
parseDate: function (format, value, settings) {
8258
if (format == null || value == null)
8259
throw 'Invalid arguments';
8260
value = (typeof value == 'object' ? value.toString() : value + '');
8263
var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff;
8264
shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
8265
new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
8266
var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
8267
var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
8268
var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
8269
var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
8274
var literal = false;
8275
// Check whether a format character is doubled
8276
var lookAhead = function(match) {
8277
var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8282
// Extract a number from the string value
8283
var getNumber = function(match) {
8284
var isDoubled = lookAhead(match);
8285
var size = (match == '@' ? 14 : (match == '!' ? 20 :
8286
(match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2))));
8287
var digits = new RegExp('^\\d{1,' + size + '}');
8288
var num = value.substring(iValue).match(digits);
8290
throw 'Missing number at position ' + iValue;
8291
iValue += num[0].length;
8292
return parseInt(num[0], 10);
8294
// Extract a name from the string value and convert to an index
8295
var getName = function(match, shortNames, longNames) {
8296
var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
8298
}).sort(function (a, b) {
8299
return -(a[1].length - b[1].length);
8302
$.each(names, function (i, pair) {
8304
if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) {
8306
iValue += name.length;
8313
throw 'Unknown name at position ' + iValue;
8315
// Confirm that a literal character matches the string value
8316
var checkLiteral = function() {
8317
if (value.charAt(iValue) != format.charAt(iFormat))
8318
throw 'Unexpected literal at position ' + iValue;
8322
for (var iFormat = 0; iFormat < format.length; iFormat++) {
8324
if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8329
switch (format.charAt(iFormat)) {
8331
day = getNumber('d');
8334
getName('D', dayNamesShort, dayNames);
8337
doy = getNumber('o');
8340
month = getNumber('m');
8343
month = getName('M', monthNamesShort, monthNames);
8346
year = getNumber('y');
8349
var date = new Date(getNumber('@'));
8350
year = date.getFullYear();
8351
month = date.getMonth() + 1;
8352
day = date.getDate();
8355
var date = new Date((getNumber('!') - this._ticksTo1970) / 10000);
8356
year = date.getFullYear();
8357
month = date.getMonth() + 1;
8358
day = date.getDate();
8370
if (iValue < value.length){
8371
throw "Extra/unparsed characters found in date: " + value.substring(iValue);
8374
year = new Date().getFullYear();
8375
else if (year < 100)
8376
year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8377
(year <= shortYearCutoff ? 0 : -100);
8382
var dim = this._getDaysInMonth(year, month - 1);
8389
var date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8390
if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day)
8391
throw 'Invalid date'; // E.g. 31/02/00
8395
/* Standard date formats. */
8396
ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601)
8397
COOKIE: 'D, dd M yy',
8398
ISO_8601: 'yy-mm-dd',
8399
RFC_822: 'D, d M y',
8400
RFC_850: 'DD, dd-M-y',
8401
RFC_1036: 'D, d M y',
8402
RFC_1123: 'D, d M yy',
8403
RFC_2822: 'D, d M yy',
8404
RSS: 'D, d M y', // RFC 822
8407
W3C: 'yy-mm-dd', // ISO 8601
8409
_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8410
Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8412
/* Format a date object into a string value.
8413
The format can be combinations of the following:
8414
d - day of month (no leading zero)
8415
dd - day of month (two digit)
8416
o - day of year (no leading zeros)
8417
oo - day of year (three digit)
8420
m - month of year (no leading zero)
8421
mm - month of year (two digit)
8422
M - month name short
8423
MM - month name long
8424
y - year (two digit)
8425
yy - year (four digit)
8426
@ - Unix timestamp (ms since 01/01/1970)
8427
! - Windows ticks (100ns since 01/01/0001)
8428
'...' - literal text
8431
@param format string - the desired format of the date
8432
@param date Date - the date value to format
8433
@param settings Object - attributes include:
8434
dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
8435
dayNames string[7] - names of the days from Sunday (optional)
8436
monthNamesShort string[12] - abbreviated names of the months (optional)
8437
monthNames string[12] - names of the months (optional)
8438
@return string - the date in the above format */
8439
formatDate: function (format, date, settings) {
8442
var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort;
8443
var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames;
8444
var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort;
8445
var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames;
8446
// Check whether a format character is doubled
8447
var lookAhead = function(match) {
8448
var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8453
// Format a number, with leading zero if necessary
8454
var formatNumber = function(match, value, len) {
8455
var num = '' + value;
8456
if (lookAhead(match))
8457
while (num.length < len)
8461
// Format a name, short or long as requested
8462
var formatName = function(match, value, shortNames, longNames) {
8463
return (lookAhead(match) ? longNames[value] : shortNames[value]);
8466
var literal = false;
8468
for (var iFormat = 0; iFormat < format.length; iFormat++) {
8470
if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8473
output += format.charAt(iFormat);
8475
switch (format.charAt(iFormat)) {
8477
output += formatNumber('d', date.getDate(), 2);
8480
output += formatName('D', date.getDay(), dayNamesShort, dayNames);
8483
output += formatNumber('o',
8484
Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
8487
output += formatNumber('m', date.getMonth() + 1, 2);
8490
output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
8493
output += (lookAhead('y') ? date.getFullYear() :
8494
(date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
8497
output += date.getTime();
8500
output += date.getTime() * 10000 + this._ticksTo1970;
8509
output += format.charAt(iFormat);
8515
/* Extract all possible characters from the date format. */
8516
_possibleChars: function (format) {
8518
var literal = false;
8519
// Check whether a format character is doubled
8520
var lookAhead = function(match) {
8521
var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
8526
for (var iFormat = 0; iFormat < format.length; iFormat++)
8528
if (format.charAt(iFormat) == "'" && !lookAhead("'"))
8531
chars += format.charAt(iFormat);
8533
switch (format.charAt(iFormat)) {
8534
case 'd': case 'm': case 'y': case '@':
8535
chars += '0123456789';
8538
return null; // Accept anything
8546
chars += format.charAt(iFormat);
8551
/* Get a setting value, defaulting if necessary. */
8552
_get: function(inst, name) {
8553
return inst.settings[name] !== undefined ?
8554
inst.settings[name] : this._defaults[name];
8557
/* Parse existing date and initialise date picker. */
8558
_setDateFromField: function(inst, noDefault) {
8559
if (inst.input.val() == inst.lastVal) {
8562
var dateFormat = this._get(inst, 'dateFormat');
8563
var dates = inst.lastVal = inst.input ? inst.input.val() : null;
8564
var date, defaultDate;
8565
date = defaultDate = this._getDefaultDate(inst);
8566
var settings = this._getFormatConfig(inst);
8568
date = this.parseDate(dateFormat, dates, settings) || defaultDate;
8571
dates = (noDefault ? '' : dates);
8573
inst.selectedDay = date.getDate();
8574
inst.drawMonth = inst.selectedMonth = date.getMonth();
8575
inst.drawYear = inst.selectedYear = date.getFullYear();
8576
inst.currentDay = (dates ? date.getDate() : 0);
8577
inst.currentMonth = (dates ? date.getMonth() : 0);
8578
inst.currentYear = (dates ? date.getFullYear() : 0);
8579
this._adjustInstDate(inst);
8582
/* Retrieve the default date shown on opening. */
8583
_getDefaultDate: function(inst) {
8584
return this._restrictMinMax(inst,
8585
this._determineDate(inst, this._get(inst, 'defaultDate'), new Date()));
8588
/* A date may be specified as an exact value or a relative one. */
8589
_determineDate: function(inst, date, defaultDate) {
8590
var offsetNumeric = function(offset) {
8591
var date = new Date();
8592
date.setDate(date.getDate() + offset);
8595
var offsetString = function(offset) {
8597
return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
8598
offset, $.datepicker._getFormatConfig(inst));
8603
var date = (offset.toLowerCase().match(/^c/) ?
8604
$.datepicker._getDate(inst) : null) || new Date();
8605
var year = date.getFullYear();
8606
var month = date.getMonth();
8607
var day = date.getDate();
8608
var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
8609
var matches = pattern.exec(offset);
8611
switch (matches[2] || 'd') {
8612
case 'd' : case 'D' :
8613
day += parseInt(matches[1],10); break;
8614
case 'w' : case 'W' :
8615
day += parseInt(matches[1],10) * 7; break;
8616
case 'm' : case 'M' :
8617
month += parseInt(matches[1],10);
8618
day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8620
case 'y': case 'Y' :
8621
year += parseInt(matches[1],10);
8622
day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8625
matches = pattern.exec(offset);
8627
return new Date(year, month, day);
8629
var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) :
8630
(typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
8631
newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate);
8633
newDate.setHours(0);
8634
newDate.setMinutes(0);
8635
newDate.setSeconds(0);
8636
newDate.setMilliseconds(0);
8638
return this._daylightSavingAdjust(newDate);
8641
/* Handle switch to/from daylight saving.
8642
Hours may be non-zero on daylight saving cut-over:
8643
> 12 when midnight changeover, but then cannot generate
8644
midnight datetime, so jump to 1AM, otherwise reset.
8645
@param date (Date) the date to check
8646
@return (Date) the corrected date */
8647
_daylightSavingAdjust: function(date) {
8648
if (!date) return null;
8649
date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
8653
/* Set the date(s) directly. */
8654
_setDate: function(inst, date, noChange) {
8656
var origMonth = inst.selectedMonth;
8657
var origYear = inst.selectedYear;
8658
var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
8659
inst.selectedDay = inst.currentDay = newDate.getDate();
8660
inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8661
inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8662
if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange)
8663
this._notifyChange(inst);
8664
this._adjustInstDate(inst);
8666
inst.input.val(clear ? '' : this._formatDate(inst));
8670
/* Retrieve the date(s) directly. */
8671
_getDate: function(inst) {
8672
var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null :
8673
this._daylightSavingAdjust(new Date(
8674
inst.currentYear, inst.currentMonth, inst.currentDay)));
8678
/* Generate the HTML for the current state of the date picker. */
8679
_generateHTML: function(inst) {
8680
var today = new Date();
8681
today = this._daylightSavingAdjust(
8682
new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time
8683
var isRTL = this._get(inst, 'isRTL');
8684
var showButtonPanel = this._get(inst, 'showButtonPanel');
8685
var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext');
8686
var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat');
8687
var numMonths = this._getNumberOfMonths(inst);
8688
var showCurrentAtPos = this._get(inst, 'showCurrentAtPos');
8689
var stepMonths = this._get(inst, 'stepMonths');
8690
var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1);
8691
var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
8692
new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
8693
var minDate = this._getMinMaxDate(inst, 'min');
8694
var maxDate = this._getMinMaxDate(inst, 'max');
8695
var drawMonth = inst.drawMonth - showCurrentAtPos;
8696
var drawYear = inst.drawYear;
8697
if (drawMonth < 0) {
8702
var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
8703
maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
8704
maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
8705
while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
8707
if (drawMonth < 0) {
8713
inst.drawMonth = drawMonth;
8714
inst.drawYear = drawYear;
8715
var prevText = this._get(inst, 'prevText');
8716
prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
8717
this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
8718
this._getFormatConfig(inst)));
8719
var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
8720
'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid +
8721
'.datepicker._adjustDate(\'#' + inst.id + '\', -' + stepMonths + ', \'M\');"' +
8722
' title="' + prevText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'e' : 'w') + '">' + prevText + '</span></a>' :
8723
(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>'));
8724
var nextText = this._get(inst, 'nextText');
8725
nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
8726
this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
8727
this._getFormatConfig(inst)));
8728
var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
8729
'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid +
8730
'.datepicker._adjustDate(\'#' + inst.id + '\', +' + stepMonths + ', \'M\');"' +
8731
' title="' + nextText + '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL ? 'w' : 'e') + '">' + nextText + '</span></a>' :
8732
(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>'));
8733
var currentText = this._get(inst, 'currentText');
8734
var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today);
8735
currentText = (!navigationAsDateFormat ? currentText :
8736
this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
8737
var controls = (!inst.inline ? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
8738
'.datepicker._hideDatepicker();">' + this._get(inst, 'closeText') + '</button>' : '');
8739
var buttonPanel = (showButtonPanel) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL ? controls : '') +
8740
(this._isInRange(inst, gotoDate) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid +
8741
'.datepicker._gotoToday(\'#' + inst.id + '\');"' +
8742
'>' + currentText + '</button>' : '') + (isRTL ? '' : controls) + '</div>' : '';
8743
var firstDay = parseInt(this._get(inst, 'firstDay'),10);
8744
firstDay = (isNaN(firstDay) ? 0 : firstDay);
8745
var showWeek = this._get(inst, 'showWeek');
8746
var dayNames = this._get(inst, 'dayNames');
8747
var dayNamesShort = this._get(inst, 'dayNamesShort');
8748
var dayNamesMin = this._get(inst, 'dayNamesMin');
8749
var monthNames = this._get(inst, 'monthNames');
8750
var monthNamesShort = this._get(inst, 'monthNamesShort');
8751
var beforeShowDay = this._get(inst, 'beforeShowDay');
8752
var showOtherMonths = this._get(inst, 'showOtherMonths');
8753
var selectOtherMonths = this._get(inst, 'selectOtherMonths');
8754
var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week;
8755
var defaultDate = this._getDefaultDate(inst);
8757
for (var row = 0; row < numMonths[0]; row++) {
8760
for (var col = 0; col < numMonths[1]; col++) {
8761
var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
8762
var cornerClass = ' ui-corner-all';
8765
calender += '<div class="ui-datepicker-group';
8766
if (numMonths[1] > 1)
8768
case 0: calender += ' ui-datepicker-group-first';
8769
cornerClass = ' ui-corner-' + (isRTL ? 'right' : 'left'); break;
8770
case numMonths[1]-1: calender += ' ui-datepicker-group-last';
8771
cornerClass = ' ui-corner-' + (isRTL ? 'left' : 'right'); break;
8772
default: calender += ' ui-datepicker-group-middle'; cornerClass = ''; break;
8776
calender += '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass + '">' +
8777
(/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') +
8778
(/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') +
8779
this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
8780
row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
8781
'</div><table class="ui-datepicker-calendar"><thead>' +
8783
var thead = (showWeek ? '<th class="ui-datepicker-week-col">' + this._get(inst, 'weekHeader') + '</th>' : '');
8784
for (var dow = 0; dow < 7; dow++) { // days of the week
8785
var day = (dow + firstDay) % 7;
8786
thead += '<th' + ((dow + firstDay + 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
8787
'<span title="' + dayNames[day] + '">' + dayNamesMin[day] + '</span></th>';
8789
calender += thead + '</tr></thead><tbody>';
8790
var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
8791
if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth)
8792
inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
8793
var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
8794
var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
8795
var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
8796
this.maxRows = numRows;
8797
var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
8798
for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
8800
var tbody = (!showWeek ? '' : '<td class="ui-datepicker-week-col">' +
8801
this._get(inst, 'calculateWeek')(printDate) + '</td>');
8802
for (var dow = 0; dow < 7; dow++) { // create date picker days
8803
var daySettings = (beforeShowDay ?
8804
beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
8805
var otherMonth = (printDate.getMonth() != drawMonth);
8806
var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
8807
(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
8808
tbody += '<td class="' +
8809
((dow + firstDay + 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
8810
(otherMonth ? ' ui-datepicker-other-month' : '') + // highlight days from other months
8811
((printDate.getTime() == selectedDate.getTime() && drawMonth == inst.selectedMonth && inst._keyEvent) || // user pressed key
8812
(defaultDate.getTime() == printDate.getTime() && defaultDate.getTime() == selectedDate.getTime()) ?
8813
// or defaultDate is current printedDate and defaultDate is selectedDate
8814
' ' + this._dayOverClass : '') + // highlight selected day
8815
(unselectable ? ' ' + this._unselectableClass + ' ui-state-disabled': '') + // highlight unselectable days
8816
(otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
8817
(printDate.getTime() == currentDate.getTime() ? ' ' + this._currentClass : '') + // highlight selected day
8818
(printDate.getTime() == today.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
8819
((!otherMonth || showOtherMonths) && daySettings[2] ? ' title="' + daySettings[2] + '"' : '') + // cell title
8820
(unselectable ? '' : ' onclick="DP_jQuery_' + dpuuid + '.datepicker._selectDay(\'#' +
8821
inst.id + '\',' + printDate.getMonth() + ',' + printDate.getFullYear() + ', this);return false;"') + '>' + // actions
8822
(otherMonth && !showOtherMonths ? ' ' : // display for other months
8823
(unselectable ? '<span class="ui-state-default">' + printDate.getDate() + '</span>' : '<a class="ui-state-default' +
8824
(printDate.getTime() == today.getTime() ? ' ui-state-highlight' : '') +
8825
(printDate.getTime() == currentDate.getTime() ? ' ui-state-active' : '') + // highlight selected day
8826
(otherMonth ? ' ui-priority-secondary' : '') + // distinguish dates from other months
8827
'" href="#">' + printDate.getDate() + '</a>')) + '</td>'; // display selectable date
8828
printDate.setDate(printDate.getDate() + 1);
8829
printDate = this._daylightSavingAdjust(printDate);
8831
calender += tbody + '</tr>';
8834
if (drawMonth > 11) {
8838
calender += '</tbody></table>' + (isMultiMonth ? '</div>' +
8839
((numMonths[0] > 0 && col == numMonths[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
8844
html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ?
8845
'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
8846
inst._keyEvent = false;
8850
/* Generate the month and year header. */
8851
_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
8852
secondary, monthNames, monthNamesShort) {
8853
var changeMonth = this._get(inst, 'changeMonth');
8854
var changeYear = this._get(inst, 'changeYear');
8855
var showMonthAfterYear = this._get(inst, 'showMonthAfterYear');
8856
var html = '<div class="ui-datepicker-title">';
8859
if (secondary || !changeMonth)
8860
monthHtml += '<span class="ui-datepicker-month">' + monthNames[drawMonth] + '</span>';
8862
var inMinYear = (minDate && minDate.getFullYear() == drawYear);
8863
var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
8864
monthHtml += '<select class="ui-datepicker-month" ' +
8865
'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'M\');" ' +
8867
for (var month = 0; month < 12; month++) {
8868
if ((!inMinYear || month >= minDate.getMonth()) &&
8869
(!inMaxYear || month <= maxDate.getMonth()))
8870
monthHtml += '<option value="' + month + '"' +
8871
(month == drawMonth ? ' selected="selected"' : '') +
8872
'>' + monthNamesShort[month] + '</option>';
8874
monthHtml += '</select>';
8876
if (!showMonthAfterYear)
8877
html += monthHtml + (secondary || !(changeMonth && changeYear) ? ' ' : '');
8879
if ( !inst.yearshtml ) {
8880
inst.yearshtml = '';
8881
if (secondary || !changeYear)
8882
html += '<span class="ui-datepicker-year">' + drawYear + '</span>';
8884
// determine range of years to display
8885
var years = this._get(inst, 'yearRange').split(':');
8886
var thisYear = new Date().getFullYear();
8887
var determineYear = function(value) {
8888
var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) :
8889
(value.match(/[+-].*/) ? thisYear + parseInt(value, 10) :
8890
parseInt(value, 10)));
8891
return (isNaN(year) ? thisYear : year);
8893
var year = determineYear(years[0]);
8894
var endYear = Math.max(year, determineYear(years[1] || ''));
8895
year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
8896
endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
8897
inst.yearshtml += '<select class="ui-datepicker-year" ' +
8898
'onchange="DP_jQuery_' + dpuuid + '.datepicker._selectMonthYear(\'#' + inst.id + '\', this, \'Y\');" ' +
8900
for (; year <= endYear; year++) {
8901
inst.yearshtml += '<option value="' + year + '"' +
8902
(year == drawYear ? ' selected="selected"' : '') +
8903
'>' + year + '</option>';
8905
inst.yearshtml += '</select>';
8907
html += inst.yearshtml;
8908
inst.yearshtml = null;
8911
html += this._get(inst, 'yearSuffix');
8912
if (showMonthAfterYear)
8913
html += (secondary || !(changeMonth && changeYear) ? ' ' : '') + monthHtml;
8914
html += '</div>'; // Close datepicker_header
8918
/* Adjust one of the date sub-fields. */
8919
_adjustInstDate: function(inst, offset, period) {
8920
var year = inst.drawYear + (period == 'Y' ? offset : 0);
8921
var month = inst.drawMonth + (period == 'M' ? offset : 0);
8922
var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) +
8923
(period == 'D' ? offset : 0);
8924
var date = this._restrictMinMax(inst,
8925
this._daylightSavingAdjust(new Date(year, month, day)));
8926
inst.selectedDay = date.getDate();
8927
inst.drawMonth = inst.selectedMonth = date.getMonth();
8928
inst.drawYear = inst.selectedYear = date.getFullYear();
8929
if (period == 'M' || period == 'Y')
8930
this._notifyChange(inst);
8933
/* Ensure a date is within any min/max bounds. */
8934
_restrictMinMax: function(inst, date) {
8935
var minDate = this._getMinMaxDate(inst, 'min');
8936
var maxDate = this._getMinMaxDate(inst, 'max');
8937
var newDate = (minDate && date < minDate ? minDate : date);
8938
newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
8942
/* Notify change of month/year. */
8943
_notifyChange: function(inst) {
8944
var onChange = this._get(inst, 'onChangeMonthYear');
8946
onChange.apply((inst.input ? inst.input[0] : null),
8947
[inst.selectedYear, inst.selectedMonth + 1, inst]);
8950
/* Determine the number of months to show. */
8951
_getNumberOfMonths: function(inst) {
8952
var numMonths = this._get(inst, 'numberOfMonths');
8953
return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
8956
/* Determine the current maximum date - ensure no time components are set. */
8957
_getMinMaxDate: function(inst, minMax) {
8958
return this._determineDate(inst, this._get(inst, minMax + 'Date'), null);
8961
/* Find the number of days in a given month. */
8962
_getDaysInMonth: function(year, month) {
8963
return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
8966
/* Find the day of the week of the first of a month. */
8967
_getFirstDayOfMonth: function(year, month) {
8968
return new Date(year, month, 1).getDay();
8971
/* Determines if we should allow a "next/prev" month display change. */
8972
_canAdjustMonth: function(inst, offset, curYear, curMonth) {
8973
var numMonths = this._getNumberOfMonths(inst);
8974
var date = this._daylightSavingAdjust(new Date(curYear,
8975
curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
8977
date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
8978
return this._isInRange(inst, date);
8981
/* Is the given date in the accepted range? */
8982
_isInRange: function(inst, date) {
8983
var minDate = this._getMinMaxDate(inst, 'min');
8984
var maxDate = this._getMinMaxDate(inst, 'max');
8985
return ((!minDate || date.getTime() >= minDate.getTime()) &&
8986
(!maxDate || date.getTime() <= maxDate.getTime()));
8989
/* Provide the configuration settings for formatting/parsing. */
8990
_getFormatConfig: function(inst) {
8991
var shortYearCutoff = this._get(inst, 'shortYearCutoff');
8992
shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
8993
new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
8994
return {shortYearCutoff: shortYearCutoff,
8995
dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
8996
monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
8999
/* Format the given date for display. */
9000
_formatDate: function(inst, day, month, year) {
9002
inst.currentDay = inst.selectedDay;
9003
inst.currentMonth = inst.selectedMonth;
9004
inst.currentYear = inst.selectedYear;
9006
var date = (day ? (typeof day == 'object' ? day :
9007
this._daylightSavingAdjust(new Date(year, month, day))) :
9008
this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9009
return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst));
9014
* Bind hover events for datepicker elements.
9015
* Done via delegate so the binding only occurs once in the lifetime of the parent div.
9016
* Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9018
function bindHover(dpDiv) {
9019
var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
9020
return dpDiv.bind('mouseout', function(event) {
9021
var elem = $( event.target ).closest( selector );
9022
if ( !elem.length ) {
9025
elem.removeClass( "ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover" );
9027
.bind('mouseover', function(event) {
9028
var elem = $( event.target ).closest( selector );
9029
if ($.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0]) ||
9033
elem.parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
9034
elem.addClass('ui-state-hover');
9035
if (elem.hasClass('ui-datepicker-prev')) elem.addClass('ui-datepicker-prev-hover');
9036
if (elem.hasClass('ui-datepicker-next')) elem.addClass('ui-datepicker-next-hover');
9040
/* jQuery extend now ignores nulls! */
9041
function extendRemove(target, props) {
9042
$.extend(target, props);
9043
for (var name in props)
9044
if (props[name] == null || props[name] == undefined)
9045
target[name] = props[name];
9049
/* Determine whether an object is an array. */
9050
function isArray(a) {
9051
return (a && (($.browser.safari && typeof a == 'object' && a.length) ||
9052
(a.constructor && a.constructor.toString().match(/\Array\(\)/))));
9055
/* Invoke the datepicker functionality.
9056
@param options string - a command, optionally followed by additional parameters or
9057
Object - settings for attaching new datepicker functionality
9058
@return jQuery object */
9059
$.fn.datepicker = function(options){
9061
/* Verify an empty collection wasn't passed - Fixes #6976 */
9062
if ( !this.length ) {
9066
/* Initialise the date picker. */
9067
if (!$.datepicker.initialized) {
9068
$(document).mousedown($.datepicker._checkExternalClick).
9069
find('body').append($.datepicker.dpDiv);
9070
$.datepicker.initialized = true;
9073
var otherArgs = Array.prototype.slice.call(arguments, 1);
9074
if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget'))
9075
return $.datepicker['_' + options + 'Datepicker'].
9076
apply($.datepicker, [this[0]].concat(otherArgs));
9077
if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string')
9078
return $.datepicker['_' + options + 'Datepicker'].
9079
apply($.datepicker, [this[0]].concat(otherArgs));
9080
return this.each(function() {
9081
typeof options == 'string' ?
9082
$.datepicker['_' + options + 'Datepicker'].
9083
apply($.datepicker, [this].concat(otherArgs)) :
9084
$.datepicker._attachDatepicker(this, options);
9088
$.datepicker = new Datepicker(); // singleton instance
9089
$.datepicker.initialized = false;
9090
$.datepicker.uuid = new Date().getTime();
9091
$.datepicker.version = "1.8.18";
9093
// Workaround for #4055
9094
// Add another global to avoid noConflict issues with inline event handlers
9095
window['DP_jQuery_' + dpuuid] = $;
9099
* jQuery UI Dialog 1.8.18
9101
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
9102
* Dual licensed under the MIT or GPL Version 2 licenses.
9103
* http://jquery.org/license
9105
* http://docs.jquery.com/UI/Dialog
9109
* jquery.ui.widget.js
9110
* jquery.ui.button.js
9111
* jquery.ui.draggable.js
9112
* jquery.ui.mouse.js
9113
* jquery.ui.position.js
9114
* jquery.ui.resizable.js
9116
(function( $, undefined ) {
9118
var uiDialogClasses =
9121
'ui-widget-content ' +
9123
sizeRelatedOptions = {
9132
resizableRelatedOptions = {
9138
// support for jQuery 1.3.2 - handle common attrFn methods for dialog
9139
attrFn = $.attrFn || {
9151
$.widget("ui.dialog", {
9155
closeOnEscape: true,
9170
// ensure that the titlebar is never outside the document
9171
using: function(pos) {
9172
var topOffset = $(this).css(pos).offset().top;
9173
if (topOffset < 0) {
9174
$(this).css('top', pos.top - topOffset);
9186
_create: function() {
9187
this.originalTitle = this.element.attr('title');
9188
// #5742 - .attr() might return a DOMElement
9189
if ( typeof this.originalTitle !== "string" ) {
9190
this.originalTitle = "";
9193
this.options.title = this.options.title || this.originalTitle;
9195
options = self.options,
9197
title = options.title || ' ',
9198
titleId = $.ui.dialog.getTitleId(self.element),
9200
uiDialog = (self.uiDialog = $('<div></div>'))
9201
.appendTo(document.body)
9203
.addClass(uiDialogClasses + options.dialogClass)
9205
zIndex: options.zIndex
9207
// setting tabIndex makes the div focusable
9208
// setting outline to 0 prevents a border on focus in Mozilla
9209
.attr('tabIndex', -1).css('outline', 0).keydown(function(event) {
9210
if (options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9211
event.keyCode === $.ui.keyCode.ESCAPE) {
9214
event.preventDefault();
9219
'aria-labelledby': titleId
9221
.mousedown(function(event) {
9222
self.moveToTop(false, event);
9225
uiDialogContent = self.element
9227
.removeAttr('title')
9229
'ui-dialog-content ' +
9230
'ui-widget-content')
9231
.appendTo(uiDialog),
9233
uiDialogTitlebar = (self.uiDialogTitlebar = $('<div></div>'))
9235
'ui-dialog-titlebar ' +
9236
'ui-widget-header ' +
9238
'ui-helper-clearfix'
9240
.prependTo(uiDialog),
9242
uiDialogTitlebarClose = $('<a href="#"></a>')
9244
'ui-dialog-titlebar-close ' +
9247
.attr('role', 'button')
9250
uiDialogTitlebarClose.addClass('ui-state-hover');
9253
uiDialogTitlebarClose.removeClass('ui-state-hover');
9257
uiDialogTitlebarClose.addClass('ui-state-focus');
9260
uiDialogTitlebarClose.removeClass('ui-state-focus');
9262
.click(function(event) {
9266
.appendTo(uiDialogTitlebar),
9268
uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('<span></span>'))
9271
'ui-icon-closethick'
9273
.text(options.closeText)
9274
.appendTo(uiDialogTitlebarClose),
9276
uiDialogTitle = $('<span></span>')
9277
.addClass('ui-dialog-title')
9278
.attr('id', titleId)
9280
.prependTo(uiDialogTitlebar);
9282
//handling of deprecated beforeclose (vs beforeClose) option
9283
//Ticket #4669 http://dev.jqueryui.com/ticket/4669
9284
//TODO: remove in 1.9pre
9285
if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) {
9286
options.beforeClose = options.beforeclose;
9289
uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
9291
if (options.draggable && $.fn.draggable) {
9292
self._makeDraggable();
9294
if (options.resizable && $.fn.resizable) {
9295
self._makeResizable();
9298
self._createButtons(options.buttons);
9299
self._isOpen = false;
9301
if ($.fn.bgiframe) {
9302
uiDialog.bgiframe();
9307
if ( this.options.autoOpen ) {
9312
destroy: function() {
9316
self.overlay.destroy();
9318
self.uiDialog.hide();
9321
.removeData('dialog')
9322
.removeClass('ui-dialog-content ui-widget-content')
9323
.hide().appendTo('body');
9324
self.uiDialog.remove();
9326
if (self.originalTitle) {
9327
self.element.attr('title', self.originalTitle);
9333
widget: function() {
9334
return this.uiDialog;
9337
close: function(event) {
9341
if (false === self._trigger('beforeClose', event)) {
9346
self.overlay.destroy();
9348
self.uiDialog.unbind('keypress.ui-dialog');
9350
self._isOpen = false;
9352
if (self.options.hide) {
9353
self.uiDialog.hide(self.options.hide, function() {
9354
self._trigger('close', event);
9357
self.uiDialog.hide();
9358
self._trigger('close', event);
9361
$.ui.dialog.overlay.resize();
9363
// adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
9364
if (self.options.modal) {
9366
$('.ui-dialog').each(function() {
9367
if (this !== self.uiDialog[0]) {
9368
thisZ = $(this).css('z-index');
9370
maxZ = Math.max(maxZ, thisZ);
9374
$.ui.dialog.maxZ = maxZ;
9380
isOpen: function() {
9381
return this._isOpen;
9384
// the force parameter allows us to move modal dialogs to their correct
9386
moveToTop: function(force, event) {
9388
options = self.options,
9391
if ((options.modal && !force) ||
9392
(!options.stack && !options.modal)) {
9393
return self._trigger('focus', event);
9396
if (options.zIndex > $.ui.dialog.maxZ) {
9397
$.ui.dialog.maxZ = options.zIndex;
9400
$.ui.dialog.maxZ += 1;
9401
self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ);
9404
//Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
9405
// http://ui.jquery.com/bugs/ticket/3193
9406
saveScroll = { scrollTop: self.element.scrollTop(), scrollLeft: self.element.scrollLeft() };
9407
$.ui.dialog.maxZ += 1;
9408
self.uiDialog.css('z-index', $.ui.dialog.maxZ);
9409
self.element.attr(saveScroll);
9410
self._trigger('focus', event);
9416
if (this._isOpen) { return; }
9419
options = self.options,
9420
uiDialog = self.uiDialog;
9422
self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null;
9424
self._position(options.position);
9425
uiDialog.show(options.show);
9426
self.moveToTop(true);
9428
// prevent tabbing out of modal dialogs
9429
if ( options.modal ) {
9430
uiDialog.bind( "keydown.ui-dialog", function( event ) {
9431
if ( event.keyCode !== $.ui.keyCode.TAB ) {
9435
var tabbables = $(':tabbable', this),
9436
first = tabbables.filter(':first'),
9437
last = tabbables.filter(':last');
9439
if (event.target === last[0] && !event.shiftKey) {
9442
} else if (event.target === first[0] && event.shiftKey) {
9449
// set focus to the first tabbable element in the content area or the first button
9450
// if there are no tabbable elements, set focus on the dialog itself
9451
$(self.element.find(':tabbable').get().concat(
9452
uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
9453
uiDialog.get()))).eq(0).focus();
9455
self._isOpen = true;
9456
self._trigger('open');
9461
_createButtons: function(buttons) {
9464
uiDialogButtonPane = $('<div></div>')
9466
'ui-dialog-buttonpane ' +
9467
'ui-widget-content ' +
9468
'ui-helper-clearfix'
9470
uiButtonSet = $( "<div></div>" )
9471
.addClass( "ui-dialog-buttonset" )
9472
.appendTo( uiDialogButtonPane );
9474
// if we already have a button pane, remove it
9475
self.uiDialog.find('.ui-dialog-buttonpane').remove();
9477
if (typeof buttons === 'object' && buttons !== null) {
9478
$.each(buttons, function() {
9479
return !(hasButtons = true);
9483
$.each(buttons, function(name, props) {
9484
props = $.isFunction( props ) ?
9485
{ click: props, text: name } :
9487
var button = $('<button type="button"></button>')
9489
props.click.apply(self.element[0], arguments);
9491
.appendTo(uiButtonSet);
9492
// can't use .attr( props, true ) with jQuery 1.3.2.
9493
$.each( props, function( key, value ) {
9494
if ( key === "click" ) {
9497
if ( key in attrFn ) {
9498
button[ key ]( value );
9500
button.attr( key, value );
9507
uiDialogButtonPane.appendTo(self.uiDialog);
9511
_makeDraggable: function() {
9513
options = self.options,
9517
function filteredUi(ui) {
9519
position: ui.position,
9524
self.uiDialog.draggable({
9525
cancel: '.ui-dialog-content, .ui-dialog-titlebar-close',
9526
handle: '.ui-dialog-titlebar',
9527
containment: 'document',
9528
start: function(event, ui) {
9529
heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height();
9530
$(this).height($(this).height()).addClass("ui-dialog-dragging");
9531
self._trigger('dragStart', event, filteredUi(ui));
9533
drag: function(event, ui) {
9534
self._trigger('drag', event, filteredUi(ui));
9536
stop: function(event, ui) {
9537
options.position = [ui.position.left - doc.scrollLeft(),
9538
ui.position.top - doc.scrollTop()];
9539
$(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag);
9540
self._trigger('dragStop', event, filteredUi(ui));
9541
$.ui.dialog.overlay.resize();
9546
_makeResizable: function(handles) {
9547
handles = (handles === undefined ? this.options.resizable : handles);
9549
options = self.options,
9550
// .ui-resizable has position: relative defined in the stylesheet
9551
// but dialogs have to use absolute or fixed positioning
9552
position = self.uiDialog.css('position'),
9553
resizeHandles = (typeof handles === 'string' ?
9555
'n,e,s,w,se,sw,ne,nw'
9558
function filteredUi(ui) {
9560
originalPosition: ui.originalPosition,
9561
originalSize: ui.originalSize,
9562
position: ui.position,
9567
self.uiDialog.resizable({
9568
cancel: '.ui-dialog-content',
9569
containment: 'document',
9570
alsoResize: self.element,
9571
maxWidth: options.maxWidth,
9572
maxHeight: options.maxHeight,
9573
minWidth: options.minWidth,
9574
minHeight: self._minHeight(),
9575
handles: resizeHandles,
9576
start: function(event, ui) {
9577
$(this).addClass("ui-dialog-resizing");
9578
self._trigger('resizeStart', event, filteredUi(ui));
9580
resize: function(event, ui) {
9581
self._trigger('resize', event, filteredUi(ui));
9583
stop: function(event, ui) {
9584
$(this).removeClass("ui-dialog-resizing");
9585
options.height = $(this).height();
9586
options.width = $(this).width();
9587
self._trigger('resizeStop', event, filteredUi(ui));
9588
$.ui.dialog.overlay.resize();
9591
.css('position', position)
9592
.find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
9595
_minHeight: function() {
9596
var options = this.options;
9598
if (options.height === 'auto') {
9599
return options.minHeight;
9601
return Math.min(options.minHeight, options.height);
9605
_position: function(position) {
9611
// deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
9612
// if (typeof position == 'string' || $.isArray(position)) {
9613
// myAt = $.isArray(position) ? position : position.split(' ');
9615
if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) {
9616
myAt = position.split ? position.split(' ') : [position[0], position[1]];
9617
if (myAt.length === 1) {
9621
$.each(['left', 'top'], function(i, offsetPosition) {
9622
if (+myAt[i] === myAt[i]) {
9623
offset[i] = myAt[i];
9624
myAt[i] = offsetPosition;
9631
offset: offset.join(" ")
9635
position = $.extend({}, $.ui.dialog.prototype.options.position, position);
9637
position = $.ui.dialog.prototype.options.position;
9640
// need to show the dialog to get the actual offset in the position plugin
9641
isVisible = this.uiDialog.is(':visible');
9643
this.uiDialog.show();
9646
// workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
9647
.css({ top: 0, left: 0 })
9648
.position($.extend({ of: window }, position));
9650
this.uiDialog.hide();
9654
_setOptions: function( options ) {
9656
resizableOptions = {},
9659
$.each( options, function( key, value ) {
9660
self._setOption( key, value );
9662
if ( key in sizeRelatedOptions ) {
9665
if ( key in resizableRelatedOptions ) {
9666
resizableOptions[ key ] = value;
9673
if ( this.uiDialog.is( ":data(resizable)" ) ) {
9674
this.uiDialog.resizable( "option", resizableOptions );
9678
_setOption: function(key, value){
9680
uiDialog = self.uiDialog;
9683
//handling of deprecated beforeclose (vs beforeClose) option
9684
//Ticket #4669 http://dev.jqueryui.com/ticket/4669
9685
//TODO: remove in 1.9pre
9687
key = "beforeClose";
9690
self._createButtons(value);
9693
// ensure that we always pass a string
9694
self.uiDialogTitlebarCloseText.text("" + value);
9698
.removeClass(self.options.dialogClass)
9699
.addClass(uiDialogClasses + value);
9703
uiDialog.addClass('ui-dialog-disabled');
9705
uiDialog.removeClass('ui-dialog-disabled');
9709
var isDraggable = uiDialog.is( ":data(draggable)" );
9710
if ( isDraggable && !value ) {
9711
uiDialog.draggable( "destroy" );
9714
if ( !isDraggable && value ) {
9715
self._makeDraggable();
9719
self._position(value);
9722
// currently resizable, becoming non-resizable
9723
var isResizable = uiDialog.is( ":data(resizable)" );
9724
if (isResizable && !value) {
9725
uiDialog.resizable('destroy');
9728
// currently resizable, changing handles
9729
if (isResizable && typeof value === 'string') {
9730
uiDialog.resizable('option', 'handles', value);
9733
// currently non-resizable, becoming resizable
9734
if (!isResizable && value !== false) {
9735
self._makeResizable(value);
9739
// convert whatever was passed in o a string, for html() to not throw up
9740
$(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || ' '));
9744
$.Widget.prototype._setOption.apply(self, arguments);
9748
/* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
9749
* divs will both have width and height set, so we need to reset them
9751
var options = this.options,
9754
isVisible = this.uiDialog.is( ":visible" );
9756
// reset content sizing
9757
this.element.show().css({
9763
if (options.minWidth > options.width) {
9764
options.width = options.minWidth;
9767
// reset wrapper sizing
9768
// determine the height of all the non-content elements
9769
nonContentHeight = this.uiDialog.css({
9771
width: options.width
9774
minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
9776
if ( options.height === "auto" ) {
9777
// only needed for IE6 support
9778
if ( $.support.minHeight ) {
9780
minHeight: minContentHeight,
9784
this.uiDialog.show();
9785
var autoHeight = this.element.css( "height", "auto" ).height();
9787
this.uiDialog.hide();
9789
this.element.height( Math.max( autoHeight, minContentHeight ) );
9792
this.element.height( Math.max( options.height - nonContentHeight, 0 ) );
9795
if (this.uiDialog.is(':data(resizable)')) {
9796
this.uiDialog.resizable('option', 'minHeight', this._minHeight());
9801
$.extend($.ui.dialog, {
9807
getTitleId: function($el) {
9808
var id = $el.attr('id');
9813
return 'ui-dialog-title-' + id;
9816
overlay: function(dialog) {
9817
this.$el = $.ui.dialog.overlay.create(dialog);
9821
$.extend($.ui.dialog.overlay, {
9823
// reuse old instances due to IE memory leak with alpha transparency (see #5185)
9826
events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
9827
function(event) { return event + '.dialog-overlay'; }).join(' '),
9828
create: function(dialog) {
9829
if (this.instances.length === 0) {
9830
// prevent use of anchors and inputs
9831
// we use a setTimeout in case the overlay is created from an
9832
// event that we're going to be cancelling (see #2804)
9833
setTimeout(function() {
9834
// handle $(el).dialog().dialog('close') (see #4065)
9835
if ($.ui.dialog.overlay.instances.length) {
9836
$(document).bind($.ui.dialog.overlay.events, function(event) {
9837
// stop events if the z-index of the target is < the z-index of the overlay
9838
// we cannot return true when we don't want to cancel the event (#3523)
9839
if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) {
9846
// allow closing by pressing the escape key
9847
$(document).bind('keydown.dialog-overlay', function(event) {
9848
if (dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9849
event.keyCode === $.ui.keyCode.ESCAPE) {
9851
dialog.close(event);
9852
event.preventDefault();
9856
// handle window resize
9857
$(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize);
9860
var $el = (this.oldInstances.pop() || $('<div></div>').addClass('ui-widget-overlay'))
9861
.appendTo(document.body)
9863
width: this.width(),
9864
height: this.height()
9867
if ($.fn.bgiframe) {
9871
this.instances.push($el);
9875
destroy: function($el) {
9876
var indexOf = $.inArray($el, this.instances);
9878
this.oldInstances.push(this.instances.splice(indexOf, 1)[0]);
9881
if (this.instances.length === 0) {
9882
$([document, window]).unbind('.dialog-overlay');
9887
// adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
9889
$.each(this.instances, function() {
9890
maxZ = Math.max(maxZ, this.css('z-index'));
9895
height: function() {
9899
if ($.browser.msie && $.browser.version < 7) {
9900
scrollHeight = Math.max(
9901
document.documentElement.scrollHeight,
9902
document.body.scrollHeight
9904
offsetHeight = Math.max(
9905
document.documentElement.offsetHeight,
9906
document.body.offsetHeight
9909
if (scrollHeight < offsetHeight) {
9910
return $(window).height() + 'px';
9912
return scrollHeight + 'px';
9914
// handle "good" browsers
9916
return $(document).height() + 'px';
9924
if ( $.browser.msie ) {
9925
scrollWidth = Math.max(
9926
document.documentElement.scrollWidth,
9927
document.body.scrollWidth
9929
offsetWidth = Math.max(
9930
document.documentElement.offsetWidth,
9931
document.body.offsetWidth
9934
if (scrollWidth < offsetWidth) {
9935
return $(window).width() + 'px';
9937
return scrollWidth + 'px';
9939
// handle "good" browsers
9941
return $(document).width() + 'px';
9945
resize: function() {
9946
/* If the dialog is draggable and the user drags it past the
9947
* right edge of the window, the document becomes wider so we
9948
* need to stretch the overlay. If the user then drags the
9949
* dialog back to the left, the document will become narrower,
9950
* so we need to shrink the overlay to the appropriate size.
9951
* This is handled by shrinking the overlay before setting it
9952
* to the full document size.
9954
var $overlays = $([]);
9955
$.each($.ui.dialog.overlay.instances, function() {
9956
$overlays = $overlays.add(this);
9963
width: $.ui.dialog.overlay.width(),
9964
height: $.ui.dialog.overlay.height()
9969
$.extend($.ui.dialog.overlay.prototype, {
9970
destroy: function() {
9971
$.ui.dialog.overlay.destroy(this.$el);
9977
* jQuery UI Position 1.8.18
9979
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
9980
* Dual licensed under the MIT or GPL Version 2 licenses.
9981
* http://jquery.org/license
9983
* http://docs.jquery.com/UI/Position
9985
(function( $, undefined ) {
9989
var horizontalPositions = /left|center|right/,
9990
verticalPositions = /top|center|bottom/,
9993
_position = $.fn.position,
9994
_offset = $.fn.offset;
9996
$.fn.position = function( options ) {
9997
if ( !options || !options.of ) {
9998
return _position.apply( this, arguments );
10001
// make a copy, we don't want to modify arguments
10002
options = $.extend( {}, options );
10004
var target = $( options.of ),
10005
targetElem = target[0],
10006
collision = ( options.collision || "flip" ).split( " " ),
10007
offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ],
10012
if ( targetElem.nodeType === 9 ) {
10013
targetWidth = target.width();
10014
targetHeight = target.height();
10015
basePosition = { top: 0, left: 0 };
10016
// TODO: use $.isWindow() in 1.9
10017
} else if ( targetElem.setTimeout ) {
10018
targetWidth = target.width();
10019
targetHeight = target.height();
10020
basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
10021
} else if ( targetElem.preventDefault ) {
10022
// force left top to allow flipping
10023
options.at = "left top";
10024
targetWidth = targetHeight = 0;
10025
basePosition = { top: options.of.pageY, left: options.of.pageX };
10027
targetWidth = target.outerWidth();
10028
targetHeight = target.outerHeight();
10029
basePosition = target.offset();
10032
// force my and at to have valid horizontal and veritcal positions
10033
// if a value is missing or invalid, it will be converted to center
10034
$.each( [ "my", "at" ], function() {
10035
var pos = ( options[this] || "" ).split( " " );
10036
if ( pos.length === 1) {
10037
pos = horizontalPositions.test( pos[0] ) ?
10038
pos.concat( [center] ) :
10039
verticalPositions.test( pos[0] ) ?
10040
[ center ].concat( pos ) :
10041
[ center, center ];
10043
pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center;
10044
pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center;
10045
options[ this ] = pos;
10048
// normalize collision option
10049
if ( collision.length === 1 ) {
10050
collision[ 1 ] = collision[ 0 ];
10053
// normalize offset option
10054
offset[ 0 ] = parseInt( offset[0], 10 ) || 0;
10055
if ( offset.length === 1 ) {
10056
offset[ 1 ] = offset[ 0 ];
10058
offset[ 1 ] = parseInt( offset[1], 10 ) || 0;
10060
if ( options.at[0] === "right" ) {
10061
basePosition.left += targetWidth;
10062
} else if ( options.at[0] === center ) {
10063
basePosition.left += targetWidth / 2;
10066
if ( options.at[1] === "bottom" ) {
10067
basePosition.top += targetHeight;
10068
} else if ( options.at[1] === center ) {
10069
basePosition.top += targetHeight / 2;
10072
basePosition.left += offset[ 0 ];
10073
basePosition.top += offset[ 1 ];
10075
return this.each(function() {
10076
var elem = $( this ),
10077
elemWidth = elem.outerWidth(),
10078
elemHeight = elem.outerHeight(),
10079
marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
10080
marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
10081
collisionWidth = elemWidth + marginLeft +
10082
( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
10083
collisionHeight = elemHeight + marginTop +
10084
( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
10085
position = $.extend( {}, basePosition ),
10088
if ( options.my[0] === "right" ) {
10089
position.left -= elemWidth;
10090
} else if ( options.my[0] === center ) {
10091
position.left -= elemWidth / 2;
10094
if ( options.my[1] === "bottom" ) {
10095
position.top -= elemHeight;
10096
} else if ( options.my[1] === center ) {
10097
position.top -= elemHeight / 2;
10100
// prevent fractions if jQuery version doesn't support them (see #5280)
10101
if ( !support.fractions ) {
10102
position.left = Math.round( position.left );
10103
position.top = Math.round( position.top );
10106
collisionPosition = {
10107
left: position.left - marginLeft,
10108
top: position.top - marginTop
10111
$.each( [ "left", "top" ], function( i, dir ) {
10112
if ( $.ui.position[ collision[i] ] ) {
10113
$.ui.position[ collision[i] ][ dir ]( position, {
10114
targetWidth: targetWidth,
10115
targetHeight: targetHeight,
10116
elemWidth: elemWidth,
10117
elemHeight: elemHeight,
10118
collisionPosition: collisionPosition,
10119
collisionWidth: collisionWidth,
10120
collisionHeight: collisionHeight,
10128
if ( $.fn.bgiframe ) {
10131
elem.offset( $.extend( position, { using: options.using } ) );
10137
left: function( position, data ) {
10138
var win = $( window ),
10139
over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft();
10140
position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left );
10142
top: function( position, data ) {
10143
var win = $( window ),
10144
over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop();
10145
position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top );
10150
left: function( position, data ) {
10151
if ( data.at[0] === center ) {
10154
var win = $( window ),
10155
over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(),
10156
myOffset = data.my[ 0 ] === "left" ?
10158
data.my[ 0 ] === "right" ?
10161
atOffset = data.at[ 0 ] === "left" ?
10164
offset = -2 * data.offset[ 0 ];
10165
position.left += data.collisionPosition.left < 0 ?
10166
myOffset + atOffset + offset :
10168
myOffset + atOffset + offset :
10171
top: function( position, data ) {
10172
if ( data.at[1] === center ) {
10175
var win = $( window ),
10176
over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(),
10177
myOffset = data.my[ 1 ] === "top" ?
10179
data.my[ 1 ] === "bottom" ?
10182
atOffset = data.at[ 1 ] === "top" ?
10183
data.targetHeight :
10184
-data.targetHeight,
10185
offset = -2 * data.offset[ 1 ];
10186
position.top += data.collisionPosition.top < 0 ?
10187
myOffset + atOffset + offset :
10189
myOffset + atOffset + offset :
10195
// offset setter from jQuery 1.4
10196
if ( !$.offset.setOffset ) {
10197
$.offset.setOffset = function( elem, options ) {
10198
// set position first, in-case top/left are set even on static elem
10199
if ( /static/.test( $.curCSS( elem, "position" ) ) ) {
10200
elem.style.position = "relative";
10202
var curElem = $( elem ),
10203
curOffset = curElem.offset(),
10204
curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0,
10205
curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0,
10207
top: (options.top - curOffset.top) + curTop,
10208
left: (options.left - curOffset.left) + curLeft
10211
if ( 'using' in options ) {
10212
options.using.call( elem, props );
10214
curElem.css( props );
10218
$.fn.offset = function( options ) {
10219
var elem = this[ 0 ];
10220
if ( !elem || !elem.ownerDocument ) { return null; }
10222
return this.each(function() {
10223
$.offset.setOffset( this, options );
10226
return _offset.call( this );
10230
// fraction support test (older versions of jQuery don't support fractions)
10232
var body = document.getElementsByTagName( "body" )[ 0 ],
10233
div = document.createElement( "div" ),
10234
testElement, testElementParent, testElementStyle, offset, offsetTotal;
10236
//Create a "fake body" for testing based on method used in jQuery.support
10237
testElement = document.createElement( body ? "div" : "body" );
10238
testElementStyle = {
10239
visibility: "hidden",
10247
$.extend( testElementStyle, {
10248
position: "absolute",
10253
for ( var i in testElementStyle ) {
10254
testElement.style[ i ] = testElementStyle[ i ];
10256
testElement.appendChild( div );
10257
testElementParent = body || document.documentElement;
10258
testElementParent.insertBefore( testElement, testElementParent.firstChild );
10260
div.style.cssText = "position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;";
10262
offset = $( div ).offset( function( _, offset ) {
10266
testElement.innerHTML = "";
10267
testElementParent.removeChild( testElement );
10269
offsetTotal = offset.top + offset.left + ( body ? 2000 : 0 );
10270
support.fractions = offsetTotal > 21 && offsetTotal < 22;
10275
* jQuery UI Progressbar 1.8.18
10277
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10278
* Dual licensed under the MIT or GPL Version 2 licenses.
10279
* http://jquery.org/license
10281
* http://docs.jquery.com/UI/Progressbar
10284
* jquery.ui.core.js
10285
* jquery.ui.widget.js
10287
(function( $, undefined ) {
10289
$.widget( "ui.progressbar", {
10297
_create: function() {
10299
.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10301
role: "progressbar",
10302
"aria-valuemin": this.min,
10303
"aria-valuemax": this.options.max,
10304
"aria-valuenow": this._value()
10307
this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
10308
.appendTo( this.element );
10310
this.oldValue = this._value();
10311
this._refreshValue();
10314
destroy: function() {
10316
.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10317
.removeAttr( "role" )
10318
.removeAttr( "aria-valuemin" )
10319
.removeAttr( "aria-valuemax" )
10320
.removeAttr( "aria-valuenow" );
10322
this.valueDiv.remove();
10324
$.Widget.prototype.destroy.apply( this, arguments );
10327
value: function( newValue ) {
10328
if ( newValue === undefined ) {
10329
return this._value();
10332
this._setOption( "value", newValue );
10336
_setOption: function( key, value ) {
10337
if ( key === "value" ) {
10338
this.options.value = value;
10339
this._refreshValue();
10340
if ( this._value() === this.options.max ) {
10341
this._trigger( "complete" );
10345
$.Widget.prototype._setOption.apply( this, arguments );
10348
_value: function() {
10349
var val = this.options.value;
10350
// normalize invalid value
10351
if ( typeof val !== "number" ) {
10354
return Math.min( this.options.max, Math.max( this.min, val ) );
10357
_percentage: function() {
10358
return 100 * this._value() / this.options.max;
10361
_refreshValue: function() {
10362
var value = this.value();
10363
var percentage = this._percentage();
10365
if ( this.oldValue !== value ) {
10366
this.oldValue = value;
10367
this._trigger( "change" );
10371
.toggle( value > this.min )
10372
.toggleClass( "ui-corner-right", value === this.options.max )
10373
.width( percentage.toFixed(0) + "%" );
10374
this.element.attr( "aria-valuenow", value );
10378
$.extend( $.ui.progressbar, {
10384
* jQuery UI Slider 1.8.18
10386
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
10387
* Dual licensed under the MIT or GPL Version 2 licenses.
10388
* http://jquery.org/license
10390
* http://docs.jquery.com/UI/Slider
10393
* jquery.ui.core.js
10394
* jquery.ui.mouse.js
10395
* jquery.ui.widget.js
10397
(function( $, undefined ) {
10399
// number of pages in a slider
10400
// (how many times can you page up/down to go through the whole range)
10403
$.widget( "ui.slider", $.ui.mouse, {
10405
widgetEventPrefix: "slide",
10412
orientation: "horizontal",
10419
_create: function() {
10422
existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
10423
handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
10424
handleCount = ( o.values && o.values.length ) || 1,
10427
this._keySliding = false;
10428
this._mouseSliding = false;
10429
this._animateOff = true;
10430
this._handleIndex = null;
10431
this._detectOrientation();
10435
.addClass( "ui-slider" +
10436
" ui-slider-" + this.orientation +
10438
" ui-widget-content" +
10440
( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) );
10442
this.range = $([]);
10445
if ( o.range === true ) {
10447
o.values = [ this._valueMin(), this._valueMin() ];
10449
if ( o.values.length && o.values.length !== 2 ) {
10450
o.values = [ o.values[0], o.values[0] ];
10454
this.range = $( "<div></div>" )
10455
.appendTo( this.element )
10456
.addClass( "ui-slider-range" +
10457
// note: this isn't the most fittingly semantic framework class for this element,
10458
// but worked best visually with a variety of themes
10459
" ui-widget-header" +
10460
( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
10463
for ( var i = existingHandles.length; i < handleCount; i += 1 ) {
10464
handles.push( handle );
10467
this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( self.element ) );
10469
this.handle = this.handles.eq( 0 );
10471
this.handles.add( this.range ).filter( "a" )
10472
.click(function( event ) {
10473
event.preventDefault();
10475
.hover(function() {
10476
if ( !o.disabled ) {
10477
$( this ).addClass( "ui-state-hover" );
10480
$( this ).removeClass( "ui-state-hover" );
10482
.focus(function() {
10483
if ( !o.disabled ) {
10484
$( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
10485
$( this ).addClass( "ui-state-focus" );
10491
$( this ).removeClass( "ui-state-focus" );
10494
this.handles.each(function( i ) {
10495
$( this ).data( "index.ui-slider-handle", i );
10499
.keydown(function( event ) {
10500
var index = $( this ).data( "index.ui-slider-handle" ),
10506
if ( self.options.disabled ) {
10510
switch ( event.keyCode ) {
10511
case $.ui.keyCode.HOME:
10512
case $.ui.keyCode.END:
10513
case $.ui.keyCode.PAGE_UP:
10514
case $.ui.keyCode.PAGE_DOWN:
10515
case $.ui.keyCode.UP:
10516
case $.ui.keyCode.RIGHT:
10517
case $.ui.keyCode.DOWN:
10518
case $.ui.keyCode.LEFT:
10519
event.preventDefault();
10520
if ( !self._keySliding ) {
10521
self._keySliding = true;
10522
$( this ).addClass( "ui-state-active" );
10523
allowed = self._start( event, index );
10524
if ( allowed === false ) {
10531
step = self.options.step;
10532
if ( self.options.values && self.options.values.length ) {
10533
curVal = newVal = self.values( index );
10535
curVal = newVal = self.value();
10538
switch ( event.keyCode ) {
10539
case $.ui.keyCode.HOME:
10540
newVal = self._valueMin();
10542
case $.ui.keyCode.END:
10543
newVal = self._valueMax();
10545
case $.ui.keyCode.PAGE_UP:
10546
newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) );
10548
case $.ui.keyCode.PAGE_DOWN:
10549
newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) );
10551
case $.ui.keyCode.UP:
10552
case $.ui.keyCode.RIGHT:
10553
if ( curVal === self._valueMax() ) {
10556
newVal = self._trimAlignValue( curVal + step );
10558
case $.ui.keyCode.DOWN:
10559
case $.ui.keyCode.LEFT:
10560
if ( curVal === self._valueMin() ) {
10563
newVal = self._trimAlignValue( curVal - step );
10567
self._slide( event, index, newVal );
10569
.keyup(function( event ) {
10570
var index = $( this ).data( "index.ui-slider-handle" );
10572
if ( self._keySliding ) {
10573
self._keySliding = false;
10574
self._stop( event, index );
10575
self._change( event, index );
10576
$( this ).removeClass( "ui-state-active" );
10581
this._refreshValue();
10583
this._animateOff = false;
10586
destroy: function() {
10587
this.handles.remove();
10588
this.range.remove();
10591
.removeClass( "ui-slider" +
10592
" ui-slider-horizontal" +
10593
" ui-slider-vertical" +
10594
" ui-slider-disabled" +
10596
" ui-widget-content" +
10598
.removeData( "slider" )
10599
.unbind( ".slider" );
10601
this._mouseDestroy();
10606
_mouseCapture: function( event ) {
10607
var o = this.options,
10618
if ( o.disabled ) {
10622
this.elementSize = {
10623
width: this.element.outerWidth(),
10624
height: this.element.outerHeight()
10626
this.elementOffset = this.element.offset();
10628
position = { x: event.pageX, y: event.pageY };
10629
normValue = this._normValueFromMouse( position );
10630
distance = this._valueMax() - this._valueMin() + 1;
10632
this.handles.each(function( i ) {
10633
var thisDistance = Math.abs( normValue - self.values(i) );
10634
if ( distance > thisDistance ) {
10635
distance = thisDistance;
10636
closestHandle = $( this );
10641
// workaround for bug #3736 (if both handles of a range are at 0,
10642
// the first is always used as the one with least distance,
10643
// and moving it is obviously prevented by preventing negative ranges)
10644
if( o.range === true && this.values(1) === o.min ) {
10646
closestHandle = $( this.handles[index] );
10649
allowed = this._start( event, index );
10650
if ( allowed === false ) {
10653
this._mouseSliding = true;
10655
self._handleIndex = index;
10658
.addClass( "ui-state-active" )
10661
offset = closestHandle.offset();
10662
mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" );
10663
this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
10664
left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
10665
top: event.pageY - offset.top -
10666
( closestHandle.height() / 2 ) -
10667
( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
10668
( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
10669
( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
10672
if ( !this.handles.hasClass( "ui-state-hover" ) ) {
10673
this._slide( event, index, normValue );
10675
this._animateOff = true;
10679
_mouseStart: function( event ) {
10683
_mouseDrag: function( event ) {
10684
var position = { x: event.pageX, y: event.pageY },
10685
normValue = this._normValueFromMouse( position );
10687
this._slide( event, this._handleIndex, normValue );
10692
_mouseStop: function( event ) {
10693
this.handles.removeClass( "ui-state-active" );
10694
this._mouseSliding = false;
10696
this._stop( event, this._handleIndex );
10697
this._change( event, this._handleIndex );
10699
this._handleIndex = null;
10700
this._clickOffset = null;
10701
this._animateOff = false;
10706
_detectOrientation: function() {
10707
this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
10710
_normValueFromMouse: function( position ) {
10717
if ( this.orientation === "horizontal" ) {
10718
pixelTotal = this.elementSize.width;
10719
pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
10721
pixelTotal = this.elementSize.height;
10722
pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
10725
percentMouse = ( pixelMouse / pixelTotal );
10726
if ( percentMouse > 1 ) {
10729
if ( percentMouse < 0 ) {
10732
if ( this.orientation === "vertical" ) {
10733
percentMouse = 1 - percentMouse;
10736
valueTotal = this._valueMax() - this._valueMin();
10737
valueMouse = this._valueMin() + percentMouse * valueTotal;
10739
return this._trimAlignValue( valueMouse );
10742
_start: function( event, index ) {
10744
handle: this.handles[ index ],
10745
value: this.value()
10747
if ( this.options.values && this.options.values.length ) {
10748
uiHash.value = this.values( index );
10749
uiHash.values = this.values();
10751
return this._trigger( "start", event, uiHash );
10754
_slide: function( event, index, newVal ) {
10759
if ( this.options.values && this.options.values.length ) {
10760
otherVal = this.values( index ? 0 : 1 );
10762
if ( ( this.options.values.length === 2 && this.options.range === true ) &&
10763
( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
10768
if ( newVal !== this.values( index ) ) {
10769
newValues = this.values();
10770
newValues[ index ] = newVal;
10771
// A slide can be canceled by returning false from the slide callback
10772
allowed = this._trigger( "slide", event, {
10773
handle: this.handles[ index ],
10777
otherVal = this.values( index ? 0 : 1 );
10778
if ( allowed !== false ) {
10779
this.values( index, newVal, true );
10783
if ( newVal !== this.value() ) {
10784
// A slide can be canceled by returning false from the slide callback
10785
allowed = this._trigger( "slide", event, {
10786
handle: this.handles[ index ],
10789
if ( allowed !== false ) {
10790
this.value( newVal );
10796
_stop: function( event, index ) {
10798
handle: this.handles[ index ],
10799
value: this.value()
10801
if ( this.options.values && this.options.values.length ) {
10802
uiHash.value = this.values( index );
10803
uiHash.values = this.values();
10806
this._trigger( "stop", event, uiHash );
10809
_change: function( event, index ) {
10810
if ( !this._keySliding && !this._mouseSliding ) {
10812
handle: this.handles[ index ],
10813
value: this.value()
10815
if ( this.options.values && this.options.values.length ) {
10816
uiHash.value = this.values( index );
10817
uiHash.values = this.values();
10820
this._trigger( "change", event, uiHash );
10824
value: function( newValue ) {
10825
if ( arguments.length ) {
10826
this.options.value = this._trimAlignValue( newValue );
10827
this._refreshValue();
10828
this._change( null, 0 );
10832
return this._value();
10835
values: function( index, newValue ) {
10840
if ( arguments.length > 1 ) {
10841
this.options.values[ index ] = this._trimAlignValue( newValue );
10842
this._refreshValue();
10843
this._change( null, index );
10847
if ( arguments.length ) {
10848
if ( $.isArray( arguments[ 0 ] ) ) {
10849
vals = this.options.values;
10850
newValues = arguments[ 0 ];
10851
for ( i = 0; i < vals.length; i += 1 ) {
10852
vals[ i ] = this._trimAlignValue( newValues[ i ] );
10853
this._change( null, i );
10855
this._refreshValue();
10857
if ( this.options.values && this.options.values.length ) {
10858
return this._values( index );
10860
return this.value();
10864
return this._values();
10868
_setOption: function( key, value ) {
10872
if ( $.isArray( this.options.values ) ) {
10873
valsLength = this.options.values.length;
10876
$.Widget.prototype._setOption.apply( this, arguments );
10881
this.handles.filter( ".ui-state-focus" ).blur();
10882
this.handles.removeClass( "ui-state-hover" );
10883
this.handles.propAttr( "disabled", true );
10884
this.element.addClass( "ui-disabled" );
10886
this.handles.propAttr( "disabled", false );
10887
this.element.removeClass( "ui-disabled" );
10890
case "orientation":
10891
this._detectOrientation();
10893
.removeClass( "ui-slider-horizontal ui-slider-vertical" )
10894
.addClass( "ui-slider-" + this.orientation );
10895
this._refreshValue();
10898
this._animateOff = true;
10899
this._refreshValue();
10900
this._change( null, 0 );
10901
this._animateOff = false;
10904
this._animateOff = true;
10905
this._refreshValue();
10906
for ( i = 0; i < valsLength; i += 1 ) {
10907
this._change( null, i );
10909
this._animateOff = false;
10914
//internal value getter
10915
// _value() returns value trimmed by min and max, aligned by step
10916
_value: function() {
10917
var val = this.options.value;
10918
val = this._trimAlignValue( val );
10923
//internal values getter
10924
// _values() returns array of values trimmed by min and max, aligned by step
10925
// _values( index ) returns single value trimmed by min and max, aligned by step
10926
_values: function( index ) {
10931
if ( arguments.length ) {
10932
val = this.options.values[ index ];
10933
val = this._trimAlignValue( val );
10937
// .slice() creates a copy of the array
10938
// this copy gets trimmed by min and max and then returned
10939
vals = this.options.values.slice();
10940
for ( i = 0; i < vals.length; i+= 1) {
10941
vals[ i ] = this._trimAlignValue( vals[ i ] );
10948
// returns the step-aligned value that val is closest to, between (inclusive) min and max
10949
_trimAlignValue: function( val ) {
10950
if ( val <= this._valueMin() ) {
10951
return this._valueMin();
10953
if ( val >= this._valueMax() ) {
10954
return this._valueMax();
10956
var step = ( this.options.step > 0 ) ? this.options.step : 1,
10957
valModStep = (val - this._valueMin()) % step,
10958
alignValue = val - valModStep;
10960
if ( Math.abs(valModStep) * 2 >= step ) {
10961
alignValue += ( valModStep > 0 ) ? step : ( -step );
10964
// Since JavaScript has problems with large floats, round
10965
// the final value to 5 digits after the decimal point (see #4124)
10966
return parseFloat( alignValue.toFixed(5) );
10969
_valueMin: function() {
10970
return this.options.min;
10973
_valueMax: function() {
10974
return this.options.max;
10977
_refreshValue: function() {
10978
var oRange = this.options.range,
10981
animate = ( !this._animateOff ) ? o.animate : false,
10989
if ( this.options.values && this.options.values.length ) {
10990
this.handles.each(function( i, j ) {
10991
valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100;
10992
_set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
10993
$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
10994
if ( self.options.range === true ) {
10995
if ( self.orientation === "horizontal" ) {
10997
self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
11000
self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
11004
self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
11007
self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
11011
lastValPercent = valPercent;
11014
value = this.value();
11015
valueMin = this._valueMin();
11016
valueMax = this._valueMax();
11017
valPercent = ( valueMax !== valueMin ) ?
11018
( value - valueMin ) / ( valueMax - valueMin ) * 100 :
11020
_set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
11021
this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
11023
if ( oRange === "min" && this.orientation === "horizontal" ) {
11024
this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
11026
if ( oRange === "max" && this.orientation === "horizontal" ) {
11027
this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
11029
if ( oRange === "min" && this.orientation === "vertical" ) {
11030
this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
11032
if ( oRange === "max" && this.orientation === "vertical" ) {
11033
this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
11040
$.extend( $.ui.slider, {
11046
* jQuery UI Tabs 1.8.18
11048
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
11049
* Dual licensed under the MIT or GPL Version 2 licenses.
11050
* http://jquery.org/license
11052
* http://docs.jquery.com/UI/Tabs
11055
* jquery.ui.core.js
11056
* jquery.ui.widget.js
11058
(function( $, undefined ) {
11063
function getNextTabId() {
11067
function getNextListId() {
11071
$.widget( "ui.tabs", {
11076
cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
11077
collapsible: false,
11082
fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
11083
idPrefix: "ui-tabs-",
11085
panelTemplate: "<div></div>",
11089
spinner: "<em>Loading…</em>",
11090
tabTemplate: "<li><a href='#{href}'><span>#{label}</span></a></li>"
11093
_create: function() {
11094
this._tabify( true );
11097
_setOption: function( key, value ) {
11098
if ( key == "selected" ) {
11099
if (this.options.collapsible && value == this.options.selected ) {
11102
this.select( value );
11104
this.options[ key ] = value;
11109
_tabId: function( a ) {
11110
return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
11111
this.options.idPrefix + getNextTabId();
11114
_sanitizeSelector: function( hash ) {
11115
// we need this because an id may contain a ":"
11116
return hash.replace( /:/g, "\\:" );
11119
_cookie: function() {
11120
var cookie = this.cookie ||
11121
( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() );
11122
return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) );
11125
_ui: function( tab, panel ) {
11129
index: this.anchors.index( tab )
11133
_cleanup: function() {
11134
// restore all former loading tabs labels
11135
this.lis.filter( ".ui-state-processing" )
11136
.removeClass( "ui-state-processing" )
11137
.find( "span:data(label.tabs)" )
11139
var el = $( this );
11140
el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" );
11144
_tabify: function( init ) {
11147
fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
11149
this.list = this.element.find( "ol,ul" ).eq( 0 );
11150
this.lis = $( " > li:has(a[href])", this.list );
11151
this.anchors = this.lis.map(function() {
11152
return $( "a", this )[ 0 ];
11154
this.panels = $( [] );
11156
this.anchors.each(function( i, a ) {
11157
var href = $( a ).attr( "href" );
11158
// For dynamically created HTML that contains a hash as href IE < 8 expands
11159
// such href to the full page url with hash and then misinterprets tab as ajax.
11160
// Same consideration applies for an added tab with a fragment identifier
11161
// since a[href=#fragment-identifier] does unexpectedly not match.
11162
// Thus normalize href attribute...
11163
var hrefBase = href.split( "#" )[ 0 ],
11165
if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
11166
( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
11172
if ( fragmentId.test( href ) ) {
11173
self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) );
11175
// prevent loading the page itself if href is just "#"
11176
} else if ( href && href !== "#" ) {
11177
// required for restore on destroy
11178
$.data( a, "href.tabs", href );
11180
// TODO until #3808 is fixed strip fragment identifier from url
11181
// (IE fails to load from such url)
11182
$.data( a, "load.tabs", href.replace( /#.*$/, "" ) );
11184
var id = self._tabId( a );
11186
var $panel = self.element.find( "#" + id );
11187
if ( !$panel.length ) {
11188
$panel = $( o.panelTemplate )
11190
.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
11191
.insertAfter( self.panels[ i - 1 ] || self.list );
11192
$panel.data( "destroy.tabs", true );
11194
self.panels = self.panels.add( $panel );
11195
// invalid tab href
11197
o.disabled.push( i );
11201
// initialization from scratch
11203
// attach necessary classes for styling
11204
this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" );
11205
this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
11206
this.lis.addClass( "ui-state-default ui-corner-top" );
11207
this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" );
11210
// use "selected" option or try to retrieve:
11211
// 1. from fragment identifier in url
11213
// 3. from selected class attribute on <li>
11214
if ( o.selected === undefined ) {
11215
if ( location.hash ) {
11216
this.anchors.each(function( i, a ) {
11217
if ( a.hash == location.hash ) {
11223
if ( typeof o.selected !== "number" && o.cookie ) {
11224
o.selected = parseInt( self._cookie(), 10 );
11226
if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) {
11227
o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
11229
o.selected = o.selected || ( this.lis.length ? 0 : -1 );
11230
} else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release
11234
// sanity check - default to first tab...
11235
o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 )
11239
// Take disabling tabs via class attribute from HTML
11240
// into account and update option properly.
11241
// A selected tab cannot become disabled.
11242
o.disabled = $.unique( o.disabled.concat(
11243
$.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) {
11244
return self.lis.index( n );
11248
if ( $.inArray( o.selected, o.disabled ) != -1 ) {
11249
o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 );
11252
// highlight selected tab
11253
this.panels.addClass( "ui-tabs-hide" );
11254
this.lis.removeClass( "ui-tabs-selected ui-state-active" );
11255
// check for length avoids error when initializing empty list
11256
if ( o.selected >= 0 && this.anchors.length ) {
11257
self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" );
11258
this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
11260
// seems to be expected behavior that the show callback is fired
11261
self.element.queue( "tabs", function() {
11262
self._trigger( "show", null,
11263
self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) );
11266
this.load( o.selected );
11269
// clean up to avoid memory leaks in certain versions of IE 6
11270
// TODO: namespace this event
11271
$( window ).bind( "unload", function() {
11272
self.lis.add( self.anchors ).unbind( ".tabs" );
11273
self.lis = self.anchors = self.panels = null;
11275
// update selected after add/remove
11277
o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) );
11280
// update collapsible
11281
// TODO: use .toggleClass()
11282
this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" );
11284
// set or update cookie after init and add/remove respectively
11286
this._cookie( o.selected, o.cookie );
11290
for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) {
11291
$( li )[ $.inArray( i, o.disabled ) != -1 &&
11292
// TODO: use .toggleClass()
11293
!$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" );
11296
// reset cache if switching from cached to not cached
11297
if ( o.cache === false ) {
11298
this.anchors.removeData( "cache.tabs" );
11301
// remove all handlers before, tabify may run on existing tabs after add or option change
11302
this.lis.add( this.anchors ).unbind( ".tabs" );
11304
if ( o.event !== "mouseover" ) {
11305
var addState = function( state, el ) {
11306
if ( el.is( ":not(.ui-state-disabled)" ) ) {
11307
el.addClass( "ui-state-" + state );
11310
var removeState = function( state, el ) {
11311
el.removeClass( "ui-state-" + state );
11313
this.lis.bind( "mouseover.tabs" , function() {
11314
addState( "hover", $( this ) );
11316
this.lis.bind( "mouseout.tabs", function() {
11317
removeState( "hover", $( this ) );
11319
this.anchors.bind( "focus.tabs", function() {
11320
addState( "focus", $( this ).closest( "li" ) );
11322
this.anchors.bind( "blur.tabs", function() {
11323
removeState( "focus", $( this ).closest( "li" ) );
11327
// set up animations
11328
var hideFx, showFx;
11330
if ( $.isArray( o.fx ) ) {
11331
hideFx = o.fx[ 0 ];
11332
showFx = o.fx[ 1 ];
11334
hideFx = showFx = o.fx;
11338
// Reset certain styles left over from animation
11339
// and prevent IE's ClearType bug...
11340
function resetStyle( $el, fx ) {
11341
$el.css( "display", "" );
11342
if ( !$.support.opacity && fx.opacity ) {
11343
$el[ 0 ].style.removeAttribute( "filter" );
11348
var showTab = showFx
11349
? function( clicked, $show ) {
11350
$( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
11351
$show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way
11352
.animate( showFx, showFx.duration || "normal", function() {
11353
resetStyle( $show, showFx );
11354
self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
11357
: function( clicked, $show ) {
11358
$( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
11359
$show.removeClass( "ui-tabs-hide" );
11360
self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) );
11363
// Hide a tab, $show is optional...
11364
var hideTab = hideFx
11365
? function( clicked, $hide ) {
11366
$hide.animate( hideFx, hideFx.duration || "normal", function() {
11367
self.lis.removeClass( "ui-tabs-selected ui-state-active" );
11368
$hide.addClass( "ui-tabs-hide" );
11369
resetStyle( $hide, hideFx );
11370
self.element.dequeue( "tabs" );
11373
: function( clicked, $hide, $show ) {
11374
self.lis.removeClass( "ui-tabs-selected ui-state-active" );
11375
$hide.addClass( "ui-tabs-hide" );
11376
self.element.dequeue( "tabs" );
11379
// attach tab event handler, unbind to avoid duplicates from former tabifying...
11380
this.anchors.bind( o.event + ".tabs", function() {
11382
$li = $(el).closest( "li" ),
11383
$hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
11384
$show = self.element.find( self._sanitizeSelector( el.hash ) );
11386
// If tab is already selected and not collapsible or tab disabled or
11387
// or is already loading or click callback returns false stop here.
11388
// Check if click handler returns false last so that it is not executed
11389
// for a disabled or loading tab!
11390
if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) ||
11391
$li.hasClass( "ui-state-disabled" ) ||
11392
$li.hasClass( "ui-state-processing" ) ||
11393
self.panels.filter( ":animated" ).length ||
11394
self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) {
11399
o.selected = self.anchors.index( this );
11403
// if tab may be closed
11404
if ( o.collapsible ) {
11405
if ( $li.hasClass( "ui-tabs-selected" ) ) {
11409
self._cookie( o.selected, o.cookie );
11412
self.element.queue( "tabs", function() {
11413
hideTab( el, $hide );
11414
}).dequeue( "tabs" );
11418
} else if ( !$hide.length ) {
11420
self._cookie( o.selected, o.cookie );
11423
self.element.queue( "tabs", function() {
11424
showTab( el, $show );
11427
// TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
11428
self.load( self.anchors.index( this ) );
11436
self._cookie( o.selected, o.cookie );
11440
if ( $show.length ) {
11441
if ( $hide.length ) {
11442
self.element.queue( "tabs", function() {
11443
hideTab( el, $hide );
11446
self.element.queue( "tabs", function() {
11447
showTab( el, $show );
11450
self.load( self.anchors.index( this ) );
11452
throw "jQuery UI Tabs: Mismatching fragment identifier.";
11455
// Prevent IE from keeping other link focussed when using the back button
11456
// and remove dotted border from clicked link. This is controlled via CSS
11457
// in modern browsers; blur() removes focus from address bar in Firefox
11458
// which can become a usability and annoying problem with tabs('rotate').
11459
if ( $.browser.msie ) {
11464
// disable click in any case
11465
this.anchors.bind( "click.tabs", function(){
11470
_getIndex: function( index ) {
11471
// meta-function to give users option to provide a href string instead of a numerical index.
11472
// also sanitizes numerical indexes to valid values.
11473
if ( typeof index == "string" ) {
11474
index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) );
11480
destroy: function() {
11481
var o = this.options;
11487
.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" )
11488
.removeData( "tabs" );
11490
this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
11492
this.anchors.each(function() {
11493
var href = $.data( this, "href.tabs" );
11497
var $this = $( this ).unbind( ".tabs" );
11498
$.each( [ "href", "load", "cache" ], function( i, prefix ) {
11499
$this.removeData( prefix + ".tabs" );
11503
this.lis.unbind( ".tabs" ).add( this.panels ).each(function() {
11504
if ( $.data( this, "destroy.tabs" ) ) {
11505
$( this ).remove();
11507
$( this ).removeClass([
11508
"ui-state-default",
11510
"ui-tabs-selected",
11514
"ui-state-disabled",
11516
"ui-widget-content",
11517
"ui-corner-bottom",
11524
this._cookie( null, o.cookie );
11530
add: function( url, label, index ) {
11531
if ( index === undefined ) {
11532
index = this.anchors.length;
11537
$li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ),
11538
id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] );
11540
$li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true );
11542
// try to find an existing element before creating a new one
11543
var $panel = self.element.find( "#" + id );
11544
if ( !$panel.length ) {
11545
$panel = $( o.panelTemplate )
11547
.data( "destroy.tabs", true );
11549
$panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" );
11551
if ( index >= this.lis.length ) {
11552
$li.appendTo( this.list );
11553
$panel.appendTo( this.list[ 0 ].parentNode );
11555
$li.insertBefore( this.lis[ index ] );
11556
$panel.insertBefore( this.panels[ index ] );
11559
o.disabled = $.map( o.disabled, function( n, i ) {
11560
return n >= index ? ++n : n;
11565
if ( this.anchors.length == 1 ) {
11567
$li.addClass( "ui-tabs-selected ui-state-active" );
11568
$panel.removeClass( "ui-tabs-hide" );
11569
this.element.queue( "tabs", function() {
11570
self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) );
11576
this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11580
remove: function( index ) {
11581
index = this._getIndex( index );
11582
var o = this.options,
11583
$li = this.lis.eq( index ).remove(),
11584
$panel = this.panels.eq( index ).remove();
11586
// If selected tab was removed focus tab to the right or
11587
// in case the last tab was removed the tab to the left.
11588
if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) {
11589
this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) );
11592
o.disabled = $.map(
11593
$.grep( o.disabled, function(n, i) {
11597
return n >= index ? --n : n;
11602
this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) );
11606
enable: function( index ) {
11607
index = this._getIndex( index );
11608
var o = this.options;
11609
if ( $.inArray( index, o.disabled ) == -1 ) {
11613
this.lis.eq( index ).removeClass( "ui-state-disabled" );
11614
o.disabled = $.grep( o.disabled, function( n, i ) {
11618
this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11622
disable: function( index ) {
11623
index = this._getIndex( index );
11624
var self = this, o = this.options;
11625
// cannot disable already selected tab
11626
if ( index != o.selected ) {
11627
this.lis.eq( index ).addClass( "ui-state-disabled" );
11629
o.disabled.push( index );
11632
this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) );
11638
select: function( index ) {
11639
index = this._getIndex( index );
11640
if ( index == -1 ) {
11641
if ( this.options.collapsible && this.options.selected != -1 ) {
11642
index = this.options.selected;
11647
this.anchors.eq( index ).trigger( this.options.event + ".tabs" );
11651
load: function( index ) {
11652
index = this._getIndex( index );
11655
a = this.anchors.eq( index )[ 0 ],
11656
url = $.data( a, "load.tabs" );
11660
// not remote or from cache
11661
if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) {
11662
this.element.dequeue( "tabs" );
11666
// load remote from here on
11667
this.lis.eq( index ).addClass( "ui-state-processing" );
11670
var span = $( "span", a );
11671
span.data( "label.tabs", span.html() ).html( o.spinner );
11674
this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, {
11676
success: function( r, s ) {
11677
self.element.find( self._sanitizeSelector( a.hash ) ).html( r );
11679
// take care of tab labels
11683
$.data( a, "cache.tabs", true );
11686
self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
11688
o.ajaxOptions.success( r, s );
11692
error: function( xhr, s, e ) {
11693
// take care of tab labels
11696
self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) );
11698
// Passing index avoid a race condition when this method is
11699
// called after the user has selected another tab.
11700
// Pass the anchor that initiated this request allows
11701
// loadError to manipulate the tab content panel via $(a.hash)
11702
o.ajaxOptions.error( xhr, s, index, a );
11708
// last, so that load event is fired before show...
11709
self.element.dequeue( "tabs" );
11714
abort: function() {
11715
// stop possibly running animations
11716
this.element.queue( [] );
11717
this.panels.stop( false, true );
11719
// "tabs" queue must not contain more than two elements,
11720
// which are the callbacks for the latest clicked tab...
11721
this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) );
11723
// terminate pending requests from other tabs
11729
// take care of tab labels
11734
url: function( index, url ) {
11735
this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url );
11739
length: function() {
11740
return this.anchors.length;
11744
$.extend( $.ui.tabs, {
11755
$.extend( $.ui.tabs.prototype, {
11757
rotate: function( ms, continuing ) {
11761
var rotate = self._rotate || ( self._rotate = function( e ) {
11762
clearTimeout( self.rotation );
11763
self.rotation = setTimeout(function() {
11764
var t = o.selected;
11765
self.select( ++t < self.anchors.length ? t : 0 );
11769
e.stopPropagation();
11773
var stop = self._unrotate || ( self._unrotate = !continuing
11775
if (e.clientX) { // in case of a true click
11786
this.element.bind( "tabsshow", rotate );
11787
this.anchors.bind( o.event + ".tabs", stop );
11791
clearTimeout( self.rotation );
11792
this.element.unbind( "tabsshow", rotate );
11793
this.anchors.unbind( o.event + ".tabs", stop );
11794
delete this._rotate;
11795
delete this._unrotate;