4 * Copyright 2012, 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.21
323 * Copyright 2012, 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.21
595 * Copyright 2012, 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
);
640 .unbind('mousemove.'+this.widgetName
, this._mouseMoveDelegate
)
641 .unbind('mouseup.'+this.widgetName
, this._mouseUpDelegate
);
644 _mouseDown: function(event
) {
645 // don't let more than one widget handle mouseStart
646 if( mouseHandled
) { return };
648 // we may have missed mouseup (out of window)
649 (this._mouseStarted
&& this._mouseUp(event
));
651 this._mouseDownEvent
= event
;
654 btnIsLeft
= (event
.which
== 1),
655 // event.target.nodeName works around a bug in IE 8 with
656 // disabled inputs (#7620)
657 elIsCancel
= (typeof this.options
.cancel
== "string" && event
.target
.nodeName
? $(event
.target
).closest(this.options
.cancel
).length
: false);
658 if (!btnIsLeft
|| elIsCancel
|| !this._mouseCapture(event
)) {
662 this.mouseDelayMet
= !this.options
.delay
;
663 if (!this.mouseDelayMet
) {
664 this._mouseDelayTimer
= setTimeout(function() {
665 self
.mouseDelayMet
= true;
666 }, this.options
.delay
);
669 if (this._mouseDistanceMet(event
) && this._mouseDelayMet(event
)) {
670 this._mouseStarted
= (this._mouseStart(event
) !== false);
671 if (!this._mouseStarted
) {
672 event
.preventDefault();
677 // Click event may never have fired (Gecko & Opera)
678 if (true === $.data(event
.target
, this.widgetName
+ '.preventClickEvent')) {
679 $.removeData(event
.target
, this.widgetName
+ '.preventClickEvent');
682 // these delegates are required to keep context
683 this._mouseMoveDelegate = function(event
) {
684 return self
._mouseMove(event
);
686 this._mouseUpDelegate = function(event
) {
687 return self
._mouseUp(event
);
690 .bind('mousemove.'+this.widgetName
, this._mouseMoveDelegate
)
691 .bind('mouseup.'+this.widgetName
, this._mouseUpDelegate
);
693 event
.preventDefault();
699 _mouseMove: function(event
) {
700 // IE mouseup check - mouseup happened when mouse was out of window
701 if ($.browser
.msie
&& !(document
.documentMode
>= 9) && !event
.button
) {
702 return this._mouseUp(event
);
705 if (this._mouseStarted
) {
706 this._mouseDrag(event
);
707 return event
.preventDefault();
710 if (this._mouseDistanceMet(event
) && this._mouseDelayMet(event
)) {
712 (this._mouseStart(this._mouseDownEvent
, event
) !== false);
713 (this._mouseStarted
? this._mouseDrag(event
) : this._mouseUp(event
));
716 return !this._mouseStarted
;
719 _mouseUp: function(event
) {
721 .unbind('mousemove.'+this.widgetName
, this._mouseMoveDelegate
)
722 .unbind('mouseup.'+this.widgetName
, this._mouseUpDelegate
);
724 if (this._mouseStarted
) {
725 this._mouseStarted
= false;
727 if (event
.target
== this._mouseDownEvent
.target
) {
728 $.data(event
.target
, this.widgetName
+ '.preventClickEvent', true);
731 this._mouseStop(event
);
737 _mouseDistanceMet: function(event
) {
739 Math
.abs(this._mouseDownEvent
.pageX
- event
.pageX
),
740 Math
.abs(this._mouseDownEvent
.pageY
- event
.pageY
)
741 ) >= this.options
.distance
745 _mouseDelayMet: function(event
) {
746 return this.mouseDelayMet
;
749 // These are placeholder methods, to be overriden by extending plugin
750 _mouseStart: function(event
) {},
751 _mouseDrag: function(event
) {},
752 _mouseStop: function(event
) {},
753 _mouseCapture: function(event
) { return true; }
758 * jQuery UI Position 1.8.21
760 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
761 * Dual licensed under the MIT or GPL Version 2 licenses.
762 * http://jquery.org/license
764 * http://docs.jquery.com/UI/Position
766 (function( $, undefined ) {
770 var horizontalPositions
= /left|center|right/,
771 verticalPositions
= /top|center|bottom/,
774 _position
= $.fn
.position
,
775 _offset
= $.fn
.offset
;
777 $.fn
.position = function( options
) {
778 if ( !options
|| !options
.of ) {
779 return _position
.apply( this, arguments
);
782 // make a copy, we don't want to modify arguments
783 options
= $.extend( {}, options
);
785 var target
= $( options
.of ),
786 targetElem
= target
[0],
787 collision
= ( options
.collision
|| "flip" ).split( " " ),
788 offset
= options
.offset
? options
.offset
.split( " " ) : [ 0, 0 ],
793 if ( targetElem
.nodeType
=== 9 ) {
794 targetWidth
= target
.width();
795 targetHeight
= target
.height();
796 basePosition
= { top
: 0, left
: 0 };
797 // TODO: use $.isWindow() in 1.9
798 } else if ( targetElem
.setTimeout
) {
799 targetWidth
= target
.width();
800 targetHeight
= target
.height();
801 basePosition
= { top
: target
.scrollTop(), left
: target
.scrollLeft() };
802 } else if ( targetElem
.preventDefault
) {
803 // force left top to allow flipping
804 options
.at
= "left top";
805 targetWidth
= targetHeight
= 0;
806 basePosition
= { top
: options
.of.pageY
, left
: options
.of.pageX
};
808 targetWidth
= target
.outerWidth();
809 targetHeight
= target
.outerHeight();
810 basePosition
= target
.offset();
813 // force my and at to have valid horizontal and veritcal positions
814 // if a value is missing or invalid, it will be converted to center
815 $.each( [ "my", "at" ], function() {
816 var pos
= ( options
[this] || "" ).split( " " );
817 if ( pos
.length
=== 1) {
818 pos
= horizontalPositions
.test( pos
[0] ) ?
819 pos
.concat( [center
] ) :
820 verticalPositions
.test( pos
[0] ) ?
821 [ center
].concat( pos
) :
824 pos
[ 0 ] = horizontalPositions
.test( pos
[0] ) ? pos
[ 0 ] : center
;
825 pos
[ 1 ] = verticalPositions
.test( pos
[1] ) ? pos
[ 1 ] : center
;
826 options
[ this ] = pos
;
829 // normalize collision option
830 if ( collision
.length
=== 1 ) {
831 collision
[ 1 ] = collision
[ 0 ];
834 // normalize offset option
835 offset
[ 0 ] = parseInt( offset
[0], 10 ) || 0;
836 if ( offset
.length
=== 1 ) {
837 offset
[ 1 ] = offset
[ 0 ];
839 offset
[ 1 ] = parseInt( offset
[1], 10 ) || 0;
841 if ( options
.at
[0] === "right" ) {
842 basePosition
.left
+= targetWidth
;
843 } else if ( options
.at
[0] === center
) {
844 basePosition
.left
+= targetWidth
/ 2;
847 if ( options
.at
[1] === "bottom" ) {
848 basePosition
.top
+= targetHeight
;
849 } else if ( options
.at
[1] === center
) {
850 basePosition
.top
+= targetHeight
/ 2;
853 basePosition
.left
+= offset
[ 0 ];
854 basePosition
.top
+= offset
[ 1 ];
856 return this.each(function() {
857 var elem
= $( this ),
858 elemWidth
= elem
.outerWidth(),
859 elemHeight
= elem
.outerHeight(),
860 marginLeft
= parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
861 marginTop
= parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
862 collisionWidth
= elemWidth
+ marginLeft
+
863 ( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ),
864 collisionHeight
= elemHeight
+ marginTop
+
865 ( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ),
866 position
= $.extend( {}, basePosition
),
869 if ( options
.my
[0] === "right" ) {
870 position
.left
-= elemWidth
;
871 } else if ( options
.my
[0] === center
) {
872 position
.left
-= elemWidth
/ 2;
875 if ( options
.my
[1] === "bottom" ) {
876 position
.top
-= elemHeight
;
877 } else if ( options
.my
[1] === center
) {
878 position
.top
-= elemHeight
/ 2;
881 // prevent fractions if jQuery version doesn't support them (see #5280)
882 if ( !support
.fractions
) {
883 position
.left
= Math
.round( position
.left
);
884 position
.top
= Math
.round( position
.top
);
887 collisionPosition
= {
888 left
: position
.left
- marginLeft
,
889 top
: position
.top
- marginTop
892 $.each( [ "left", "top" ], function( i
, dir
) {
893 if ( $.ui
.position
[ collision
[i
] ] ) {
894 $.ui
.position
[ collision
[i
] ][ dir
]( position
, {
895 targetWidth
: targetWidth
,
896 targetHeight
: targetHeight
,
897 elemWidth
: elemWidth
,
898 elemHeight
: elemHeight
,
899 collisionPosition
: collisionPosition
,
900 collisionWidth
: collisionWidth
,
901 collisionHeight
: collisionHeight
,
909 if ( $.fn
.bgiframe
) {
912 elem
.offset( $.extend( position
, { using
: options
.using
} ) );
918 left: function( position
, data
) {
919 var win
= $( window
),
920 over
= data
.collisionPosition
.left
+ data
.collisionWidth
- win
.width() - win
.scrollLeft();
921 position
.left
= over
> 0 ? position
.left
- over
: Math
.max( position
.left
- data
.collisionPosition
.left
, position
.left
);
923 top: function( position
, data
) {
924 var win
= $( window
),
925 over
= data
.collisionPosition
.top
+ data
.collisionHeight
- win
.height() - win
.scrollTop();
926 position
.top
= over
> 0 ? position
.top
- over
: Math
.max( position
.top
- data
.collisionPosition
.top
, position
.top
);
931 left: function( position
, data
) {
932 if ( data
.at
[0] === center
) {
935 var win
= $( window
),
936 over
= data
.collisionPosition
.left
+ data
.collisionWidth
- win
.width() - win
.scrollLeft(),
937 myOffset
= data
.my
[ 0 ] === "left" ?
939 data
.my
[ 0 ] === "right" ?
942 atOffset
= data
.at
[ 0 ] === "left" ?
945 offset
= -2 * data
.offset
[ 0 ];
946 position
.left
+= data
.collisionPosition
.left
< 0 ?
947 myOffset
+ atOffset
+ offset
:
949 myOffset
+ atOffset
+ offset
:
952 top: function( position
, data
) {
953 if ( data
.at
[1] === center
) {
956 var win
= $( window
),
957 over
= data
.collisionPosition
.top
+ data
.collisionHeight
- win
.height() - win
.scrollTop(),
958 myOffset
= data
.my
[ 1 ] === "top" ?
960 data
.my
[ 1 ] === "bottom" ?
963 atOffset
= data
.at
[ 1 ] === "top" ?
966 offset
= -2 * data
.offset
[ 1 ];
967 position
.top
+= data
.collisionPosition
.top
< 0 ?
968 myOffset
+ atOffset
+ offset
:
970 myOffset
+ atOffset
+ offset
:
976 // offset setter from jQuery 1.4
977 if ( !$.offset
.setOffset
) {
978 $.offset
.setOffset = function( elem
, options
) {
979 // set position first, in-case top/left are set even on static elem
980 if ( /static/.test( $.curCSS( elem
, "position" ) ) ) {
981 elem
.style
.position
= "relative";
983 var curElem
= $( elem
),
984 curOffset
= curElem
.offset(),
985 curTop
= parseInt( $.curCSS( elem
, "top", true ), 10 ) || 0,
986 curLeft
= parseInt( $.curCSS( elem
, "left", true ), 10) || 0,
988 top
: (options
.top
- curOffset
.top
) + curTop
,
989 left
: (options
.left
- curOffset
.left
) + curLeft
992 if ( 'using' in options
) {
993 options
.using
.call( elem
, props
);
995 curElem
.css( props
);
999 $.fn
.offset = function( options
) {
1000 var elem
= this[ 0 ];
1001 if ( !elem
|| !elem
.ownerDocument
) { return null; }
1003 if ( $.isFunction( options
) ) {
1004 return this.each(function( i
) {
1005 $( this ).offset( options
.call( this, i
, $( this ).offset() ) );
1008 return this.each(function() {
1009 $.offset
.setOffset( this, options
);
1012 return _offset
.call( this );
1016 // fraction support test (older versions of jQuery don't support fractions)
1018 var body
= document
.getElementsByTagName( "body" )[ 0 ],
1019 div
= document
.createElement( "div" ),
1020 testElement
, testElementParent
, testElementStyle
, offset
, offsetTotal
;
1022 //Create a "fake body" for testing based on method used in jQuery.support
1023 testElement
= document
.createElement( body
? "div" : "body" );
1024 testElementStyle
= {
1025 visibility
: "hidden",
1033 $.extend( testElementStyle
, {
1034 position
: "absolute",
1039 for ( var i
in testElementStyle
) {
1040 testElement
.style
[ i
] = testElementStyle
[ i
];
1042 testElement
.appendChild( div
);
1043 testElementParent
= body
|| document
.documentElement
;
1044 testElementParent
.insertBefore( testElement
, testElementParent
.firstChild
);
1046 div
.style
.cssText
= "position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;";
1048 offset
= $( div
).offset( function( _
, offset
) {
1052 testElement
.innerHTML
= "";
1053 testElementParent
.removeChild( testElement
);
1055 offsetTotal
= offset
.top
+ offset
.left
+ ( body
? 2000 : 0 );
1056 support
.fractions
= offsetTotal
> 21 && offsetTotal
< 22;
1061 * jQuery UI Draggable 1.8.21
1063 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
1064 * Dual licensed under the MIT or GPL Version 2 licenses.
1065 * http://jquery.org/license
1067 * http://docs.jquery.com/UI/Draggables
1071 * jquery.ui.mouse.js
1072 * jquery.ui.widget.js
1074 (function( $, undefined ) {
1076 $.widget("ui.draggable", $.ui
.mouse
, {
1077 widgetEventPrefix
: "drag",
1082 connectToSortable
: false,
1091 refreshPositions
: false,
1093 revertDuration
: 500,
1096 scrollSensitivity
: 20,
1104 _create: function() {
1106 if (this.options
.helper
== 'original' && !(/^(?:r|a|f)/).test(this.element
.css("position")))
1107 this.element
[0].style
.position
= 'relative';
1109 (this.options
.addClasses
&& this.element
.addClass("ui-draggable"));
1110 (this.options
.disabled
&& this.element
.addClass("ui-draggable-disabled"));
1116 destroy: function() {
1117 if(!this.element
.data('draggable')) return;
1119 .removeData("draggable")
1120 .unbind(".draggable")
1121 .removeClass("ui-draggable"
1122 + " ui-draggable-dragging"
1123 + " ui-draggable-disabled");
1124 this._mouseDestroy();
1129 _mouseCapture: function(event
) {
1131 var o
= this.options
;
1133 // among others, prevent a drag on a resizable-handle
1134 if (this.helper
|| o
.disabled
|| $(event
.target
).is('.ui-resizable-handle'))
1137 //Quit if we're not on a valid handle
1138 this.handle
= this._getHandle(event
);
1142 if ( o
.iframeFix
) {
1143 $(o
.iframeFix
=== true ? "iframe" : o
.iframeFix
).each(function() {
1144 $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
1146 width
: this.offsetWidth
+"px", height
: this.offsetHeight
+"px",
1147 position
: "absolute", opacity
: "0.001", zIndex
: 1000
1149 .css($(this).offset())
1158 _mouseStart: function(event
) {
1160 var o
= this.options
;
1162 //Create and append the visible helper
1163 this.helper
= this._createHelper(event
);
1165 this.helper
.addClass("ui-draggable-dragging");
1167 //Cache the helper size
1168 this._cacheHelperProportions();
1170 //If ddmanager is used for droppables, set the global draggable
1172 $.ui
.ddmanager
.current
= this;
1175 * - Position generation -
1176 * This block generates everything position related - it's the core of draggables.
1179 //Cache the margins of the original element
1180 this._cacheMargins();
1182 //Store the helper's css position
1183 this.cssPosition
= this.helper
.css("position");
1184 this.scrollParent
= this.helper
.scrollParent();
1186 //The element's absolute position on the page minus margins
1187 this.offset
= this.positionAbs
= this.element
.offset();
1189 top
: this.offset
.top
- this.margins
.top
,
1190 left
: this.offset
.left
- this.margins
.left
1193 $.extend(this.offset
, {
1194 click
: { //Where the click happened, relative to the element
1195 left
: event
.pageX
- this.offset
.left
,
1196 top
: event
.pageY
- this.offset
.top
1198 parent
: this._getParentOffset(),
1199 relative
: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1202 //Generate the original position
1203 this.originalPosition
= this.position
= this._generatePosition(event
);
1204 this.originalPageX
= event
.pageX
;
1205 this.originalPageY
= event
.pageY
;
1207 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
1208 (o
.cursorAt
&& this._adjustOffsetFromHelper(o
.cursorAt
));
1210 //Set a containment if given in the options
1212 this._setContainment();
1214 //Trigger event + callbacks
1215 if(this._trigger("start", event
) === false) {
1220 //Recache the helper size
1221 this._cacheHelperProportions();
1223 //Prepare the droppable offsets
1224 if ($.ui
.ddmanager
&& !o
.dropBehaviour
)
1225 $.ui
.ddmanager
.prepareOffsets(this, event
);
1228 this._mouseDrag(event
, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1230 //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1231 if ( $.ui
.ddmanager
) $.ui
.ddmanager
.dragStart(this, event
);
1236 _mouseDrag: function(event
, noPropagation
) {
1238 //Compute the helpers position
1239 this.position
= this._generatePosition(event
);
1240 this.positionAbs
= this._convertPositionTo("absolute");
1242 //Call plugins and callbacks and use the resulting position if something is returned
1243 if (!noPropagation
) {
1244 var ui
= this._uiHash();
1245 if(this._trigger('drag', event
, ui
) === false) {
1249 this.position
= ui
.position
;
1252 if(!this.options
.axis
|| this.options
.axis
!= "y") this.helper
[0].style
.left
= this.position
.left
+'px';
1253 if(!this.options
.axis
|| this.options
.axis
!= "x") this.helper
[0].style
.top
= this.position
.top
+'px';
1254 if($.ui
.ddmanager
) $.ui
.ddmanager
.drag(this, event
);
1259 _mouseStop: function(event
) {
1261 //If we are using droppables, inform the manager about the drop
1262 var dropped
= false;
1263 if ($.ui
.ddmanager
&& !this.options
.dropBehaviour
)
1264 dropped
= $.ui
.ddmanager
.drop(this, event
);
1266 //if a drop comes from outside (a sortable)
1268 dropped
= this.dropped
;
1269 this.dropped
= false;
1272 //if the original element is no longer in the DOM don't bother to continue (see #8269)
1273 var element
= this.element
[0], elementInDom
= false;
1274 while ( element
&& (element
= element
.parentNode
) ) {
1275 if (element
== document
) {
1276 elementInDom
= true;
1279 if ( !elementInDom
&& this.options
.helper
=== "original" )
1282 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
))) {
1284 $(this.helper
).animate(this.originalPosition
, parseInt(this.options
.revertDuration
, 10), function() {
1285 if(self
._trigger("stop", event
) !== false) {
1290 if(this._trigger("stop", event
) !== false) {
1298 _mouseUp: function(event
) {
1299 if (this.options
.iframeFix
=== true) {
1300 $("div.ui-draggable-iframeFix").each(function() {
1301 this.parentNode
.removeChild(this);
1302 }); //Remove frame helpers
1305 //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1306 if( $.ui
.ddmanager
) $.ui
.ddmanager
.dragStop(this, event
);
1308 return $.ui
.mouse
.prototype._mouseUp
.call(this, event
);
1311 cancel: function() {
1313 if(this.helper
.is(".ui-draggable-dragging")) {
1323 _getHandle: function(event
) {
1325 var handle
= !this.options
.handle
|| !$(this.options
.handle
, this.element
).length
? true : false;
1326 $(this.options
.handle
, this.element
)
1330 if(this == event
.target
) handle
= true;
1337 _createHelper: function(event
) {
1339 var o
= this.options
;
1340 var helper
= $.isFunction(o
.helper
) ? $(o
.helper
.apply(this.element
[0], [event
])) : (o
.helper
== 'clone' ? this.element
.clone().removeAttr('id') : this.element
);
1342 if(!helper
.parents('body').length
)
1343 helper
.appendTo((o
.appendTo
== 'parent' ? this.element
[0].parentNode
: o
.appendTo
));
1345 if(helper
[0] != this.element
[0] && !(/(fixed|absolute)/).test(helper
.css("position")))
1346 helper
.css("position", "absolute");
1352 _adjustOffsetFromHelper: function(obj
) {
1353 if (typeof obj
== 'string') {
1354 obj
= obj
.split(' ');
1356 if ($.isArray(obj
)) {
1357 obj
= {left
: +obj
[0], top
: +obj
[1] || 0};
1359 if ('left' in obj
) {
1360 this.offset
.click
.left
= obj
.left
+ this.margins
.left
;
1362 if ('right' in obj
) {
1363 this.offset
.click
.left
= this.helperProportions
.width
- obj
.right
+ this.margins
.left
;
1366 this.offset
.click
.top
= obj
.top
+ this.margins
.top
;
1368 if ('bottom' in obj
) {
1369 this.offset
.click
.top
= this.helperProportions
.height
- obj
.bottom
+ this.margins
.top
;
1373 _getParentOffset: function() {
1375 //Get the offsetParent and cache its position
1376 this.offsetParent
= this.helper
.offsetParent();
1377 var po
= this.offsetParent
.offset();
1379 // This is a special case where we need to modify a offset calculated on start, since the following happened:
1380 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1381 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1382 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1383 if(this.cssPosition
== 'absolute' && this.scrollParent
[0] != document
&& $.ui
.contains(this.scrollParent
[0], this.offsetParent
[0])) {
1384 po
.left
+= this.scrollParent
.scrollLeft();
1385 po
.top
+= this.scrollParent
.scrollTop();
1388 if((this.offsetParent
[0] == document
.body
) //This needs to be actually done for all browsers, since pageX/pageY includes this information
1389 || (this.offsetParent
[0].tagName
&& this.offsetParent
[0].tagName
.toLowerCase() == 'html' && $.browser
.msie
)) //Ugly IE fix
1390 po
= { top
: 0, left
: 0 };
1393 top
: po
.top
+ (parseInt(this.offsetParent
.css("borderTopWidth"),10) || 0),
1394 left
: po
.left
+ (parseInt(this.offsetParent
.css("borderLeftWidth"),10) || 0)
1399 _getRelativeOffset: function() {
1401 if(this.cssPosition
== "relative") {
1402 var p
= this.element
.position();
1404 top
: p
.top
- (parseInt(this.helper
.css("top"),10) || 0) + this.scrollParent
.scrollTop(),
1405 left
: p
.left
- (parseInt(this.helper
.css("left"),10) || 0) + this.scrollParent
.scrollLeft()
1408 return { top
: 0, left
: 0 };
1413 _cacheMargins: function() {
1415 left
: (parseInt(this.element
.css("marginLeft"),10) || 0),
1416 top
: (parseInt(this.element
.css("marginTop"),10) || 0),
1417 right
: (parseInt(this.element
.css("marginRight"),10) || 0),
1418 bottom
: (parseInt(this.element
.css("marginBottom"),10) || 0)
1422 _cacheHelperProportions: function() {
1423 this.helperProportions
= {
1424 width
: this.helper
.outerWidth(),
1425 height
: this.helper
.outerHeight()
1429 _setContainment: function() {
1431 var o
= this.options
;
1432 if(o
.containment
== 'parent') o
.containment
= this.helper
[0].parentNode
;
1433 if(o
.containment
== 'document' || o
.containment
== 'window') this.containment
= [
1434 o
.containment
== 'document' ? 0 : $(window
).scrollLeft() - this.offset
.relative
.left
- this.offset
.parent
.left
,
1435 o
.containment
== 'document' ? 0 : $(window
).scrollTop() - this.offset
.relative
.top
- this.offset
.parent
.top
,
1436 (o
.containment
== 'document' ? 0 : $(window
).scrollLeft()) + $(o
.containment
== 'document' ? document
: window
).width() - this.helperProportions
.width
- this.margins
.left
,
1437 (o
.containment
== 'document' ? 0 : $(window
).scrollTop()) + ($(o
.containment
== 'document' ? document
: window
).height() || document
.body
.parentNode
.scrollHeight
) - this.helperProportions
.height
- this.margins
.top
1440 if(!(/^(document|window|parent)$/).test(o
.containment
) && o
.containment
.constructor != Array
) {
1441 var c
= $(o
.containment
);
1442 var ce
= c
[0]; if(!ce
) return;
1443 var co
= c
.offset();
1444 var over
= ($(ce
).css("overflow") != 'hidden');
1446 this.containment
= [
1447 (parseInt($(ce
).css("borderLeftWidth"),10) || 0) + (parseInt($(ce
).css("paddingLeft"),10) || 0),
1448 (parseInt($(ce
).css("borderTopWidth"),10) || 0) + (parseInt($(ce
).css("paddingTop"),10) || 0),
1449 (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
,
1450 (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
1452 this.relative_container
= c
;
1454 } else if(o
.containment
.constructor == Array
) {
1455 this.containment
= o
.containment
;
1460 _convertPositionTo: function(d
, pos
) {
1462 if(!pos
) pos
= this.position
;
1463 var mod
= d
== "absolute" ? 1 : -1;
1464 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
);
1468 pos
.top
// The absolute mouse position
1469 + this.offset
.relative
.top
* mod
// Only for relative positioned nodes: Relative offset from element to offset parent
1470 + this.offset
.parent
.top
* mod
// The offsetParent's offset without borders (offset + border)
1471 - ($.browser
.safari
&& $.browser
.version
< 526 && this.cssPosition
== 'fixed' ? 0 : ( this.cssPosition
== 'fixed' ? -this.scrollParent
.scrollTop() : ( scrollIsRootNode
? 0 : scroll
.scrollTop() ) ) * mod
)
1474 pos
.left
// The absolute mouse position
1475 + this.offset
.relative
.left
* mod
// Only for relative positioned nodes: Relative offset from element to offset parent
1476 + this.offset
.parent
.left
* mod
// The offsetParent's offset without borders (offset + border)
1477 - ($.browser
.safari
&& $.browser
.version
< 526 && this.cssPosition
== 'fixed' ? 0 : ( this.cssPosition
== 'fixed' ? -this.scrollParent
.scrollLeft() : scrollIsRootNode
? 0 : scroll
.scrollLeft() ) * mod
)
1483 _generatePosition: function(event
) {
1485 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
);
1486 var pageX
= event
.pageX
;
1487 var pageY
= event
.pageY
;
1490 * - Position constraining -
1491 * Constrain the position to a mix of grid, containment.
1494 if(this.originalPosition
) { //If we are not dragging yet, we won't check for options
1496 if(this.containment
) {
1497 if (this.relative_container
){
1498 var co
= this.relative_container
.offset();
1499 containment
= [ this.containment
[0] + co
.left
,
1500 this.containment
[1] + co
.top
,
1501 this.containment
[2] + co
.left
,
1502 this.containment
[3] + co
.top
];
1505 containment
= this.containment
;
1508 if(event
.pageX
- this.offset
.click
.left
< containment
[0]) pageX
= containment
[0] + this.offset
.click
.left
;
1509 if(event
.pageY
- this.offset
.click
.top
< containment
[1]) pageY
= containment
[1] + this.offset
.click
.top
;
1510 if(event
.pageX
- this.offset
.click
.left
> containment
[2]) pageX
= containment
[2] + this.offset
.click
.left
;
1511 if(event
.pageY
- this.offset
.click
.top
> containment
[3]) pageY
= containment
[3] + this.offset
.click
.top
;
1515 //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1516 var top
= o
.grid
[1] ? this.originalPageY
+ Math
.round((pageY
- this.originalPageY
) / o
.grid
[1]) * o
.grid
[1] : this.originalPageY
;
1517 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
;
1519 var left
= o
.grid
[0] ? this.originalPageX
+ Math
.round((pageX
- this.originalPageX
) / o
.grid
[0]) * o
.grid
[0] : this.originalPageX
;
1520 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
;
1527 pageY
// The absolute mouse position
1528 - this.offset
.click
.top
// Click offset (relative to the element)
1529 - this.offset
.relative
.top
// Only for relative positioned nodes: Relative offset from element to offset parent
1530 - this.offset
.parent
.top
// The offsetParent's offset without borders (offset + border)
1531 + ($.browser
.safari
&& $.browser
.version
< 526 && this.cssPosition
== 'fixed' ? 0 : ( this.cssPosition
== 'fixed' ? -this.scrollParent
.scrollTop() : ( scrollIsRootNode
? 0 : scroll
.scrollTop() ) ))
1534 pageX
// The absolute mouse position
1535 - this.offset
.click
.left
// Click offset (relative to the element)
1536 - this.offset
.relative
.left
// Only for relative positioned nodes: Relative offset from element to offset parent
1537 - this.offset
.parent
.left
// The offsetParent's offset without borders (offset + border)
1538 + ($.browser
.safari
&& $.browser
.version
< 526 && this.cssPosition
== 'fixed' ? 0 : ( this.cssPosition
== 'fixed' ? -this.scrollParent
.scrollLeft() : scrollIsRootNode
? 0 : scroll
.scrollLeft() ))
1544 _clear: function() {
1545 this.helper
.removeClass("ui-draggable-dragging");
1546 if(this.helper
[0] != this.element
[0] && !this.cancelHelperRemoval
) this.helper
.remove();
1547 //if($.ui.ddmanager) $.ui.ddmanager.current = null;
1549 this.cancelHelperRemoval
= false;
1552 // From now on bulk stuff - mainly helpers
1554 _trigger: function(type
, event
, ui
) {
1555 ui
= ui
|| this._uiHash();
1556 $.ui
.plugin
.call(this, type
, [event
, ui
]);
1557 if(type
== "drag") this.positionAbs
= this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
1558 return $.Widget
.prototype._trigger
.call(this, type
, event
, ui
);
1563 _uiHash: function(event
) {
1565 helper
: this.helper
,
1566 position
: this.position
,
1567 originalPosition
: this.originalPosition
,
1568 offset
: this.positionAbs
1574 $.extend($.ui
.draggable
, {
1578 $.ui
.plugin
.add("draggable", "connectToSortable", {
1579 start: function(event
, ui
) {
1581 var inst
= $(this).data("draggable"), o
= inst
.options
,
1582 uiSortable
= $.extend({}, ui
, { item
: inst
.element
});
1583 inst
.sortables
= [];
1584 $(o
.connectToSortable
).each(function() {
1585 var sortable
= $.data(this, 'sortable');
1586 if (sortable
&& !sortable
.options
.disabled
) {
1587 inst
.sortables
.push({
1589 shouldRevert
: sortable
.options
.revert
1591 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).
1592 sortable
._trigger("activate", event
, uiSortable
);
1597 stop: function(event
, ui
) {
1599 //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1600 var inst
= $(this).data("draggable"),
1601 uiSortable
= $.extend({}, ui
, { item
: inst
.element
});
1603 $.each(inst
.sortables
, function() {
1604 if(this.instance
.isOver
) {
1606 this.instance
.isOver
= 0;
1608 inst
.cancelHelperRemoval
= true; //Don't remove the helper in the draggable instance
1609 this.instance
.cancelHelperRemoval
= false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1611 //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
1612 if(this.shouldRevert
) this.instance
.options
.revert
= true;
1614 //Trigger the stop of the sortable
1615 this.instance
._mouseStop(event
);
1617 this.instance
.options
.helper
= this.instance
.options
._helper
;
1619 //If the helper has been the original item, restore properties in the sortable
1620 if(inst
.options
.helper
== 'original')
1621 this.instance
.currentItem
.css({ top
: 'auto', left
: 'auto' });
1624 this.instance
.cancelHelperRemoval
= false; //Remove the helper in the sortable instance
1625 this.instance
._trigger("deactivate", event
, uiSortable
);
1631 drag: function(event
, ui
) {
1633 var inst
= $(this).data("draggable"), self
= this;
1635 var checkPos = function(o
) {
1636 var dyClick
= this.offset
.click
.top
, dxClick
= this.offset
.click
.left
;
1637 var helperTop
= this.positionAbs
.top
, helperLeft
= this.positionAbs
.left
;
1638 var itemHeight
= o
.height
, itemWidth
= o
.width
;
1639 var itemTop
= o
.top
, itemLeft
= o
.left
;
1641 return $.ui
.isOver(helperTop
+ dyClick
, helperLeft
+ dxClick
, itemTop
, itemLeft
, itemHeight
, itemWidth
);
1644 $.each(inst
.sortables
, function(i
) {
1646 //Copy over some variables to allow calling the sortable's native _intersectsWith
1647 this.instance
.positionAbs
= inst
.positionAbs
;
1648 this.instance
.helperProportions
= inst
.helperProportions
;
1649 this.instance
.offset
.click
= inst
.offset
.click
;
1651 if(this.instance
._intersectsWith(this.instance
.containerCache
)) {
1653 //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1654 if(!this.instance
.isOver
) {
1656 this.instance
.isOver
= 1;
1657 //Now we fake the start of dragging for the sortable instance,
1658 //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1659 //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)
1660 this.instance
.currentItem
= $(self
).clone().removeAttr('id').appendTo(this.instance
.element
).data("sortable-item", true);
1661 this.instance
.options
._helper
= this.instance
.options
.helper
; //Store helper option to later restore it
1662 this.instance
.options
.helper = function() { return ui
.helper
[0]; };
1664 event
.target
= this.instance
.currentItem
[0];
1665 this.instance
._mouseCapture(event
, true);
1666 this.instance
._mouseStart(event
, true, true);
1668 //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1669 this.instance
.offset
.click
.top
= inst
.offset
.click
.top
;
1670 this.instance
.offset
.click
.left
= inst
.offset
.click
.left
;
1671 this.instance
.offset
.parent
.left
-= inst
.offset
.parent
.left
- this.instance
.offset
.parent
.left
;
1672 this.instance
.offset
.parent
.top
-= inst
.offset
.parent
.top
- this.instance
.offset
.parent
.top
;
1674 inst
._trigger("toSortable", event
);
1675 inst
.dropped
= this.instance
.element
; //draggable revert needs that
1676 //hack so receive/update callbacks work (mostly)
1677 inst
.currentItem
= inst
.element
;
1678 this.instance
.fromOutside
= inst
;
1682 //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
1683 if(this.instance
.currentItem
) this.instance
._mouseDrag(event
);
1687 //If it doesn't intersect with the sortable, and it intersected before,
1688 //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1689 if(this.instance
.isOver
) {
1691 this.instance
.isOver
= 0;
1692 this.instance
.cancelHelperRemoval
= true;
1694 //Prevent reverting on this forced stop
1695 this.instance
.options
.revert
= false;
1697 // The out event needs to be triggered independently
1698 this.instance
._trigger('out', event
, this.instance
._uiHash(this.instance
));
1700 this.instance
._mouseStop(event
, true);
1701 this.instance
.options
.helper
= this.instance
.options
._helper
;
1703 //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1704 this.instance
.currentItem
.remove();
1705 if(this.instance
.placeholder
) this.instance
.placeholder
.remove();
1707 inst
._trigger("fromSortable", event
);
1708 inst
.dropped
= false; //draggable revert needs that
1718 $.ui
.plugin
.add("draggable", "cursor", {
1719 start: function(event
, ui
) {
1720 var t
= $('body'), o
= $(this).data('draggable').options
;
1721 if (t
.css("cursor")) o
._cursor
= t
.css("cursor");
1722 t
.css("cursor", o
.cursor
);
1724 stop: function(event
, ui
) {
1725 var o
= $(this).data('draggable').options
;
1726 if (o
._cursor
) $('body').css("cursor", o
._cursor
);
1730 $.ui
.plugin
.add("draggable", "opacity", {
1731 start: function(event
, ui
) {
1732 var t
= $(ui
.helper
), o
= $(this).data('draggable').options
;
1733 if(t
.css("opacity")) o
._opacity
= t
.css("opacity");
1734 t
.css('opacity', o
.opacity
);
1736 stop: function(event
, ui
) {
1737 var o
= $(this).data('draggable').options
;
1738 if(o
._opacity
) $(ui
.helper
).css('opacity', o
._opacity
);
1742 $.ui
.plugin
.add("draggable", "scroll", {
1743 start: function(event
, ui
) {
1744 var i
= $(this).data("draggable");
1745 if(i
.scrollParent
[0] != document
&& i
.scrollParent
[0].tagName
!= 'HTML') i
.overflowOffset
= i
.scrollParent
.offset();
1747 drag: function(event
, ui
) {
1749 var i
= $(this).data("draggable"), o
= i
.options
, scrolled
= false;
1751 if(i
.scrollParent
[0] != document
&& i
.scrollParent
[0].tagName
!= 'HTML') {
1753 if(!o
.axis
|| o
.axis
!= 'x') {
1754 if((i
.overflowOffset
.top
+ i
.scrollParent
[0].offsetHeight
) - event
.pageY
< o
.scrollSensitivity
)
1755 i
.scrollParent
[0].scrollTop
= scrolled
= i
.scrollParent
[0].scrollTop
+ o
.scrollSpeed
;
1756 else if(event
.pageY
- i
.overflowOffset
.top
< o
.scrollSensitivity
)
1757 i
.scrollParent
[0].scrollTop
= scrolled
= i
.scrollParent
[0].scrollTop
- o
.scrollSpeed
;
1760 if(!o
.axis
|| o
.axis
!= 'y') {
1761 if((i
.overflowOffset
.left
+ i
.scrollParent
[0].offsetWidth
) - event
.pageX
< o
.scrollSensitivity
)
1762 i
.scrollParent
[0].scrollLeft
= scrolled
= i
.scrollParent
[0].scrollLeft
+ o
.scrollSpeed
;
1763 else if(event
.pageX
- i
.overflowOffset
.left
< o
.scrollSensitivity
)
1764 i
.scrollParent
[0].scrollLeft
= scrolled
= i
.scrollParent
[0].scrollLeft
- o
.scrollSpeed
;
1769 if(!o
.axis
|| o
.axis
!= 'x') {
1770 if(event
.pageY
- $(document
).scrollTop() < o
.scrollSensitivity
)
1771 scrolled
= $(document
).scrollTop($(document
).scrollTop() - o
.scrollSpeed
);
1772 else if($(window
).height() - (event
.pageY
- $(document
).scrollTop()) < o
.scrollSensitivity
)
1773 scrolled
= $(document
).scrollTop($(document
).scrollTop() + o
.scrollSpeed
);
1776 if(!o
.axis
|| o
.axis
!= 'y') {
1777 if(event
.pageX
- $(document
).scrollLeft() < o
.scrollSensitivity
)
1778 scrolled
= $(document
).scrollLeft($(document
).scrollLeft() - o
.scrollSpeed
);
1779 else if($(window
).width() - (event
.pageX
- $(document
).scrollLeft()) < o
.scrollSensitivity
)
1780 scrolled
= $(document
).scrollLeft($(document
).scrollLeft() + o
.scrollSpeed
);
1785 if(scrolled
!== false && $.ui
.ddmanager
&& !o
.dropBehaviour
)
1786 $.ui
.ddmanager
.prepareOffsets(i
, event
);
1791 $.ui
.plugin
.add("draggable", "snap", {
1792 start: function(event
, ui
) {
1794 var i
= $(this).data("draggable"), o
= i
.options
;
1795 i
.snapElements
= [];
1797 $(o
.snap
.constructor != String
? ( o
.snap
.items
|| ':data(draggable)' ) : o
.snap
).each(function() {
1798 var $t
= $(this); var $o
= $t
.offset();
1799 if(this != i
.element
[0]) i
.snapElements
.push({
1801 width
: $t
.outerWidth(), height
: $t
.outerHeight(),
1802 top
: $o
.top
, left
: $o
.left
1807 drag: function(event
, ui
) {
1809 var inst
= $(this).data("draggable"), o
= inst
.options
;
1810 var d
= o
.snapTolerance
;
1812 var x1
= ui
.offset
.left
, x2
= x1
+ inst
.helperProportions
.width
,
1813 y1
= ui
.offset
.top
, y2
= y1
+ inst
.helperProportions
.height
;
1815 for (var i
= inst
.snapElements
.length
- 1; i
>= 0; i
--){
1817 var l
= inst
.snapElements
[i
].left
, r
= l
+ inst
.snapElements
[i
].width
,
1818 t
= inst
.snapElements
[i
].top
, b
= t
+ inst
.snapElements
[i
].height
;
1820 //Yes, I know, this is insane ;)
1821 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
))) {
1822 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
})));
1823 inst
.snapElements
[i
].snapping
= false;
1827 if(o
.snapMode
!= 'inner') {
1828 var ts
= Math
.abs(t
- y2
) <= d
;
1829 var bs
= Math
.abs(b
- y1
) <= d
;
1830 var ls
= Math
.abs(l
- x2
) <= d
;
1831 var rs
= Math
.abs(r
- x1
) <= d
;
1832 if(ts
) ui
.position
.top
= inst
._convertPositionTo("relative", { top
: t
- inst
.helperProportions
.height
, left
: 0 }).top
- inst
.margins
.top
;
1833 if(bs
) ui
.position
.top
= inst
._convertPositionTo("relative", { top
: b
, left
: 0 }).top
- inst
.margins
.top
;
1834 if(ls
) ui
.position
.left
= inst
._convertPositionTo("relative", { top
: 0, left
: l
- inst
.helperProportions
.width
}).left
- inst
.margins
.left
;
1835 if(rs
) ui
.position
.left
= inst
._convertPositionTo("relative", { top
: 0, left
: r
}).left
- inst
.margins
.left
;
1838 var first
= (ts
|| bs
|| ls
|| rs
);
1840 if(o
.snapMode
!= 'outer') {
1841 var ts
= Math
.abs(t
- y1
) <= d
;
1842 var bs
= Math
.abs(b
- y2
) <= d
;
1843 var ls
= Math
.abs(l
- x1
) <= d
;
1844 var rs
= Math
.abs(r
- x2
) <= d
;
1845 if(ts
) ui
.position
.top
= inst
._convertPositionTo("relative", { top
: t
, left
: 0 }).top
- inst
.margins
.top
;
1846 if(bs
) ui
.position
.top
= inst
._convertPositionTo("relative", { top
: b
- inst
.helperProportions
.height
, left
: 0 }).top
- inst
.margins
.top
;
1847 if(ls
) ui
.position
.left
= inst
._convertPositionTo("relative", { top
: 0, left
: l
}).left
- inst
.margins
.left
;
1848 if(rs
) ui
.position
.left
= inst
._convertPositionTo("relative", { top
: 0, left
: r
- inst
.helperProportions
.width
}).left
- inst
.margins
.left
;
1851 if(!inst
.snapElements
[i
].snapping
&& (ts
|| bs
|| ls
|| rs
|| first
))
1852 (inst
.options
.snap
.snap
&& inst
.options
.snap
.snap
.call(inst
.element
, event
, $.extend(inst
._uiHash(), { snapItem
: inst
.snapElements
[i
].item
})));
1853 inst
.snapElements
[i
].snapping
= (ts
|| bs
|| ls
|| rs
|| first
);
1860 $.ui
.plugin
.add("draggable", "stack", {
1861 start: function(event
, ui
) {
1863 var o
= $(this).data("draggable").options
;
1865 var group
= $.makeArray($(o
.stack
)).sort(function(a
,b
) {
1866 return (parseInt($(a
).css("zIndex"),10) || 0) - (parseInt($(b
).css("zIndex"),10) || 0);
1868 if (!group
.length
) { return; }
1870 var min
= parseInt(group
[0].style
.zIndex
) || 0;
1871 $(group
).each(function(i
) {
1872 this.style
.zIndex
= min
+ i
;
1875 this[0].style
.zIndex
= min
+ group
.length
;
1880 $.ui
.plugin
.add("draggable", "zIndex", {
1881 start: function(event
, ui
) {
1882 var t
= $(ui
.helper
), o
= $(this).data("draggable").options
;
1883 if(t
.css("zIndex")) o
._zIndex
= t
.css("zIndex");
1884 t
.css('zIndex', o
.zIndex
);
1886 stop: function(event
, ui
) {
1887 var o
= $(this).data("draggable").options
;
1888 if(o
._zIndex
) $(ui
.helper
).css('zIndex', o
._zIndex
);
1894 * jQuery UI Droppable 1.8.21
1896 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
1897 * Dual licensed under the MIT or GPL Version 2 licenses.
1898 * http://jquery.org/license
1900 * http://docs.jquery.com/UI/Droppables
1904 * jquery.ui.widget.js
1905 * jquery.ui.mouse.js
1906 * jquery.ui.draggable.js
1908 (function( $, undefined ) {
1910 $.widget("ui.droppable", {
1911 widgetEventPrefix
: "drop",
1919 tolerance
: 'intersect'
1921 _create: function() {
1923 var o
= this.options
, accept
= o
.accept
;
1924 this.isover
= 0; this.isout
= 1;
1926 this.accept
= $.isFunction(accept
) ? accept : function(d
) {
1927 return d
.is(accept
);
1930 //Store the droppable's proportions
1931 this.proportions
= { width
: this.element
[0].offsetWidth
, height
: this.element
[0].offsetHeight
};
1933 // Add the reference and positions to the manager
1934 $.ui
.ddmanager
.droppables
[o
.scope
] = $.ui
.ddmanager
.droppables
[o
.scope
] || [];
1935 $.ui
.ddmanager
.droppables
[o
.scope
].push(this);
1937 (o
.addClasses
&& this.element
.addClass("ui-droppable"));
1941 destroy: function() {
1942 var drop
= $.ui
.ddmanager
.droppables
[this.options
.scope
];
1943 for ( var i
= 0; i
< drop
.length
; i
++ )
1944 if ( drop
[i
] == this )
1948 .removeClass("ui-droppable ui-droppable-disabled")
1949 .removeData("droppable")
1950 .unbind(".droppable");
1955 _setOption: function(key
, value
) {
1957 if(key
== 'accept') {
1958 this.accept
= $.isFunction(value
) ? value : function(d
) {
1962 $.Widget
.prototype._setOption
.apply(this, arguments
);
1965 _activate: function(event
) {
1966 var draggable
= $.ui
.ddmanager
.current
;
1967 if(this.options
.activeClass
) this.element
.addClass(this.options
.activeClass
);
1968 (draggable
&& this._trigger('activate', event
, this.ui(draggable
)));
1971 _deactivate: function(event
) {
1972 var draggable
= $.ui
.ddmanager
.current
;
1973 if(this.options
.activeClass
) this.element
.removeClass(this.options
.activeClass
);
1974 (draggable
&& this._trigger('deactivate', event
, this.ui(draggable
)));
1977 _over: function(event
) {
1979 var draggable
= $.ui
.ddmanager
.current
;
1980 if (!draggable
|| (draggable
.currentItem
|| draggable
.element
)[0] == this.element
[0]) return; // Bail if draggable and droppable are same element
1982 if (this.accept
.call(this.element
[0],(draggable
.currentItem
|| draggable
.element
))) {
1983 if(this.options
.hoverClass
) this.element
.addClass(this.options
.hoverClass
);
1984 this._trigger('over', event
, this.ui(draggable
));
1989 _out: function(event
) {
1991 var draggable
= $.ui
.ddmanager
.current
;
1992 if (!draggable
|| (draggable
.currentItem
|| draggable
.element
)[0] == this.element
[0]) return; // Bail if draggable and droppable are same element
1994 if (this.accept
.call(this.element
[0],(draggable
.currentItem
|| draggable
.element
))) {
1995 if(this.options
.hoverClass
) this.element
.removeClass(this.options
.hoverClass
);
1996 this._trigger('out', event
, this.ui(draggable
));
2001 _drop: function(event
,custom
) {
2003 var draggable
= custom
|| $.ui
.ddmanager
.current
;
2004 if (!draggable
|| (draggable
.currentItem
|| draggable
.element
)[0] == this.element
[0]) return false; // Bail if draggable and droppable are same element
2006 var childrenIntersection
= false;
2007 this.element
.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {
2008 var inst
= $.data(this, 'droppable');
2011 && !inst
.options
.disabled
2012 && inst
.options
.scope
== draggable
.options
.scope
2013 && inst
.accept
.call(inst
.element
[0], (draggable
.currentItem
|| draggable
.element
))
2014 && $.ui
.intersect(draggable
, $.extend(inst
, { offset
: inst
.element
.offset() }), inst
.options
.tolerance
)
2015 ) { childrenIntersection
= true; return false; }
2017 if(childrenIntersection
) return false;
2019 if(this.accept
.call(this.element
[0],(draggable
.currentItem
|| draggable
.element
))) {
2020 if(this.options
.activeClass
) this.element
.removeClass(this.options
.activeClass
);
2021 if(this.options
.hoverClass
) this.element
.removeClass(this.options
.hoverClass
);
2022 this._trigger('drop', event
, this.ui(draggable
));
2023 return this.element
;
2032 draggable
: (c
.currentItem
|| c
.element
),
2034 position
: c
.position
,
2035 offset
: c
.positionAbs
2041 $.extend($.ui
.droppable
, {
2045 $.ui
.intersect = function(draggable
, droppable
, toleranceMode
) {
2047 if (!droppable
.offset
) return false;
2049 var x1
= (draggable
.positionAbs
|| draggable
.position
.absolute
).left
, x2
= x1
+ draggable
.helperProportions
.width
,
2050 y1
= (draggable
.positionAbs
|| draggable
.position
.absolute
).top
, y2
= y1
+ draggable
.helperProportions
.height
;
2051 var l
= droppable
.offset
.left
, r
= l
+ droppable
.proportions
.width
,
2052 t
= droppable
.offset
.top
, b
= t
+ droppable
.proportions
.height
;
2054 switch (toleranceMode
) {
2056 return (l
<= x1
&& x2
<= r
2057 && t
<= y1
&& y2
<= b
);
2060 return (l
< x1
+ (draggable
.helperProportions
.width
/ 2) // Right Half
2061 && x2
- (draggable
.helperProportions
.width
/ 2) < r
// Left Half
2062 && t
< y1
+ (draggable
.helperProportions
.height
/ 2) // Bottom Half
2063 && y2
- (draggable
.helperProportions
.height
/ 2) < b
); // Top Half
2066 var draggableLeft
= ((draggable
.positionAbs
|| draggable
.position
.absolute
).left
+ (draggable
.clickOffset
|| draggable
.offset
.click
).left
),
2067 draggableTop
= ((draggable
.positionAbs
|| draggable
.position
.absolute
).top
+ (draggable
.clickOffset
|| draggable
.offset
.click
).top
),
2068 isOver
= $.ui
.isOver(draggableTop
, draggableLeft
, t
, l
, droppable
.proportions
.height
, droppable
.proportions
.width
);
2073 (y1
>= t
&& y1
<= b
) || // Top edge touching
2074 (y2
>= t
&& y2
<= b
) || // Bottom edge touching
2075 (y1
< t
&& y2
> b
) // Surrounded vertically
2077 (x1
>= l
&& x1
<= r
) || // Left edge touching
2078 (x2
>= l
&& x2
<= r
) || // Right edge touching
2079 (x1
< l
&& x2
> r
) // Surrounded horizontally
2090 This manager tracks offsets of draggables and droppables
2094 droppables
: { 'default': [] },
2095 prepareOffsets: function(t
, event
) {
2097 var m
= $.ui
.ddmanager
.droppables
[t
.options
.scope
] || [];
2098 var type
= event
? event
.type
: null; // workaround for #2317
2099 var list
= (t
.currentItem
|| t
.element
).find(":data(droppable)").andSelf();
2101 droppablesLoop
: for (var i
= 0; i
< m
.length
; i
++) {
2103 if(m
[i
].options
.disabled
|| (t
&& !m
[i
].accept
.call(m
[i
].element
[0],(t
.currentItem
|| t
.element
)))) continue; //No disabled and non-accepted
2104 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
2105 m
[i
].visible
= m
[i
].element
.css("display") != "none"; if(!m
[i
].visible
) continue; //If the element is not visible, continue
2107 if(type
== "mousedown") m
[i
]._activate
.call(m
[i
], event
); //Activate the droppable if used directly from draggables
2109 m
[i
].offset
= m
[i
].element
.offset();
2110 m
[i
].proportions
= { width
: m
[i
].element
[0].offsetWidth
, height
: m
[i
].element
[0].offsetHeight
};
2115 drop: function(draggable
, event
) {
2117 var dropped
= false;
2118 $.each($.ui
.ddmanager
.droppables
[draggable
.options
.scope
] || [], function() {
2120 if(!this.options
) return;
2121 if (!this.options
.disabled
&& this.visible
&& $.ui
.intersect(draggable
, this, this.options
.tolerance
))
2122 dropped
= this._drop
.call(this, event
) || dropped
;
2124 if (!this.options
.disabled
&& this.visible
&& this.accept
.call(this.element
[0],(draggable
.currentItem
|| draggable
.element
))) {
2125 this.isout
= 1; this.isover
= 0;
2126 this._deactivate
.call(this, event
);
2133 dragStart: function( draggable
, event
) {
2134 //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2135 draggable
.element
.parents( ":not(body,html)" ).bind( "scroll.droppable", function() {
2136 if( !draggable
.options
.refreshPositions
) $.ui
.ddmanager
.prepareOffsets( draggable
, event
);
2139 drag: function(draggable
, event
) {
2141 //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2142 if(draggable
.options
.refreshPositions
) $.ui
.ddmanager
.prepareOffsets(draggable
, event
);
2144 //Run through all droppables and check their positions based on specific tolerance options
2145 $.each($.ui
.ddmanager
.droppables
[draggable
.options
.scope
] || [], function() {
2147 if(this.options
.disabled
|| this.greedyChild
|| !this.visible
) return;
2148 var intersects
= $.ui
.intersect(draggable
, this, this.options
.tolerance
);
2150 var c
= !intersects
&& this.isover
== 1 ? 'isout' : (intersects
&& this.isover
== 0 ? 'isover' : null);
2154 if (this.options
.greedy
) {
2155 var parent
= this.element
.parents(':data(droppable):eq(0)');
2156 if (parent
.length
) {
2157 parentInstance
= $.data(parent
[0], 'droppable');
2158 parentInstance
.greedyChild
= (c
== 'isover' ? 1 : 0);
2162 // we just moved into a greedy child
2163 if (parentInstance
&& c
== 'isover') {
2164 parentInstance
['isover'] = 0;
2165 parentInstance
['isout'] = 1;
2166 parentInstance
._out
.call(parentInstance
, event
);
2169 this[c
] = 1; this[c
== 'isout' ? 'isover' : 'isout'] = 0;
2170 this[c
== "isover" ? "_over" : "_out"].call(this, event
);
2172 // we just moved out of a greedy child
2173 if (parentInstance
&& c
== 'isout') {
2174 parentInstance
['isout'] = 0;
2175 parentInstance
['isover'] = 1;
2176 parentInstance
._over
.call(parentInstance
, event
);
2181 dragStop: function( draggable
, event
) {
2182 draggable
.element
.parents( ":not(body,html)" ).unbind( "scroll.droppable" );
2183 //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2184 if( !draggable
.options
.refreshPositions
) $.ui
.ddmanager
.prepareOffsets( draggable
, event
);
2190 * jQuery UI Resizable 1.8.21
2192 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
2193 * Dual licensed under the MIT or GPL Version 2 licenses.
2194 * http://jquery.org/license
2196 * http://docs.jquery.com/UI/Resizables
2200 * jquery.ui.mouse.js
2201 * jquery.ui.widget.js
2203 (function( $, undefined ) {
2205 $.widget("ui.resizable", $.ui
.mouse
, {
2206 widgetEventPrefix
: "resize",
2210 animateDuration
: "slow",
2211 animateEasing
: "swing",
2225 _create: function() {
2227 var self
= this, o
= this.options
;
2228 this.element
.addClass("ui-resizable");
2231 _aspectRatio
: !!(o
.aspectRatio
),
2232 aspectRatio
: o
.aspectRatio
,
2233 originalElement
: this.element
,
2234 _proportionallyResizeElements
: [],
2235 _helper
: o
.helper
|| o
.ghost
|| o
.animate
? o
.helper
|| 'ui-resizable-helper' : null
2238 //Wrap the element if it cannot hold child nodes
2239 if(this.element
[0].nodeName
.match(/canvas|textarea|input|select|button|img/i)) {
2241 //Create a wrapper element and set the wrapper to the new current internal element
2243 $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
2244 position
: this.element
.css('position'),
2245 width
: this.element
.outerWidth(),
2246 height
: this.element
.outerHeight(),
2247 top
: this.element
.css('top'),
2248 left
: this.element
.css('left')
2252 //Overwrite the original this.element
2253 this.element
= this.element
.parent().data(
2254 "resizable", this.element
.data('resizable')
2257 this.elementIsWrapper
= true;
2259 //Move margins to the wrapper
2260 this.element
.css({ marginLeft
: this.originalElement
.css("marginLeft"), marginTop
: this.originalElement
.css("marginTop"), marginRight
: this.originalElement
.css("marginRight"), marginBottom
: this.originalElement
.css("marginBottom") });
2261 this.originalElement
.css({ marginLeft
: 0, marginTop
: 0, marginRight
: 0, marginBottom
: 0});
2263 //Prevent Safari textarea resize
2264 this.originalResizeStyle
= this.originalElement
.css('resize');
2265 this.originalElement
.css('resize', 'none');
2267 //Push the actual element to our proportionallyResize internal array
2268 this._proportionallyResizeElements
.push(this.originalElement
.css({ position
: 'static', zoom
: 1, display
: 'block' }));
2270 // avoid IE jump (hard set the margin)
2271 this.originalElement
.css({ margin
: this.originalElement
.css('margin') });
2273 // fix handlers offset
2274 this._proportionallyResize();
2278 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' });
2279 if(this.handles
.constructor == String
) {
2281 if(this.handles
== 'all') this.handles
= 'n,e,s,w,se,sw,ne,nw';
2282 var n
= this.handles
.split(","); this.handles
= {};
2284 for(var i
= 0; i
< n
.length
; i
++) {
2286 var handle
= $.trim(n
[i
]), hname
= 'ui-resizable-'+handle
;
2287 var axis
= $('<div class="ui-resizable-handle ' + hname
+ '"></div>');
2289 // Apply zIndex to all handles - see #7960
2290 axis
.css({ zIndex
: o
.zIndex
});
2292 //TODO : What's going on here?
2293 if ('se' == handle
) {
2294 axis
.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
2297 //Insert into internal handles object and append to element
2298 this.handles
[handle
] = '.ui-resizable-'+handle
;
2299 this.element
.append(axis
);
2304 this._renderAxis = function(target
) {
2306 target
= target
|| this.element
;
2308 for(var i
in this.handles
) {
2310 if(this.handles
[i
].constructor == String
)
2311 this.handles
[i
] = $(this.handles
[i
], this.element
).show();
2313 //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2314 if (this.elementIsWrapper
&& this.originalElement
[0].nodeName
.match(/textarea|input|select|button/i)) {
2316 var axis
= $(this.handles
[i
], this.element
), padWrapper
= 0;
2318 //Checking the correct pad and border
2319 padWrapper
= /sw|ne|nw|se|n|s/.test(i
) ? axis
.outerHeight() : axis
.outerWidth();
2321 //The padding type i have to apply...
2322 var padPos
= [ 'padding',
2323 /ne|nw|n/.test(i
) ? 'Top' :
2324 /se|sw|s/.test(i
) ? 'Bottom' :
2325 /^e$/.test(i
) ? 'Right' : 'Left' ].join("");
2327 target
.css(padPos
, padWrapper
);
2329 this._proportionallyResize();
2333 //TODO: What's that good for? There's not anything to be executed left
2334 if(!$(this.handles
[i
]).length
)
2340 //TODO: make renderAxis a prototype function
2341 this._renderAxis(this.element
);
2343 this._handles
= $('.ui-resizable-handle', this.element
)
2344 .disableSelection();
2346 //Matching axis name
2347 this._handles
.mouseover(function() {
2348 if (!self
.resizing
) {
2350 var axis
= this.className
.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2351 //Axis, default = se
2352 self
.axis
= axis
&& axis
[1] ? axis
[1] : 'se';
2356 //If we want to auto hide the elements
2358 this._handles
.hide();
2360 .addClass("ui-resizable-autohide")
2362 if (o
.disabled
) return;
2363 $(this).removeClass("ui-resizable-autohide");
2364 self
._handles
.show();
2367 if (o
.disabled
) return;
2368 if (!self
.resizing
) {
2369 $(this).addClass("ui-resizable-autohide");
2370 self
._handles
.hide();
2375 //Initialize the mouse interaction
2380 destroy: function() {
2382 this._mouseDestroy();
2384 var _destroy = function(exp
) {
2385 $(exp
).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2386 .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
2389 //TODO: Unwrap at same DOM position
2390 if (this.elementIsWrapper
) {
2391 _destroy(this.element
);
2392 var wrapper
= this.element
;
2394 this.originalElement
.css({
2395 position
: wrapper
.css('position'),
2396 width
: wrapper
.outerWidth(),
2397 height
: wrapper
.outerHeight(),
2398 top
: wrapper
.css('top'),
2399 left
: wrapper
.css('left')
2404 this.originalElement
.css('resize', this.originalResizeStyle
);
2405 _destroy(this.originalElement
);
2410 _mouseCapture: function(event
) {
2412 for (var i
in this.handles
) {
2413 if ($(this.handles
[i
])[0] == event
.target
) {
2418 return !this.options
.disabled
&& handle
;
2421 _mouseStart: function(event
) {
2423 var o
= this.options
, iniPos
= this.element
.position(), el
= this.element
;
2425 this.resizing
= true;
2426 this.documentScroll
= { top
: $(document
).scrollTop(), left
: $(document
).scrollLeft() };
2428 // bugfix for http://dev.jquery.com/ticket/1749
2429 if (el
.is('.ui-draggable') || (/absolute/).test(el
.css('position'))) {
2430 el
.css({ position
: 'absolute', top
: iniPos
.top
, left
: iniPos
.left
});
2433 this._renderProxy();
2435 var curleft
= num(this.helper
.css('left')), curtop
= num(this.helper
.css('top'));
2437 if (o
.containment
) {
2438 curleft
+= $(o
.containment
).scrollLeft() || 0;
2439 curtop
+= $(o
.containment
).scrollTop() || 0;
2442 //Store needed variables
2443 this.offset
= this.helper
.offset();
2444 this.position
= { left
: curleft
, top
: curtop
};
2445 this.size
= this._helper
? { width
: el
.outerWidth(), height
: el
.outerHeight() } : { width
: el
.width(), height
: el
.height() };
2446 this.originalSize
= this._helper
? { width
: el
.outerWidth(), height
: el
.outerHeight() } : { width
: el
.width(), height
: el
.height() };
2447 this.originalPosition
= { left
: curleft
, top
: curtop
};
2448 this.sizeDiff
= { width
: el
.outerWidth() - el
.width(), height
: el
.outerHeight() - el
.height() };
2449 this.originalMousePosition
= { left
: event
.pageX
, top
: event
.pageY
};
2452 this.aspectRatio
= (typeof o
.aspectRatio
== 'number') ? o
.aspectRatio
: ((this.originalSize
.width
/ this.originalSize
.height
) || 1);
2454 var cursor
= $('.ui-resizable-' + this.axis
).css('cursor');
2455 $('body').css('cursor', cursor
== 'auto' ? this.axis
+ '-resize' : cursor
);
2457 el
.addClass("ui-resizable-resizing");
2458 this._propagate("start", event
);
2462 _mouseDrag: function(event
) {
2464 //Increase performance, avoid regex
2465 var el
= this.helper
, o
= this.options
, props
= {},
2466 self
= this, smp
= this.originalMousePosition
, a
= this.axis
;
2468 var dx
= (event
.pageX
-smp
.left
)||0, dy
= (event
.pageY
-smp
.top
)||0;
2469 var trigger
= this._change
[a
];
2470 if (!trigger
) return false;
2472 // Calculate the attrs that will be change
2473 var data
= trigger
.apply(this, [event
, dx
, dy
]), ie6
= $.browser
.msie
&& $.browser
.version
< 7, csdif
= this.sizeDiff
;
2475 // Put this in the mouseDrag handler since the user can start pressing shift while resizing
2476 this._updateVirtualBoundaries(event
.shiftKey
);
2477 if (this._aspectRatio
|| event
.shiftKey
)
2478 data
= this._updateRatio(data
, event
);
2480 data
= this._respectSize(data
, event
);
2482 // plugins callbacks need to be called first
2483 this._propagate("resize", event
);
2486 top
: this.position
.top
+ "px", left
: this.position
.left
+ "px",
2487 width
: this.size
.width
+ "px", height
: this.size
.height
+ "px"
2490 if (!this._helper
&& this._proportionallyResizeElements
.length
)
2491 this._proportionallyResize();
2493 this._updateCache(data
);
2495 // calling the user callback at the end
2496 this._trigger('resize', event
, this.ui());
2501 _mouseStop: function(event
) {
2503 this.resizing
= false;
2504 var o
= this.options
, self
= this;
2507 var pr
= this._proportionallyResizeElements
, ista
= pr
.length
&& (/textarea/i).test(pr
[0].nodeName
),
2508 soffseth
= ista
&& $.ui
.hasScroll(pr
[0], 'left') /* TODO - jump height */ ? 0 : self
.sizeDiff
.height
,
2509 soffsetw
= ista
? 0 : self
.sizeDiff
.width
;
2511 var s
= { width
: (self
.helper
.width() - soffsetw
), height
: (self
.helper
.height() - soffseth
) },
2512 left
= (parseInt(self
.element
.css('left'), 10) + (self
.position
.left
- self
.originalPosition
.left
)) || null,
2513 top
= (parseInt(self
.element
.css('top'), 10) + (self
.position
.top
- self
.originalPosition
.top
)) || null;
2516 this.element
.css($.extend(s
, { top
: top
, left
: left
}));
2518 self
.helper
.height(self
.size
.height
);
2519 self
.helper
.width(self
.size
.width
);
2521 if (this._helper
&& !o
.animate
) this._proportionallyResize();
2524 $('body').css('cursor', 'auto');
2526 this.element
.removeClass("ui-resizable-resizing");
2528 this._propagate("stop", event
);
2530 if (this._helper
) this.helper
.remove();
2535 _updateVirtualBoundaries: function(forceAspectRatio
) {
2536 var o
= this.options
, pMinWidth
, pMaxWidth
, pMinHeight
, pMaxHeight
, b
;
2539 minWidth
: isNumber(o
.minWidth
) ? o
.minWidth
: 0,
2540 maxWidth
: isNumber(o
.maxWidth
) ? o
.maxWidth
: Infinity
,
2541 minHeight
: isNumber(o
.minHeight
) ? o
.minHeight
: 0,
2542 maxHeight
: isNumber(o
.maxHeight
) ? o
.maxHeight
: Infinity
2545 if(this._aspectRatio
|| forceAspectRatio
) {
2546 // We want to create an enclosing box whose aspect ration is the requested one
2547 // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2548 pMinWidth
= b
.minHeight
* this.aspectRatio
;
2549 pMinHeight
= b
.minWidth
/ this.aspectRatio
;
2550 pMaxWidth
= b
.maxHeight
* this.aspectRatio
;
2551 pMaxHeight
= b
.maxWidth
/ this.aspectRatio
;
2553 if(pMinWidth
> b
.minWidth
) b
.minWidth
= pMinWidth
;
2554 if(pMinHeight
> b
.minHeight
) b
.minHeight
= pMinHeight
;
2555 if(pMaxWidth
< b
.maxWidth
) b
.maxWidth
= pMaxWidth
;
2556 if(pMaxHeight
< b
.maxHeight
) b
.maxHeight
= pMaxHeight
;
2558 this._vBoundaries
= b
;
2561 _updateCache: function(data
) {
2562 var o
= this.options
;
2563 this.offset
= this.helper
.offset();
2564 if (isNumber(data
.left
)) this.position
.left
= data
.left
;
2565 if (isNumber(data
.top
)) this.position
.top
= data
.top
;
2566 if (isNumber(data
.height
)) this.size
.height
= data
.height
;
2567 if (isNumber(data
.width
)) this.size
.width
= data
.width
;
2570 _updateRatio: function(data
, event
) {
2572 var o
= this.options
, cpos
= this.position
, csize
= this.size
, a
= this.axis
;
2574 if (isNumber(data
.height
)) data
.width
= (data
.height
* this.aspectRatio
);
2575 else if (isNumber(data
.width
)) data
.height
= (data
.width
/ this.aspectRatio
);
2578 data
.left
= cpos
.left
+ (csize
.width
- data
.width
);
2582 data
.top
= cpos
.top
+ (csize
.height
- data
.height
);
2583 data
.left
= cpos
.left
+ (csize
.width
- data
.width
);
2589 _respectSize: function(data
, event
) {
2591 var el
= this.helper
, o
= this._vBoundaries
, pRatio
= this._aspectRatio
|| event
.shiftKey
, a
= this.axis
,
2592 ismaxw
= isNumber(data
.width
) && o
.maxWidth
&& (o
.maxWidth
< data
.width
), ismaxh
= isNumber(data
.height
) && o
.maxHeight
&& (o
.maxHeight
< data
.height
),
2593 isminw
= isNumber(data
.width
) && o
.minWidth
&& (o
.minWidth
> data
.width
), isminh
= isNumber(data
.height
) && o
.minHeight
&& (o
.minHeight
> data
.height
);
2595 if (isminw
) data
.width
= o
.minWidth
;
2596 if (isminh
) data
.height
= o
.minHeight
;
2597 if (ismaxw
) data
.width
= o
.maxWidth
;
2598 if (ismaxh
) data
.height
= o
.maxHeight
;
2600 var dw
= this.originalPosition
.left
+ this.originalSize
.width
, dh
= this.position
.top
+ this.size
.height
;
2601 var cw
= /sw|nw|w/.test(a
), ch
= /nw|ne|n/.test(a
);
2603 if (isminw
&& cw
) data
.left
= dw
- o
.minWidth
;
2604 if (ismaxw
&& cw
) data
.left
= dw
- o
.maxWidth
;
2605 if (isminh
&& ch
) data
.top
= dh
- o
.minHeight
;
2606 if (ismaxh
&& ch
) data
.top
= dh
- o
.maxHeight
;
2608 // fixing jump error on top/left - bug #2330
2609 var isNotwh
= !data
.width
&& !data
.height
;
2610 if (isNotwh
&& !data
.left
&& data
.top
) data
.top
= null;
2611 else if (isNotwh
&& !data
.top
&& data
.left
) data
.left
= null;
2616 _proportionallyResize: function() {
2618 var o
= this.options
;
2619 if (!this._proportionallyResizeElements
.length
) return;
2620 var element
= this.helper
|| this.element
;
2622 for (var i
=0; i
< this._proportionallyResizeElements
.length
; i
++) {
2624 var prel
= this._proportionallyResizeElements
[i
];
2626 if (!this.borderDif
) {
2627 var b
= [prel
.css('borderTopWidth'), prel
.css('borderRightWidth'), prel
.css('borderBottomWidth'), prel
.css('borderLeftWidth')],
2628 p
= [prel
.css('paddingTop'), prel
.css('paddingRight'), prel
.css('paddingBottom'), prel
.css('paddingLeft')];
2630 this.borderDif
= $.map(b
, function(v
, i
) {
2631 var border
= parseInt(v
,10)||0, padding
= parseInt(p
[i
],10)||0;
2632 return border
+ padding
;
2636 if ($.browser
.msie
&& !(!($(element
).is(':hidden') || $(element
).parents(':hidden').length
)))
2640 height
: (element
.height() - this.borderDif
[0] - this.borderDif
[2]) || 0,
2641 width
: (element
.width() - this.borderDif
[1] - this.borderDif
[3]) || 0
2648 _renderProxy: function() {
2650 var el
= this.element
, o
= this.options
;
2651 this.elementOffset
= el
.offset();
2655 this.helper
= this.helper
|| $('<div style="overflow:hidden;"></div>');
2657 // fix ie6 offset TODO: This seems broken
2658 var ie6
= $.browser
.msie
&& $.browser
.version
< 7, ie6offset
= (ie6
? 1 : 0),
2659 pxyoffset
= ( ie6
? 2 : -1 );
2661 this.helper
.addClass(this._helper
).css({
2662 width
: this.element
.outerWidth() + pxyoffset
,
2663 height
: this.element
.outerHeight() + pxyoffset
,
2664 position
: 'absolute',
2665 left
: this.elementOffset
.left
- ie6offset
+'px',
2666 top
: this.elementOffset
.top
- ie6offset
+'px',
2667 zIndex
: ++o
.zIndex
//TODO: Don't modify option
2672 .disableSelection();
2675 this.helper
= this.element
;
2681 e: function(event
, dx
, dy
) {
2682 return { width
: this.originalSize
.width
+ dx
};
2684 w: function(event
, dx
, dy
) {
2685 var o
= this.options
, cs
= this.originalSize
, sp
= this.originalPosition
;
2686 return { left
: sp
.left
+ dx
, width
: cs
.width
- dx
};
2688 n: function(event
, dx
, dy
) {
2689 var o
= this.options
, cs
= this.originalSize
, sp
= this.originalPosition
;
2690 return { top
: sp
.top
+ dy
, height
: cs
.height
- dy
};
2692 s: function(event
, dx
, dy
) {
2693 return { height
: this.originalSize
.height
+ dy
};
2695 se: function(event
, dx
, dy
) {
2696 return $.extend(this._change
.s
.apply(this, arguments
), this._change
.e
.apply(this, [event
, dx
, dy
]));
2698 sw: function(event
, dx
, dy
) {
2699 return $.extend(this._change
.s
.apply(this, arguments
), this._change
.w
.apply(this, [event
, dx
, dy
]));
2701 ne: function(event
, dx
, dy
) {
2702 return $.extend(this._change
.n
.apply(this, arguments
), this._change
.e
.apply(this, [event
, dx
, dy
]));
2704 nw: function(event
, dx
, dy
) {
2705 return $.extend(this._change
.n
.apply(this, arguments
), this._change
.w
.apply(this, [event
, dx
, dy
]));
2709 _propagate: function(n
, event
) {
2710 $.ui
.plugin
.call(this, n
, [event
, this.ui()]);
2711 (n
!= "resize" && this._trigger(n
, event
, this.ui()));
2718 originalElement
: this.originalElement
,
2719 element
: this.element
,
2720 helper
: this.helper
,
2721 position
: this.position
,
2723 originalSize
: this.originalSize
,
2724 originalPosition
: this.originalPosition
2730 $.extend($.ui
.resizable
, {
2735 * Resizable Extensions
2738 $.ui
.plugin
.add("resizable", "alsoResize", {
2740 start: function (event
, ui
) {
2741 var self
= $(this).data("resizable"), o
= self
.options
;
2743 var _store = function (exp
) {
2744 $(exp
).each(function() {
2746 el
.data("resizable-alsoresize", {
2747 width
: parseInt(el
.width(), 10), height
: parseInt(el
.height(), 10),
2748 left
: parseInt(el
.css('left'), 10), top
: parseInt(el
.css('top'), 10)
2753 if (typeof(o
.alsoResize
) == 'object' && !o
.alsoResize
.parentNode
) {
2754 if (o
.alsoResize
.length
) { o
.alsoResize
= o
.alsoResize
[0]; _store(o
.alsoResize
); }
2755 else { $.each(o
.alsoResize
, function (exp
) { _store(exp
); }); }
2757 _store(o
.alsoResize
);
2761 resize: function (event
, ui
) {
2762 var self
= $(this).data("resizable"), o
= self
.options
, os
= self
.originalSize
, op
= self
.originalPosition
;
2765 height
: (self
.size
.height
- os
.height
) || 0, width
: (self
.size
.width
- os
.width
) || 0,
2766 top
: (self
.position
.top
- op
.top
) || 0, left
: (self
.position
.left
- op
.left
) || 0
2769 _alsoResize = function (exp
, c
) {
2770 $(exp
).each(function() {
2771 var el
= $(this), start
= $(this).data("resizable-alsoresize"), style
= {},
2772 css
= c
&& c
.length
? c
: el
.parents(ui
.originalElement
[0]).length
? ['width', 'height'] : ['width', 'height', 'top', 'left'];
2774 $.each(css
, function (i
, prop
) {
2775 var sum
= (start
[prop
]||0) + (delta
[prop
]||0);
2776 if (sum
&& sum
>= 0)
2777 style
[prop
] = sum
|| null;
2784 if (typeof(o
.alsoResize
) == 'object' && !o
.alsoResize
.nodeType
) {
2785 $.each(o
.alsoResize
, function (exp
, c
) { _alsoResize(exp
, c
); });
2787 _alsoResize(o
.alsoResize
);
2791 stop: function (event
, ui
) {
2792 $(this).removeData("resizable-alsoresize");
2796 $.ui
.plugin
.add("resizable", "animate", {
2798 stop: function(event
, ui
) {
2799 var self
= $(this).data("resizable"), o
= self
.options
;
2801 var pr
= self
._proportionallyResizeElements
, ista
= pr
.length
&& (/textarea/i).test(pr
[0].nodeName
),
2802 soffseth
= ista
&& $.ui
.hasScroll(pr
[0], 'left') /* TODO - jump height */ ? 0 : self
.sizeDiff
.height
,
2803 soffsetw
= ista
? 0 : self
.sizeDiff
.width
;
2805 var style
= { width
: (self
.size
.width
- soffsetw
), height
: (self
.size
.height
- soffseth
) },
2806 left
= (parseInt(self
.element
.css('left'), 10) + (self
.position
.left
- self
.originalPosition
.left
)) || null,
2807 top
= (parseInt(self
.element
.css('top'), 10) + (self
.position
.top
- self
.originalPosition
.top
)) || null;
2809 self
.element
.animate(
2810 $.extend(style
, top
&& left
? { top
: top
, left
: left
} : {}), {
2811 duration
: o
.animateDuration
,
2812 easing
: o
.animateEasing
,
2816 width
: parseInt(self
.element
.css('width'), 10),
2817 height
: parseInt(self
.element
.css('height'), 10),
2818 top
: parseInt(self
.element
.css('top'), 10),
2819 left
: parseInt(self
.element
.css('left'), 10)
2822 if (pr
&& pr
.length
) $(pr
[0]).css({ width
: data
.width
, height
: data
.height
});
2824 // propagating resize, and updating values for each animation step
2825 self
._updateCache(data
);
2826 self
._propagate("resize", event
);
2835 $.ui
.plugin
.add("resizable", "containment", {
2837 start: function(event
, ui
) {
2838 var self
= $(this).data("resizable"), o
= self
.options
, el
= self
.element
;
2839 var oc
= o
.containment
, ce
= (oc
instanceof $) ? oc
.get(0) : (/parent/.test(oc
)) ? el
.parent().get(0) : oc
;
2842 self
.containerElement
= $(ce
);
2844 if (/document/.test(oc
) || oc
== document
) {
2845 self
.containerOffset
= { left
: 0, top
: 0 };
2846 self
.containerPosition
= { left
: 0, top
: 0 };
2849 element
: $(document
), left
: 0, top
: 0,
2850 width
: $(document
).width(), height
: $(document
).height() || document
.body
.parentNode
.scrollHeight
2854 // i'm a node, so compute top, left, right, bottom
2856 var element
= $(ce
), p
= [];
2857 $([ "Top", "Right", "Left", "Bottom" ]).each(function(i
, name
) { p
[i
] = num(element
.css("padding" + name
)); });
2859 self
.containerOffset
= element
.offset();
2860 self
.containerPosition
= element
.position();
2861 self
.containerSize
= { height
: (element
.innerHeight() - p
[3]), width
: (element
.innerWidth() - p
[1]) };
2863 var co
= self
.containerOffset
, ch
= self
.containerSize
.height
, cw
= self
.containerSize
.width
,
2864 width
= ($.ui
.hasScroll(ce
, "left") ? ce
.scrollWidth
: cw
), height
= ($.ui
.hasScroll(ce
) ? ce
.scrollHeight
: ch
);
2867 element
: ce
, left
: co
.left
, top
: co
.top
, width
: width
, height
: height
2872 resize: function(event
, ui
) {
2873 var self
= $(this).data("resizable"), o
= self
.options
,
2874 ps
= self
.containerSize
, co
= self
.containerOffset
, cs
= self
.size
, cp
= self
.position
,
2875 pRatio
= self
._aspectRatio
|| event
.shiftKey
, cop
= { top
:0, left
:0 }, ce
= self
.containerElement
;
2877 if (ce
[0] != document
&& (/static/).test(ce
.css('position'))) cop
= co
;
2879 if (cp
.left
< (self
._helper
? co
.left
: 0)) {
2880 self
.size
.width
= self
.size
.width
+ (self
._helper
? (self
.position
.left
- co
.left
) : (self
.position
.left
- cop
.left
));
2881 if (pRatio
) self
.size
.height
= self
.size
.width
/ self
.aspectRatio
;
2882 self
.position
.left
= o
.helper
? co
.left
: 0;
2885 if (cp
.top
< (self
._helper
? co
.top
: 0)) {
2886 self
.size
.height
= self
.size
.height
+ (self
._helper
? (self
.position
.top
- co
.top
) : self
.position
.top
);
2887 if (pRatio
) self
.size
.width
= self
.size
.height
* self
.aspectRatio
;
2888 self
.position
.top
= self
._helper
? co
.top
: 0;
2891 self
.offset
.left
= self
.parentData
.left
+self
.position
.left
;
2892 self
.offset
.top
= self
.parentData
.top
+self
.position
.top
;
2894 var woset
= Math
.abs( (self
._helper
? self
.offset
.left
- cop
.left
: (self
.offset
.left
- cop
.left
)) + self
.sizeDiff
.width
),
2895 hoset
= Math
.abs( (self
._helper
? self
.offset
.top
- cop
.top
: (self
.offset
.top
- co
.top
)) + self
.sizeDiff
.height
);
2897 var isParent
= self
.containerElement
.get(0) == self
.element
.parent().get(0),
2898 isOffsetRelative
= /relative|absolute/.test(self
.containerElement
.css('position'));
2900 if(isParent
&& isOffsetRelative
) woset
-= self
.parentData
.left
;
2902 if (woset
+ self
.size
.width
>= self
.parentData
.width
) {
2903 self
.size
.width
= self
.parentData
.width
- woset
;
2904 if (pRatio
) self
.size
.height
= self
.size
.width
/ self
.aspectRatio
;
2907 if (hoset
+ self
.size
.height
>= self
.parentData
.height
) {
2908 self
.size
.height
= self
.parentData
.height
- hoset
;
2909 if (pRatio
) self
.size
.width
= self
.size
.height
* self
.aspectRatio
;
2913 stop: function(event
, ui
){
2914 var self
= $(this).data("resizable"), o
= self
.options
, cp
= self
.position
,
2915 co
= self
.containerOffset
, cop
= self
.containerPosition
, ce
= self
.containerElement
;
2917 var helper
= $(self
.helper
), ho
= helper
.offset(), w
= helper
.outerWidth() - self
.sizeDiff
.width
, h
= helper
.outerHeight() - self
.sizeDiff
.height
;
2919 if (self
._helper
&& !o
.animate
&& (/relative/).test(ce
.css('position')))
2920 $(this).css({ left
: ho
.left
- cop
.left
- co
.left
, width
: w
, height
: h
});
2922 if (self
._helper
&& !o
.animate
&& (/static/).test(ce
.css('position')))
2923 $(this).css({ left
: ho
.left
- cop
.left
- co
.left
, width
: w
, height
: h
});
2928 $.ui
.plugin
.add("resizable", "ghost", {
2930 start: function(event
, ui
) {
2932 var self
= $(this).data("resizable"), o
= self
.options
, cs
= self
.size
;
2934 self
.ghost
= self
.originalElement
.clone();
2936 .css({ opacity
: .25, display
: 'block', position
: 'relative', height
: cs
.height
, width
: cs
.width
, margin
: 0, left
: 0, top
: 0 })
2937 .addClass('ui-resizable-ghost')
2938 .addClass(typeof o
.ghost
== 'string' ? o
.ghost
: '');
2940 self
.ghost
.appendTo(self
.helper
);
2944 resize: function(event
, ui
){
2945 var self
= $(this).data("resizable"), o
= self
.options
;
2946 if (self
.ghost
) self
.ghost
.css({ position
: 'relative', height
: self
.size
.height
, width
: self
.size
.width
});
2949 stop: function(event
, ui
){
2950 var self
= $(this).data("resizable"), o
= self
.options
;
2951 if (self
.ghost
&& self
.helper
) self
.helper
.get(0).removeChild(self
.ghost
.get(0));
2956 $.ui
.plugin
.add("resizable", "grid", {
2958 resize: function(event
, ui
) {
2959 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
;
2960 o
.grid
= typeof o
.grid
== "number" ? [o
.grid
, o
.grid
] : o
.grid
;
2961 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);
2963 if (/^(se|s|e)$/.test(a
)) {
2964 self
.size
.width
= os
.width
+ ox
;
2965 self
.size
.height
= os
.height
+ oy
;
2967 else if (/^(ne)$/.test(a
)) {
2968 self
.size
.width
= os
.width
+ ox
;
2969 self
.size
.height
= os
.height
+ oy
;
2970 self
.position
.top
= op
.top
- oy
;
2972 else if (/^(sw)$/.test(a
)) {
2973 self
.size
.width
= os
.width
+ ox
;
2974 self
.size
.height
= os
.height
+ oy
;
2975 self
.position
.left
= op
.left
- ox
;
2978 self
.size
.width
= os
.width
+ ox
;
2979 self
.size
.height
= os
.height
+ oy
;
2980 self
.position
.top
= op
.top
- oy
;
2981 self
.position
.left
= op
.left
- ox
;
2987 var num = function(v
) {
2988 return parseInt(v
, 10) || 0;
2991 var isNumber = function(value
) {
2992 return !isNaN(parseInt(value
, 10));
2997 * jQuery UI Selectable 1.8.21
2999 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
3000 * Dual licensed under the MIT or GPL Version 2 licenses.
3001 * http://jquery.org/license
3003 * http://docs.jquery.com/UI/Selectables
3007 * jquery.ui.mouse.js
3008 * jquery.ui.widget.js
3010 (function( $, undefined ) {
3012 $.widget("ui.selectable", $.ui
.mouse
, {
3020 _create: function() {
3023 this.element
.addClass("ui-selectable");
3025 this.dragged
= false;
3027 // cache selectee children based on filter
3029 this.refresh = function() {
3030 selectees
= $(self
.options
.filter
, self
.element
[0]);
3031 selectees
.addClass("ui-selectee");
3032 selectees
.each(function() {
3033 var $this = $(this);
3034 var pos
= $this.offset();
3035 $.data(this, "selectable-item", {
3040 right
: pos
.left
+ $this.outerWidth(),
3041 bottom
: pos
.top
+ $this.outerHeight(),
3042 startselected
: false,
3043 selected
: $this.hasClass('ui-selected'),
3044 selecting
: $this.hasClass('ui-selecting'),
3045 unselecting
: $this.hasClass('ui-unselecting')
3051 this.selectees
= selectees
.addClass("ui-selectee");
3055 this.helper
= $("<div class='ui-selectable-helper'></div>");
3058 destroy: function() {
3060 .removeClass("ui-selectee")
3061 .removeData("selectable-item");
3063 .removeClass("ui-selectable ui-selectable-disabled")
3064 .removeData("selectable")
3065 .unbind(".selectable");
3066 this._mouseDestroy();
3071 _mouseStart: function(event
) {
3074 this.opos
= [event
.pageX
, event
.pageY
];
3076 if (this.options
.disabled
)
3079 var options
= this.options
;
3081 this.selectees
= $(options
.filter
, this.element
[0]);
3083 this._trigger("start", event
);
3085 $(options
.appendTo
).append(this.helper
);
3086 // position helper (lasso)
3088 "left": event
.clientX
,
3089 "top": event
.clientY
,
3094 if (options
.autoRefresh
) {
3098 this.selectees
.filter('.ui-selected').each(function() {
3099 var selectee
= $.data(this, "selectable-item");
3100 selectee
.startselected
= true;
3101 if (!event
.metaKey
&& !event
.ctrlKey
) {
3102 selectee
.$element
.removeClass('ui-selected');
3103 selectee
.selected
= false;
3104 selectee
.$element
.addClass('ui-unselecting');
3105 selectee
.unselecting
= true;
3106 // selectable UNSELECTING callback
3107 self
._trigger("unselecting", event
, {
3108 unselecting
: selectee
.element
3113 $(event
.target
).parents().andSelf().each(function() {
3114 var selectee
= $.data(this, "selectable-item");
3116 var doSelect
= (!event
.metaKey
&& !event
.ctrlKey
) || !selectee
.$element
.hasClass('ui-selected');
3118 .removeClass(doSelect
? "ui-unselecting" : "ui-selected")
3119 .addClass(doSelect
? "ui-selecting" : "ui-unselecting");
3120 selectee
.unselecting
= !doSelect
;
3121 selectee
.selecting
= doSelect
;
3122 selectee
.selected
= doSelect
;
3123 // selectable (UN)SELECTING callback
3125 self
._trigger("selecting", event
, {
3126 selecting
: selectee
.element
3129 self
._trigger("unselecting", event
, {
3130 unselecting
: selectee
.element
3139 _mouseDrag: function(event
) {
3141 this.dragged
= true;
3143 if (this.options
.disabled
)
3146 var options
= this.options
;
3148 var x1
= this.opos
[0], y1
= this.opos
[1], x2
= event
.pageX
, y2
= event
.pageY
;
3149 if (x1
> x2
) { var tmp
= x2
; x2
= x1
; x1
= tmp
; }
3150 if (y1
> y2
) { var tmp
= y2
; y2
= y1
; y1
= tmp
; }
3151 this.helper
.css({left
: x1
, top
: y1
, width
: x2
-x1
, height
: y2
-y1
});
3153 this.selectees
.each(function() {
3154 var selectee
= $.data(this, "selectable-item");
3155 //prevent helper from being selected if appendTo: selectable
3156 if (!selectee
|| selectee
.element
== self
.element
[0])
3159 if (options
.tolerance
== 'touch') {
3160 hit
= ( !(selectee
.left
> x2
|| selectee
.right
< x1
|| selectee
.top
> y2
|| selectee
.bottom
< y1
) );
3161 } else if (options
.tolerance
== 'fit') {
3162 hit
= (selectee
.left
> x1
&& selectee
.right
< x2
&& selectee
.top
> y1
&& selectee
.bottom
< y2
);
3167 if (selectee
.selected
) {
3168 selectee
.$element
.removeClass('ui-selected');
3169 selectee
.selected
= false;
3171 if (selectee
.unselecting
) {
3172 selectee
.$element
.removeClass('ui-unselecting');
3173 selectee
.unselecting
= false;
3175 if (!selectee
.selecting
) {
3176 selectee
.$element
.addClass('ui-selecting');
3177 selectee
.selecting
= true;
3178 // selectable SELECTING callback
3179 self
._trigger("selecting", event
, {
3180 selecting
: selectee
.element
3185 if (selectee
.selecting
) {
3186 if ((event
.metaKey
|| event
.ctrlKey
) && selectee
.startselected
) {
3187 selectee
.$element
.removeClass('ui-selecting');
3188 selectee
.selecting
= false;
3189 selectee
.$element
.addClass('ui-selected');
3190 selectee
.selected
= true;
3192 selectee
.$element
.removeClass('ui-selecting');
3193 selectee
.selecting
= false;
3194 if (selectee
.startselected
) {
3195 selectee
.$element
.addClass('ui-unselecting');
3196 selectee
.unselecting
= true;
3198 // selectable UNSELECTING callback
3199 self
._trigger("unselecting", event
, {
3200 unselecting
: selectee
.element
3204 if (selectee
.selected
) {
3205 if (!event
.metaKey
&& !event
.ctrlKey
&& !selectee
.startselected
) {
3206 selectee
.$element
.removeClass('ui-selected');
3207 selectee
.selected
= false;
3209 selectee
.$element
.addClass('ui-unselecting');
3210 selectee
.unselecting
= true;
3211 // selectable UNSELECTING callback
3212 self
._trigger("unselecting", event
, {
3213 unselecting
: selectee
.element
3223 _mouseStop: function(event
) {
3226 this.dragged
= false;
3228 var options
= this.options
;
3230 $('.ui-unselecting', this.element
[0]).each(function() {
3231 var selectee
= $.data(this, "selectable-item");
3232 selectee
.$element
.removeClass('ui-unselecting');
3233 selectee
.unselecting
= false;
3234 selectee
.startselected
= false;
3235 self
._trigger("unselected", event
, {
3236 unselected
: selectee
.element
3239 $('.ui-selecting', this.element
[0]).each(function() {
3240 var selectee
= $.data(this, "selectable-item");
3241 selectee
.$element
.removeClass('ui-selecting').addClass('ui-selected');
3242 selectee
.selecting
= false;
3243 selectee
.selected
= true;
3244 selectee
.startselected
= true;
3245 self
._trigger("selected", event
, {
3246 selected
: selectee
.element
3249 this._trigger("stop", event
);
3251 this.helper
.remove();
3258 $.extend($.ui
.selectable
, {
3264 * jQuery UI Sortable 1.8.21
3266 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
3267 * Dual licensed under the MIT or GPL Version 2 licenses.
3268 * http://jquery.org/license
3270 * http://docs.jquery.com/UI/Sortables
3274 * jquery.ui.mouse.js
3275 * jquery.ui.widget.js
3277 (function( $, undefined ) {
3279 $.widget("ui.sortable", $.ui
.mouse
, {
3280 widgetEventPrefix
: "sort",
3290 forcePlaceholderSize
: false,
3291 forceHelperSize
: false,
3300 scrollSensitivity
: 20,
3303 tolerance
: "intersect",
3306 _create: function() {
3308 var o
= this.options
;
3309 this.containerCache
= {};
3310 this.element
.addClass("ui-sortable");
3315 //Let's determine if the items are being displayed horizontally
3316 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;
3318 //Let's determine the parent's offset
3319 this.offset
= this.element
.offset();
3321 //Initialize mouse events for interaction
3329 destroy: function() {
3330 $.Widget
.prototype.destroy
.call( this );
3332 .removeClass("ui-sortable ui-sortable-disabled");
3333 this._mouseDestroy();
3335 for ( var i
= this.items
.length
- 1; i
>= 0; i
-- )
3336 this.items
[i
].item
.removeData(this.widgetName
+ "-item");
3341 _setOption: function(key
, value
){
3342 if ( key
=== "disabled" ) {
3343 this.options
[ key
] = value
;
3346 [ value
? "addClass" : "removeClass"]( "ui-sortable-disabled" );
3348 // Don't call widget base _setOption for disable as it adds ui-state-disabled class
3349 $.Widget
.prototype._setOption
.apply(this, arguments
);
3353 _mouseCapture: function(event
, overrideHandle
) {
3356 if (this.reverting
) {
3360 if(this.options
.disabled
|| this.options
.type
== 'static') return false;
3362 //We have to refresh the items data once first
3363 this._refreshItems(event
);
3365 //Find out if the clicked node (or one of its parents) is a actual item in this.items
3366 var currentItem
= null, self
= this, nodes
= $(event
.target
).parents().each(function() {
3367 if($.data(this, that
.widgetName
+ '-item') == self
) {
3368 currentItem
= $(this);
3372 if($.data(event
.target
, that
.widgetName
+ '-item') == self
) currentItem
= $(event
.target
);
3374 if(!currentItem
) return false;
3375 if(this.options
.handle
&& !overrideHandle
) {
3376 var validHandle
= false;
3378 $(this.options
.handle
, currentItem
).find("*").andSelf().each(function() { if(this == event
.target
) validHandle
= true; });
3379 if(!validHandle
) return false;
3382 this.currentItem
= currentItem
;
3383 this._removeCurrentsFromItems();
3388 _mouseStart: function(event
, overrideHandle
, noActivation
) {
3390 var o
= this.options
, self
= this;
3391 this.currentContainer
= this;
3393 //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3394 this.refreshPositions();
3396 //Create and append the visible helper
3397 this.helper
= this._createHelper(event
);
3399 //Cache the helper size
3400 this._cacheHelperProportions();
3403 * - Position generation -
3404 * This block generates everything position related - it's the core of draggables.
3407 //Cache the margins of the original element
3408 this._cacheMargins();
3410 //Get the next scrolling parent
3411 this.scrollParent
= this.helper
.scrollParent();
3413 //The element's absolute position on the page minus margins
3414 this.offset
= this.currentItem
.offset();
3416 top
: this.offset
.top
- this.margins
.top
,
3417 left
: this.offset
.left
- this.margins
.left
3420 $.extend(this.offset
, {
3421 click
: { //Where the click happened, relative to the element
3422 left
: event
.pageX
- this.offset
.left
,
3423 top
: event
.pageY
- this.offset
.top
3425 parent
: this._getParentOffset(),
3426 relative
: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3429 // Only after we got the offset, we can change the helper's position to absolute
3430 // TODO: Still need to figure out a way to make relative sorting possible
3431 this.helper
.css("position", "absolute");
3432 this.cssPosition
= this.helper
.css("position");
3434 //Generate the original position
3435 this.originalPosition
= this._generatePosition(event
);
3436 this.originalPageX
= event
.pageX
;
3437 this.originalPageY
= event
.pageY
;
3439 //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
3440 (o
.cursorAt
&& this._adjustOffsetFromHelper(o
.cursorAt
));
3442 //Cache the former DOM position
3443 this.domPosition
= { prev
: this.currentItem
.prev()[0], parent
: this.currentItem
.parent()[0] };
3445 //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
3446 if(this.helper
[0] != this.currentItem
[0]) {
3447 this.currentItem
.hide();
3450 //Create the placeholder
3451 this._createPlaceholder();
3453 //Set a containment if given in the options
3455 this._setContainment();
3457 if(o
.cursor
) { // cursor option
3458 if ($('body').css("cursor")) this._storedCursor
= $('body').css("cursor");
3459 $('body').css("cursor", o
.cursor
);
3462 if(o
.opacity
) { // opacity option
3463 if (this.helper
.css("opacity")) this._storedOpacity
= this.helper
.css("opacity");
3464 this.helper
.css("opacity", o
.opacity
);
3467 if(o
.zIndex
) { // zIndex option
3468 if (this.helper
.css("zIndex")) this._storedZIndex
= this.helper
.css("zIndex");
3469 this.helper
.css("zIndex", o
.zIndex
);
3473 if(this.scrollParent
[0] != document
&& this.scrollParent
[0].tagName
!= 'HTML')
3474 this.overflowOffset
= this.scrollParent
.offset();
3477 this._trigger("start", event
, this._uiHash());
3479 //Recache the helper size
3480 if(!this._preserveHelperProportions
)
3481 this._cacheHelperProportions();
3484 //Post 'activate' events to possible containers
3486 for (var i
= this.containers
.length
- 1; i
>= 0; i
--) { this.containers
[i
]._trigger("activate", event
, self
._uiHash(this)); }
3489 //Prepare possible droppables
3491 $.ui
.ddmanager
.current
= this;
3493 if ($.ui
.ddmanager
&& !o
.dropBehaviour
)
3494 $.ui
.ddmanager
.prepareOffsets(this, event
);
3496 this.dragging
= true;
3498 this.helper
.addClass("ui-sortable-helper");
3499 this._mouseDrag(event
); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3504 _mouseDrag: function(event
) {
3506 //Compute the helpers position
3507 this.position
= this._generatePosition(event
);
3508 this.positionAbs
= this._convertPositionTo("absolute");
3510 if (!this.lastPositionAbs
) {
3511 this.lastPositionAbs
= this.positionAbs
;
3515 if(this.options
.scroll
) {
3516 var o
= this.options
, scrolled
= false;
3517 if(this.scrollParent
[0] != document
&& this.scrollParent
[0].tagName
!= 'HTML') {
3519 if((this.overflowOffset
.top
+ this.scrollParent
[0].offsetHeight
) - event
.pageY
< o
.scrollSensitivity
)
3520 this.scrollParent
[0].scrollTop
= scrolled
= this.scrollParent
[0].scrollTop
+ o
.scrollSpeed
;
3521 else if(event
.pageY
- this.overflowOffset
.top
< o
.scrollSensitivity
)
3522 this.scrollParent
[0].scrollTop
= scrolled
= this.scrollParent
[0].scrollTop
- o
.scrollSpeed
;
3524 if((this.overflowOffset
.left
+ this.scrollParent
[0].offsetWidth
) - event
.pageX
< o
.scrollSensitivity
)
3525 this.scrollParent
[0].scrollLeft
= scrolled
= this.scrollParent
[0].scrollLeft
+ o
.scrollSpeed
;
3526 else if(event
.pageX
- this.overflowOffset
.left
< o
.scrollSensitivity
)
3527 this.scrollParent
[0].scrollLeft
= scrolled
= this.scrollParent
[0].scrollLeft
- o
.scrollSpeed
;
3531 if(event
.pageY
- $(document
).scrollTop() < o
.scrollSensitivity
)
3532 scrolled
= $(document
).scrollTop($(document
).scrollTop() - o
.scrollSpeed
);
3533 else if($(window
).height() - (event
.pageY
- $(document
).scrollTop()) < o
.scrollSensitivity
)
3534 scrolled
= $(document
).scrollTop($(document
).scrollTop() + o
.scrollSpeed
);
3536 if(event
.pageX
- $(document
).scrollLeft() < o
.scrollSensitivity
)
3537 scrolled
= $(document
).scrollLeft($(document
).scrollLeft() - o
.scrollSpeed
);
3538 else if($(window
).width() - (event
.pageX
- $(document
).scrollLeft()) < o
.scrollSensitivity
)
3539 scrolled
= $(document
).scrollLeft($(document
).scrollLeft() + o
.scrollSpeed
);
3543 if(scrolled
!== false && $.ui
.ddmanager
&& !o
.dropBehaviour
)
3544 $.ui
.ddmanager
.prepareOffsets(this, event
);
3547 //Regenerate the absolute position used for position checks
3548 this.positionAbs
= this._convertPositionTo("absolute");
3550 //Set the helper position
3551 if(!this.options
.axis
|| this.options
.axis
!= "y") this.helper
[0].style
.left
= this.position
.left
+'px';
3552 if(!this.options
.axis
|| this.options
.axis
!= "x") this.helper
[0].style
.top
= this.position
.top
+'px';
3555 for (var i
= this.items
.length
- 1; i
>= 0; i
--) {
3557 //Cache variables and intersection, continue if no intersection
3558 var item
= this.items
[i
], itemElement
= item
.item
[0], intersection
= this._intersectsWithPointer(item
);
3559 if (!intersection
) continue;
3561 if(itemElement
!= this.currentItem
[0] //cannot intersect with itself
3562 && this.placeholder
[intersection
== 1 ? "next" : "prev"]()[0] != itemElement
//no useless actions that have been done before
3563 && !$.ui
.contains(this.placeholder
[0], itemElement
) //no action if the item moved is the parent of the item checked
3564 && (this.options
.type
== 'semi-dynamic' ? !$.ui
.contains(this.element
[0], itemElement
) : true)
3565 //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
3568 this.direction
= intersection
== 1 ? "down" : "up";
3570 if (this.options
.tolerance
== "pointer" || this._intersectsWithSides(item
)) {
3571 this._rearrange(event
, item
);
3576 this._trigger("change", event
, this._uiHash());
3581 //Post events to containers
3582 this._contactContainers(event
);
3584 //Interconnect with droppables
3585 if($.ui
.ddmanager
) $.ui
.ddmanager
.drag(this, event
);
3588 this._trigger('sort', event
, this._uiHash());
3590 this.lastPositionAbs
= this.positionAbs
;
3595 _mouseStop: function(event
, noPropagation
) {
3599 //If we are using droppables, inform the manager about the drop
3600 if ($.ui
.ddmanager
&& !this.options
.dropBehaviour
)
3601 $.ui
.ddmanager
.drop(this, event
);
3603 if(this.options
.revert
) {
3605 var cur
= self
.placeholder
.offset();
3607 self
.reverting
= true;
3609 $(this.helper
).animate({
3610 left
: cur
.left
- this.offset
.parent
.left
- self
.margins
.left
+ (this.offsetParent
[0] == document
.body
? 0 : this.offsetParent
[0].scrollLeft
),
3611 top
: cur
.top
- this.offset
.parent
.top
- self
.margins
.top
+ (this.offsetParent
[0] == document
.body
? 0 : this.offsetParent
[0].scrollTop
)
3612 }, parseInt(this.options
.revert
, 10) || 500, function() {
3616 this._clear(event
, noPropagation
);
3623 cancel: function() {
3629 this._mouseUp({ target
: null });
3631 if(this.options
.helper
== "original")
3632 this.currentItem
.css(this._storedCSS
).removeClass("ui-sortable-helper");
3634 this.currentItem
.show();
3636 //Post deactivating events to containers
3637 for (var i
= this.containers
.length
- 1; i
>= 0; i
--){
3638 this.containers
[i
]._trigger("deactivate", null, self
._uiHash(this));
3639 if(this.containers
[i
].containerCache
.over
) {
3640 this.containers
[i
]._trigger("out", null, self
._uiHash(this));
3641 this.containers
[i
].containerCache
.over
= 0;
3647 if (this.placeholder
) {
3648 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3649 if(this.placeholder
[0].parentNode
) this.placeholder
[0].parentNode
.removeChild(this.placeholder
[0]);
3650 if(this.options
.helper
!= "original" && this.helper
&& this.helper
[0].parentNode
) this.helper
.remove();
3659 if(this.domPosition
.prev
) {
3660 $(this.domPosition
.prev
).after(this.currentItem
);
3662 $(this.domPosition
.parent
).prepend(this.currentItem
);
3670 serialize: function(o
) {
3672 var items
= this._getItemsAsjQuery(o
&& o
.connected
);
3673 var str
= []; o
= o
|| {};
3675 $(items
).each(function() {
3676 var res
= ($(o
.item
|| this).attr(o
.attribute
|| 'id') || '').match(o
.expression
|| (/(.+)[-=_](.+)/));
3677 if(res
) str
.push((o
.key
|| res
[1]+'[]')+'='+(o
.key
&& o
.expression
? res
[1] : res
[2]));
3680 if(!str
.length
&& o
.key
) {
3681 str
.push(o
.key
+ '=');
3684 return str
.join('&');
3688 toArray: function(o
) {
3690 var items
= this._getItemsAsjQuery(o
&& o
.connected
);
3691 var ret
= []; o
= o
|| {};
3693 items
.each(function() { ret
.push($(o
.item
|| this).attr(o
.attribute
|| 'id') || ''); });
3698 /* Be careful with the following core functions */
3699 _intersectsWith: function(item
) {
3701 var x1
= this.positionAbs
.left
,
3702 x2
= x1
+ this.helperProportions
.width
,
3703 y1
= this.positionAbs
.top
,
3704 y2
= y1
+ this.helperProportions
.height
;
3709 b
= t
+ item
.height
;
3711 var dyClick
= this.offset
.click
.top
,
3712 dxClick
= this.offset
.click
.left
;
3714 var isOverElement
= (y1
+ dyClick
) > t
&& (y1
+ dyClick
) < b
&& (x1
+ dxClick
) > l
&& (x1
+ dxClick
) < r
;
3716 if( this.options
.tolerance
== "pointer"
3717 || this.options
.forcePointerForContainers
3718 || (this.options
.tolerance
!= "pointer" && this.helperProportions
[this.floating
? 'width' : 'height'] > item
[this.floating
? 'width' : 'height'])
3720 return isOverElement
;
3723 return (l
< x1
+ (this.helperProportions
.width
/ 2) // Right Half
3724 && x2
- (this.helperProportions
.width
/ 2) < r
// Left Half
3725 && t
< y1
+ (this.helperProportions
.height
/ 2) // Bottom Half
3726 && y2
- (this.helperProportions
.height
/ 2) < b
); // Top Half
3731 _intersectsWithPointer: function(item
) {
3733 var isOverElementHeight
= (this.options
.axis
=== 'x') || $.ui
.isOverAxis(this.positionAbs
.top
+ this.offset
.click
.top
, item
.top
, item
.height
),
3734 isOverElementWidth
= (this.options
.axis
=== 'y') || $.ui
.isOverAxis(this.positionAbs
.left
+ this.offset
.click
.left
, item
.left
, item
.width
),
3735 isOverElement
= isOverElementHeight
&& isOverElementWidth
,
3736 verticalDirection
= this._getDragVerticalDirection(),
3737 horizontalDirection
= this._getDragHorizontalDirection();
3742 return this.floating
?
3743 ( ((horizontalDirection
&& horizontalDirection
== "right") || verticalDirection
== "down") ? 2 : 1 )
3744 : ( verticalDirection
&& (verticalDirection
== "down" ? 2 : 1) );
3748 _intersectsWithSides: function(item
) {
3750 var isOverBottomHalf
= $.ui
.isOverAxis(this.positionAbs
.top
+ this.offset
.click
.top
, item
.top
+ (item
.height
/2), item
.height
),
3751 isOverRightHalf
= $.ui
.isOverAxis(this.positionAbs
.left
+ this.offset
.click
.left
, item
.left
+ (item
.width
/2), item
.width
),
3752 verticalDirection
= this._getDragVerticalDirection(),
3753 horizontalDirection
= this._getDragHorizontalDirection();
3755 if (this.floating
&& horizontalDirection
) {
3756 return ((horizontalDirection
== "right" && isOverRightHalf
) || (horizontalDirection
== "left" && !isOverRightHalf
));
3758 return verticalDirection
&& ((verticalDirection
== "down" && isOverBottomHalf
) || (verticalDirection
== "up" && !isOverBottomHalf
));
3763 _getDragVerticalDirection: function() {
3764 var delta
= this.positionAbs
.top
- this.lastPositionAbs
.top
;
3765 return delta
!= 0 && (delta
> 0 ? "down" : "up");
3768 _getDragHorizontalDirection: function() {
3769 var delta
= this.positionAbs
.left
- this.lastPositionAbs
.left
;
3770 return delta
!= 0 && (delta
> 0 ? "right" : "left");
3773 refresh: function(event
) {
3774 this._refreshItems(event
);
3775 this.refreshPositions();
3779 _connectWith: function() {
3780 var options
= this.options
;
3781 return options
.connectWith
.constructor == String
3782 ? [options
.connectWith
]
3783 : options
.connectWith
;
3786 _getItemsAsjQuery: function(connected
) {
3791 var connectWith
= this._connectWith();
3793 if(connectWith
&& connected
) {
3794 for (var i
= connectWith
.length
- 1; i
>= 0; i
--){
3795 var cur
= $(connectWith
[i
]);
3796 for (var j
= cur
.length
- 1; j
>= 0; j
--){
3797 var inst
= $.data(cur
[j
], this.widgetName
);
3798 if(inst
&& inst
!= this && !inst
.options
.disabled
) {
3799 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
]);
3805 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]);
3807 for (var i
= queries
.length
- 1; i
>= 0; i
--){
3808 queries
[i
][0].each(function() {
3817 _removeCurrentsFromItems: function() {
3819 var list
= this.currentItem
.find(":data(" + this.widgetName
+ "-item)");
3821 for (var i
=0; i
< this.items
.length
; i
++) {
3823 for (var j
=0; j
< list
.length
; j
++) {
3824 if(list
[j
] == this.items
[i
].item
[0])
3825 this.items
.splice(i
,1);
3832 _refreshItems: function(event
) {
3835 this.containers
= [this];
3836 var items
= this.items
;
3838 var queries
= [[$.isFunction(this.options
.items
) ? this.options
.items
.call(this.element
[0], event
, { item
: this.currentItem
}) : $(this.options
.items
, this.element
), this]];
3839 var connectWith
= this._connectWith();
3841 if(connectWith
&& this.ready
) { //Shouldn't be run the first time through due to massive slow-down
3842 for (var i
= connectWith
.length
- 1; i
>= 0; i
--){
3843 var cur
= $(connectWith
[i
]);
3844 for (var j
= cur
.length
- 1; j
>= 0; j
--){
3845 var inst
= $.data(cur
[j
], this.widgetName
);
3846 if(inst
&& inst
!= this && !inst
.options
.disabled
) {
3847 queries
.push([$.isFunction(inst
.options
.items
) ? inst
.options
.items
.call(inst
.element
[0], event
, { item
: this.currentItem
}) : $(inst
.options
.items
, inst
.element
), inst
]);
3848 this.containers
.push(inst
);
3854 for (var i
= queries
.length
- 1; i
>= 0; i
--) {
3855 var targetData
= queries
[i
][1];
3856 var _queries
= queries
[i
][0];
3858 for (var j
=0, queriesLength
= _queries
.length
; j
< queriesLength
; j
++) {
3859 var item
= $(_queries
[j
]);
3861 item
.data(this.widgetName
+ '-item', targetData
); // Data for target checking (mouse manager)
3865 instance
: targetData
,
3866 width
: 0, height
: 0,
3874 refreshPositions: function(fast
) {
3876 //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
3877 if(this.offsetParent
&& this.helper
) {
3878 this.offset
.parent
= this._getParentOffset();
3881 for (var i
= this.items
.length
- 1; i
>= 0; i
--){
3882 var item
= this.items
[i
];
3884 //We ignore calculating positions of all connected containers when we're not over them
3885 if(item
.instance
!= this.currentContainer
&& this.currentContainer
&& item
.item
[0] != this.currentItem
[0])
3888 var t
= this.options
.toleranceElement
? $(this.options
.toleranceElement
, item
.item
) : item
.item
;
3891 item
.width
= t
.outerWidth();
3892 item
.height
= t
.outerHeight();
3900 if(this.options
.custom
&& this.options
.custom
.refreshContainers
) {
3901 this.options
.custom
.refreshContainers
.call(this);
3903 for (var i
= this.containers
.length
- 1; i
>= 0; i
--){
3904 var p
= this.containers
[i
].element
.offset();
3905 this.containers
[i
].containerCache
.left
= p
.left
;
3906 this.containers
[i
].containerCache
.top
= p
.top
;
3907 this.containers
[i
].containerCache
.width
= this.containers
[i
].element
.outerWidth();
3908 this.containers
[i
].containerCache
.height
= this.containers
[i
].element
.outerHeight();
3915 _createPlaceholder: function(that
) {
3917 var self
= that
|| this, o
= self
.options
;
3919 if(!o
.placeholder
|| o
.placeholder
.constructor == String
) {
3920 var className
= o
.placeholder
;
3922 element: function() {
3924 var el
= $(document
.createElement(self
.currentItem
[0].nodeName
))
3925 .addClass(className
|| self
.currentItem
[0].className
+" ui-sortable-placeholder")
3926 .removeClass("ui-sortable-helper")[0];
3929 el
.style
.visibility
= "hidden";
3933 update: function(container
, p
) {
3935 // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
3936 // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
3937 if(className
&& !o
.forcePlaceholderSize
) return;
3939 //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
3940 if(!p
.height()) { p
.height(self
.currentItem
.innerHeight() - parseInt(self
.currentItem
.css('paddingTop')||0, 10) - parseInt(self
.currentItem
.css('paddingBottom')||0, 10)); };
3941 if(!p
.width()) { p
.width(self
.currentItem
.innerWidth() - parseInt(self
.currentItem
.css('paddingLeft')||0, 10) - parseInt(self
.currentItem
.css('paddingRight')||0, 10)); };
3946 //Create the placeholder
3947 self
.placeholder
= $(o
.placeholder
.element
.call(self
.element
, self
.currentItem
));
3949 //Append it after the actual current item
3950 self
.currentItem
.after(self
.placeholder
);
3952 //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
3953 o
.placeholder
.update(self
, self
.placeholder
);
3957 _contactContainers: function(event
) {
3959 // get innermost container that intersects with item
3960 var innermostContainer
= null, innermostIndex
= null;
3963 for (var i
= this.containers
.length
- 1; i
>= 0; i
--){
3965 // never consider a container that's located within the item itself
3966 if($.ui
.contains(this.currentItem
[0], this.containers
[i
].element
[0]))
3969 if(this._intersectsWith(this.containers
[i
].containerCache
)) {
3971 // if we've already found a container and it's more "inner" than this, then continue
3972 if(innermostContainer
&& $.ui
.contains(this.containers
[i
].element
[0], innermostContainer
.element
[0]))
3975 innermostContainer
= this.containers
[i
];
3979 // container doesn't intersect. trigger "out" event if necessary
3980 if(this.containers
[i
].containerCache
.over
) {
3981 this.containers
[i
]._trigger("out", event
, this._uiHash(this));
3982 this.containers
[i
].containerCache
.over
= 0;
3988 // if no intersecting containers found, return
3989 if(!innermostContainer
) return;
3991 // move the item into the container if it's not there already
3992 if(this.containers
.length
=== 1) {
3993 this.containers
[innermostIndex
]._trigger("over", event
, this._uiHash(this));
3994 this.containers
[innermostIndex
].containerCache
.over
= 1;
3995 } else if(this.currentContainer
!= this.containers
[innermostIndex
]) {
3997 //When entering a new container, we will find the item with the least distance and append our item near it
3998 var dist
= 10000; var itemWithLeastDistance
= null; var base
= this.positionAbs
[this.containers
[innermostIndex
].floating
? 'left' : 'top'];
3999 for (var j
= this.items
.length
- 1; j
>= 0; j
--) {
4000 if(!$.ui
.contains(this.containers
[innermostIndex
].element
[0], this.items
[j
].item
[0])) continue;
4001 var cur
= this.containers
[innermostIndex
].floating
? this.items
[j
].item
.offset().left
: this.items
[j
].item
.offset().top
;
4002 if(Math
.abs(cur
- base
) < dist
) {
4003 dist
= Math
.abs(cur
- base
); itemWithLeastDistance
= this.items
[j
];
4004 this.direction
= (cur
- base
> 0) ? 'down' : 'up';
4008 if(!itemWithLeastDistance
&& !this.options
.dropOnEmpty
) //Check if dropOnEmpty is enabled
4011 this.currentContainer
= this.containers
[innermostIndex
];
4012 itemWithLeastDistance
? this._rearrange(event
, itemWithLeastDistance
, null, true) : this._rearrange(event
, null, this.containers
[innermostIndex
].element
, true);
4013 this._trigger("change", event
, this._uiHash());
4014 this.containers
[innermostIndex
]._trigger("change", event
, this._uiHash(this));
4016 //Update the placeholder
4017 this.options
.placeholder
.update(this.currentContainer
, this.placeholder
);
4019 this.containers
[innermostIndex
]._trigger("over", event
, this._uiHash(this));
4020 this.containers
[innermostIndex
].containerCache
.over
= 1;
4026 _createHelper: function(event
) {
4028 var o
= this.options
;
4029 var helper
= $.isFunction(o
.helper
) ? $(o
.helper
.apply(this.element
[0], [event
, this.currentItem
])) : (o
.helper
== 'clone' ? this.currentItem
.clone() : this.currentItem
);
4031 if(!helper
.parents('body').length
) //Add the helper to the DOM if that didn't happen already
4032 $(o
.appendTo
!= 'parent' ? o
.appendTo
: this.currentItem
[0].parentNode
)[0].appendChild(helper
[0]);
4034 if(helper
[0] == this.currentItem
[0])
4035 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") };
4037 if(helper
[0].style
.width
== '' || o
.forceHelperSize
) helper
.width(this.currentItem
.width());
4038 if(helper
[0].style
.height
== '' || o
.forceHelperSize
) helper
.height(this.currentItem
.height());
4044 _adjustOffsetFromHelper: function(obj
) {
4045 if (typeof obj
== 'string') {
4046 obj
= obj
.split(' ');
4048 if ($.isArray(obj
)) {
4049 obj
= {left
: +obj
[0], top
: +obj
[1] || 0};
4051 if ('left' in obj
) {
4052 this.offset
.click
.left
= obj
.left
+ this.margins
.left
;
4054 if ('right' in obj
) {
4055 this.offset
.click
.left
= this.helperProportions
.width
- obj
.right
+ this.margins
.left
;
4058 this.offset
.click
.top
= obj
.top
+ this.margins
.top
;
4060 if ('bottom' in obj
) {
4061 this.offset
.click
.top
= this.helperProportions
.height
- obj
.bottom
+ this.margins
.top
;
4065 _getParentOffset: function() {
4068 //Get the offsetParent and cache its position
4069 this.offsetParent
= this.helper
.offsetParent();
4070 var po
= this.offsetParent
.offset();
4072 // This is a special case where we need to modify a offset calculated on start, since the following happened:
4073 // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4074 // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4075 // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4076 if(this.cssPosition
== 'absolute' && this.scrollParent
[0] != document
&& $.ui
.contains(this.scrollParent
[0], this.offsetParent
[0])) {
4077 po
.left
+= this.scrollParent
.scrollLeft();
4078 po
.top
+= this.scrollParent
.scrollTop();
4081 if((this.offsetParent
[0] == document
.body
) //This needs to be actually done for all browsers, since pageX/pageY includes this information
4082 || (this.offsetParent
[0].tagName
&& this.offsetParent
[0].tagName
.toLowerCase() == 'html' && $.browser
.msie
)) //Ugly IE fix
4083 po
= { top
: 0, left
: 0 };
4086 top
: po
.top
+ (parseInt(this.offsetParent
.css("borderTopWidth"),10) || 0),
4087 left
: po
.left
+ (parseInt(this.offsetParent
.css("borderLeftWidth"),10) || 0)
4092 _getRelativeOffset: function() {
4094 if(this.cssPosition
== "relative") {
4095 var p
= this.currentItem
.position();
4097 top
: p
.top
- (parseInt(this.helper
.css("top"),10) || 0) + this.scrollParent
.scrollTop(),
4098 left
: p
.left
- (parseInt(this.helper
.css("left"),10) || 0) + this.scrollParent
.scrollLeft()
4101 return { top
: 0, left
: 0 };
4106 _cacheMargins: function() {
4108 left
: (parseInt(this.currentItem
.css("marginLeft"),10) || 0),
4109 top
: (parseInt(this.currentItem
.css("marginTop"),10) || 0)
4113 _cacheHelperProportions: function() {
4114 this.helperProportions
= {
4115 width
: this.helper
.outerWidth(),
4116 height
: this.helper
.outerHeight()
4120 _setContainment: function() {
4122 var o
= this.options
;
4123 if(o
.containment
== 'parent') o
.containment
= this.helper
[0].parentNode
;
4124 if(o
.containment
== 'document' || o
.containment
== 'window') this.containment
= [
4125 0 - this.offset
.relative
.left
- this.offset
.parent
.left
,
4126 0 - this.offset
.relative
.top
- this.offset
.parent
.top
,
4127 $(o
.containment
== 'document' ? document
: window
).width() - this.helperProportions
.width
- this.margins
.left
,
4128 ($(o
.containment
== 'document' ? document
: window
).height() || document
.body
.parentNode
.scrollHeight
) - this.helperProportions
.height
- this.margins
.top
4131 if(!(/^(document|window|parent)$/).test(o
.containment
)) {
4132 var ce
= $(o
.containment
)[0];
4133 var co
= $(o
.containment
).offset();
4134 var over
= ($(ce
).css("overflow") != 'hidden');
4136 this.containment
= [
4137 co
.left
+ (parseInt($(ce
).css("borderLeftWidth"),10) || 0) + (parseInt($(ce
).css("paddingLeft"),10) || 0) - this.margins
.left
,
4138 co
.top
+ (parseInt($(ce
).css("borderTopWidth"),10) || 0) + (parseInt($(ce
).css("paddingTop"),10) || 0) - this.margins
.top
,
4139 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
,
4140 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
4146 _convertPositionTo: function(d
, pos
) {
4148 if(!pos
) pos
= this.position
;
4149 var mod
= d
== "absolute" ? 1 : -1;
4150 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
);
4154 pos
.top
// The absolute mouse position
4155 + this.offset
.relative
.top
* mod
// Only for relative positioned nodes: Relative offset from element to offset parent
4156 + this.offset
.parent
.top
* mod
// The offsetParent's offset without borders (offset + border)
4157 - ($.browser
.safari
&& this.cssPosition
== 'fixed' ? 0 : ( this.cssPosition
== 'fixed' ? -this.scrollParent
.scrollTop() : ( scrollIsRootNode
? 0 : scroll
.scrollTop() ) ) * mod
)
4160 pos
.left
// The absolute mouse position
4161 + this.offset
.relative
.left
* mod
// Only for relative positioned nodes: Relative offset from element to offset parent
4162 + this.offset
.parent
.left
* mod
// The offsetParent's offset without borders (offset + border)
4163 - ($.browser
.safari
&& this.cssPosition
== 'fixed' ? 0 : ( this.cssPosition
== 'fixed' ? -this.scrollParent
.scrollLeft() : scrollIsRootNode
? 0 : scroll
.scrollLeft() ) * mod
)
4169 _generatePosition: function(event
) {
4171 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
);
4173 // This is another very weird special case that only happens for relative elements:
4174 // 1. If the css position is relative
4175 // 2. and the scroll parent is the document or similar to the offset parent
4176 // we have to refresh the relative offset during the scroll so there are no jumps
4177 if(this.cssPosition
== 'relative' && !(this.scrollParent
[0] != document
&& this.scrollParent
[0] != this.offsetParent
[0])) {
4178 this.offset
.relative
= this._getRelativeOffset();
4181 var pageX
= event
.pageX
;
4182 var pageY
= event
.pageY
;
4185 * - Position constraining -
4186 * Constrain the position to a mix of grid, containment.
4189 if(this.originalPosition
) { //If we are not dragging yet, we won't check for options
4191 if(this.containment
) {
4192 if(event
.pageX
- this.offset
.click
.left
< this.containment
[0]) pageX
= this.containment
[0] + this.offset
.click
.left
;
4193 if(event
.pageY
- this.offset
.click
.top
< this.containment
[1]) pageY
= this.containment
[1] + this.offset
.click
.top
;
4194 if(event
.pageX
- this.offset
.click
.left
> this.containment
[2]) pageX
= this.containment
[2] + this.offset
.click
.left
;
4195 if(event
.pageY
- this.offset
.click
.top
> this.containment
[3]) pageY
= this.containment
[3] + this.offset
.click
.top
;
4199 var top
= this.originalPageY
+ Math
.round((pageY
- this.originalPageY
) / o
.grid
[1]) * o
.grid
[1];
4200 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
;
4202 var left
= this.originalPageX
+ Math
.round((pageX
- this.originalPageX
) / o
.grid
[0]) * o
.grid
[0];
4203 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
;
4210 pageY
// The absolute mouse position
4211 - this.offset
.click
.top
// Click offset (relative to the element)
4212 - this.offset
.relative
.top
// Only for relative positioned nodes: Relative offset from element to offset parent
4213 - this.offset
.parent
.top
// The offsetParent's offset without borders (offset + border)
4214 + ($.browser
.safari
&& this.cssPosition
== 'fixed' ? 0 : ( this.cssPosition
== 'fixed' ? -this.scrollParent
.scrollTop() : ( scrollIsRootNode
? 0 : scroll
.scrollTop() ) ))
4217 pageX
// The absolute mouse position
4218 - this.offset
.click
.left
// Click offset (relative to the element)
4219 - this.offset
.relative
.left
// Only for relative positioned nodes: Relative offset from element to offset parent
4220 - this.offset
.parent
.left
// The offsetParent's offset without borders (offset + border)
4221 + ($.browser
.safari
&& this.cssPosition
== 'fixed' ? 0 : ( this.cssPosition
== 'fixed' ? -this.scrollParent
.scrollLeft() : scrollIsRootNode
? 0 : scroll
.scrollLeft() ))
4227 _rearrange: function(event
, i
, a
, hardRefresh
) {
4229 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
));
4231 //Various things done here to improve the performance:
4232 // 1. we create a setTimeout, that calls refreshPositions
4233 // 2. on the instance, we have a counter variable, that get's higher after every append
4234 // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4235 // 4. this lets only the last addition to the timeout stack through
4236 this.counter
= this.counter
? ++this.counter
: 1;
4237 var self
= this, counter
= this.counter
;
4239 window
.setTimeout(function() {
4240 if(counter
== self
.counter
) self
.refreshPositions(!hardRefresh
); //Precompute after each DOM insertion, NOT on mousemove
4245 _clear: function(event
, noPropagation
) {
4247 this.reverting
= false;
4248 // We delay all events that have to be triggered to after the point where the placeholder has been removed and
4249 // everything else normalized again
4250 var delayedTriggers
= [], self
= this;
4252 // We first have to update the dom position of the actual currentItem
4253 // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4254 if(!this._noFinalSort
&& this.currentItem
.parent().length
) this.placeholder
.before(this.currentItem
);
4255 this._noFinalSort
= null;
4257 if(this.helper
[0] == this.currentItem
[0]) {
4258 for(var i
in this._storedCSS
) {
4259 if(this._storedCSS
[i
] == 'auto' || this._storedCSS
[i
] == 'static') this._storedCSS
[i
] = '';
4261 this.currentItem
.css(this._storedCSS
).removeClass("ui-sortable-helper");
4263 this.currentItem
.show();
4266 if(this.fromOutside
&& !noPropagation
) delayedTriggers
.push(function(event
) { this._trigger("receive", event
, this._uiHash(this.fromOutside
)); });
4267 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
4268 if(!$.ui
.contains(this.element
[0], this.currentItem
[0])) { //Node was moved out of the current element
4269 if(!noPropagation
) delayedTriggers
.push(function(event
) { this._trigger("remove", event
, this._uiHash()); });
4270 for (var i
= this.containers
.length
- 1; i
>= 0; i
--){
4271 if($.ui
.contains(this.containers
[i
].element
[0], this.currentItem
[0]) && !noPropagation
) {
4272 delayedTriggers
.push((function(c
) { return function(event
) { c
._trigger("receive", event
, this._uiHash(this)); }; }).call(this, this.containers
[i
]));
4273 delayedTriggers
.push((function(c
) { return function(event
) { c
._trigger("update", event
, this._uiHash(this)); }; }).call(this, this.containers
[i
]));
4278 //Post events to containers
4279 for (var i
= this.containers
.length
- 1; i
>= 0; i
--){
4280 if(!noPropagation
) delayedTriggers
.push((function(c
) { return function(event
) { c
._trigger("deactivate", event
, this._uiHash(this)); }; }).call(this, this.containers
[i
]));
4281 if(this.containers
[i
].containerCache
.over
) {
4282 delayedTriggers
.push((function(c
) { return function(event
) { c
._trigger("out", event
, this._uiHash(this)); }; }).call(this, this.containers
[i
]));
4283 this.containers
[i
].containerCache
.over
= 0;
4287 //Do what was originally in plugins
4288 if(this._storedCursor
) $('body').css("cursor", this._storedCursor
); //Reset cursor
4289 if(this._storedOpacity
) this.helper
.css("opacity", this._storedOpacity
); //Reset opacity
4290 if(this._storedZIndex
) this.helper
.css("zIndex", this._storedZIndex
== 'auto' ? '' : this._storedZIndex
); //Reset z-index
4292 this.dragging
= false;
4293 if(this.cancelHelperRemoval
) {
4294 if(!noPropagation
) {
4295 this._trigger("beforeStop", event
, this._uiHash());
4296 for (var i
=0; i
< delayedTriggers
.length
; i
++) { delayedTriggers
[i
].call(this, event
); }; //Trigger all delayed events
4297 this._trigger("stop", event
, this._uiHash());
4302 if(!noPropagation
) this._trigger("beforeStop", event
, this._uiHash());
4304 //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4305 this.placeholder
[0].parentNode
.removeChild(this.placeholder
[0]);
4307 if(this.helper
[0] != this.currentItem
[0]) this.helper
.remove(); this.helper
= null;
4309 if(!noPropagation
) {
4310 for (var i
=0; i
< delayedTriggers
.length
; i
++) { delayedTriggers
[i
].call(this, event
); }; //Trigger all delayed events
4311 this._trigger("stop", event
, this._uiHash());
4314 this.fromOutside
= false;
4319 _trigger: function() {
4320 if ($.Widget
.prototype._trigger
.apply(this, arguments
) === false) {
4325 _uiHash: function(inst
) {
4326 var self
= inst
|| this;
4328 helper
: self
.helper
,
4329 placeholder
: self
.placeholder
|| $([]),
4330 position
: self
.position
,
4331 originalPosition
: self
.originalPosition
,
4332 offset
: self
.positionAbs
,
4333 item
: self
.currentItem
,
4334 sender
: inst
? inst
.element
: null
4340 $.extend($.ui
.sortable
, {
4346 * jQuery UI Accordion 1.8.21
4348 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
4349 * Dual licensed under the MIT or GPL Version 2 licenses.
4350 * http://jquery.org/license
4352 * http://docs.jquery.com/UI/Accordion
4356 * jquery.ui.widget.js
4358 (function( $, undefined ) {
4360 $.widget( "ui.accordion", {
4369 header
: "> li > :first-child,> :not(li):even",
4371 header
: "ui-icon-triangle-1-e",
4372 headerSelected
: "ui-icon-triangle-1-s"
4375 navigationFilter: function() {
4376 return this.href
.toLowerCase() === location
.href
.toLowerCase();
4380 _create: function() {
4382 options
= self
.options
;
4387 .addClass( "ui-accordion ui-widget ui-helper-reset" )
4388 // in lack of child-selectors in CSS
4389 // we need to mark top-LIs in a UL-accordion for some IE-fix
4391 .addClass( "ui-accordion-li-fix" );
4393 self
.headers
= self
.element
.find( options
.header
)
4394 .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" )
4395 .bind( "mouseenter.accordion", function() {
4396 if ( options
.disabled
) {
4399 $( this ).addClass( "ui-state-hover" );
4401 .bind( "mouseleave.accordion", function() {
4402 if ( options
.disabled
) {
4405 $( this ).removeClass( "ui-state-hover" );
4407 .bind( "focus.accordion", function() {
4408 if ( options
.disabled
) {
4411 $( this ).addClass( "ui-state-focus" );
4413 .bind( "blur.accordion", function() {
4414 if ( options
.disabled
) {
4417 $( this ).removeClass( "ui-state-focus" );
4421 .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" );
4423 if ( options
.navigation
) {
4424 var current
= self
.element
.find( "a" ).filter( options
.navigationFilter
).eq( 0 );
4425 if ( current
.length
) {
4426 var header
= current
.closest( ".ui-accordion-header" );
4427 if ( header
.length
) {
4428 // anchor within header
4429 self
.active
= header
;
4431 // anchor within content
4432 self
.active
= current
.closest( ".ui-accordion-content" ).prev();
4437 self
.active
= self
._findActive( self
.active
|| options
.active
)
4438 .addClass( "ui-state-default ui-state-active" )
4439 .toggleClass( "ui-corner-all" )
4440 .toggleClass( "ui-corner-top" );
4441 self
.active
.next().addClass( "ui-accordion-content-active" );
4443 self
._createIcons();
4447 self
.element
.attr( "role", "tablist" );
4450 .attr( "role", "tab" )
4451 .bind( "keydown.accordion", function( event
) {
4452 return self
._keydown( event
);
4455 .attr( "role", "tabpanel" );
4458 .not( self
.active
|| "" )
4460 "aria-expanded": "false",
4461 "aria-selected": "false",
4467 // make sure at least one header is in the tab order
4468 if ( !self
.active
.length
) {
4469 self
.headers
.eq( 0 ).attr( "tabIndex", 0 );
4473 "aria-expanded": "true",
4474 "aria-selected": "true",
4479 // only need links in tab order for Safari
4480 if ( !$.browser
.safari
) {
4481 self
.headers
.find( "a" ).attr( "tabIndex", -1 );
4484 if ( options
.event
) {
4485 self
.headers
.bind( options
.event
.split(" ").join(".accordion ") + ".accordion", function(event
) {
4486 self
._clickHandler
.call( self
, event
, this );
4487 event
.preventDefault();
4492 _createIcons: function() {
4493 var options
= this.options
;
4494 if ( options
.icons
) {
4495 $( "<span></span>" )
4496 .addClass( "ui-icon " + options
.icons
.header
)
4497 .prependTo( this.headers
);
4498 this.active
.children( ".ui-icon" )
4499 .toggleClass(options
.icons
.header
)
4500 .toggleClass(options
.icons
.headerSelected
);
4501 this.element
.addClass( "ui-accordion-icons" );
4505 _destroyIcons: function() {
4506 this.headers
.children( ".ui-icon" ).remove();
4507 this.element
.removeClass( "ui-accordion-icons" );
4510 destroy: function() {
4511 var options
= this.options
;
4514 .removeClass( "ui-accordion ui-widget ui-helper-reset" )
4515 .removeAttr( "role" );
4518 .unbind( ".accordion" )
4519 .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" )
4520 .removeAttr( "role" )
4521 .removeAttr( "aria-expanded" )
4522 .removeAttr( "aria-selected" )
4523 .removeAttr( "tabIndex" );
4525 this.headers
.find( "a" ).removeAttr( "tabIndex" );
4526 this._destroyIcons();
4527 var contents
= this.headers
.next()
4528 .css( "display", "" )
4529 .removeAttr( "role" )
4530 .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" );
4531 if ( options
.autoHeight
|| options
.fillHeight
) {
4532 contents
.css( "height", "" );
4535 return $.Widget
.prototype.destroy
.call( this );
4538 _setOption: function( key
, value
) {
4539 $.Widget
.prototype._setOption
.apply( this, arguments
);
4541 if ( key
== "active" ) {
4542 this.activate( value
);
4544 if ( key
== "icons" ) {
4545 this._destroyIcons();
4547 this._createIcons();
4550 // #5332 - opacity doesn't cascade to positioned elements in IE
4551 // so we need to add the disabled class to the headers and panels
4552 if ( key
== "disabled" ) {
4553 this.headers
.add(this.headers
.next())
4554 [ value
? "addClass" : "removeClass" ](
4555 "ui-accordion-disabled ui-state-disabled" );
4559 _keydown: function( event
) {
4560 if ( this.options
.disabled
|| event
.altKey
|| event
.ctrlKey
) {
4564 var keyCode
= $.ui
.keyCode
,
4565 length
= this.headers
.length
,
4566 currentIndex
= this.headers
.index( event
.target
),
4569 switch ( event
.keyCode
) {
4572 toFocus
= this.headers
[ ( currentIndex
+ 1 ) % length
];
4576 toFocus
= this.headers
[ ( currentIndex
- 1 + length
) % length
];
4580 this._clickHandler( { target
: event
.target
}, event
.target
);
4581 event
.preventDefault();
4585 $( event
.target
).attr( "tabIndex", -1 );
4586 $( toFocus
).attr( "tabIndex", 0 );
4594 resize: function() {
4595 var options
= this.options
,
4598 if ( options
.fillSpace
) {
4599 if ( $.browser
.msie
) {
4600 var defOverflow
= this.element
.parent().css( "overflow" );
4601 this.element
.parent().css( "overflow", "hidden");
4603 maxHeight
= this.element
.parent().height();
4604 if ($.browser
.msie
) {
4605 this.element
.parent().css( "overflow", defOverflow
);
4608 this.headers
.each(function() {
4609 maxHeight
-= $( this ).outerHeight( true );
4614 $( this ).height( Math
.max( 0, maxHeight
-
4615 $( this ).innerHeight() + $( this ).height() ) );
4617 .css( "overflow", "auto" );
4618 } else if ( options
.autoHeight
) {
4622 maxHeight
= Math
.max( maxHeight
, $( this ).height( "" ).height() );
4624 .height( maxHeight
);
4630 activate: function( index
) {
4631 // TODO this gets called on init, changing the option without an explicit call for that
4632 this.options
.active
= index
;
4633 // call clickHandler with custom event
4634 var active
= this._findActive( index
)[ 0 ];
4635 this._clickHandler( { target
: active
}, active
);
4640 _findActive: function( selector
) {
4642 ? typeof selector
=== "number"
4643 ? this.headers
.filter( ":eq(" + selector
+ ")" )
4644 : this.headers
.not( this.headers
.not( selector
) )
4645 : selector
=== false
4647 : this.headers
.filter( ":eq(0)" );
4650 // TODO isn't event.target enough? why the separate target argument?
4651 _clickHandler: function( event
, target
) {
4652 var options
= this.options
;
4653 if ( options
.disabled
) {
4657 // called only when using activate(false) to close all parts programmatically
4658 if ( !event
.target
) {
4659 if ( !options
.collapsible
) {
4663 .removeClass( "ui-state-active ui-corner-top" )
4664 .addClass( "ui-state-default ui-corner-all" )
4665 .children( ".ui-icon" )
4666 .removeClass( options
.icons
.headerSelected
)
4667 .addClass( options
.icons
.header
);
4668 this.active
.next().addClass( "ui-accordion-content-active" );
4669 var toHide
= this.active
.next(),
4673 oldHeader
: options
.active
,
4674 newContent
: $( [] ),
4677 toShow
= ( this.active
= $( [] ) );
4678 this._toggle( toShow
, toHide
, data
);
4682 // get the click target
4683 var clicked
= $( event
.currentTarget
|| target
),
4684 clickedIsActive
= clicked
[0] === this.active
[0];
4686 // TODO the option is changed, is that correct?
4687 // TODO if it is correct, shouldn't that happen after determining that the click is valid?
4688 options
.active
= options
.collapsible
&& clickedIsActive
?
4690 this.headers
.index( clicked
);
4692 // if animations are still active, or the active header is the target, ignore click
4693 if ( this.running
|| ( !options
.collapsible
&& clickedIsActive
) ) {
4697 // find elements to show and hide
4698 var active
= this.active
,
4699 toShow
= clicked
.next(),
4700 toHide
= this.active
.next(),
4703 newHeader
: clickedIsActive
&& options
.collapsible
? $([]) : clicked
,
4704 oldHeader
: this.active
,
4705 newContent
: clickedIsActive
&& options
.collapsible
? $([]) : toShow
,
4708 down
= this.headers
.index( this.active
[0] ) > this.headers
.index( clicked
[0] );
4710 // when the call to ._toggle() comes after the class changes
4711 // it causes a very odd bug in IE 8 (see #6720)
4712 this.active
= clickedIsActive
? $([]) : clicked
;
4713 this._toggle( toShow
, toHide
, data
, clickedIsActive
, down
);
4717 .removeClass( "ui-state-active ui-corner-top" )
4718 .addClass( "ui-state-default ui-corner-all" )
4719 .children( ".ui-icon" )
4720 .removeClass( options
.icons
.headerSelected
)
4721 .addClass( options
.icons
.header
);
4722 if ( !clickedIsActive
) {
4724 .removeClass( "ui-state-default ui-corner-all" )
4725 .addClass( "ui-state-active ui-corner-top" )
4726 .children( ".ui-icon" )
4727 .removeClass( options
.icons
.header
)
4728 .addClass( options
.icons
.headerSelected
);
4731 .addClass( "ui-accordion-content-active" );
4737 _toggle: function( toShow
, toHide
, data
, clickedIsActive
, down
) {
4739 options
= self
.options
;
4741 self
.toShow
= toShow
;
4742 self
.toHide
= toHide
;
4745 var complete = function() {
4749 return self
._completed
.apply( self
, arguments
);
4752 // trigger changestart event
4753 self
._trigger( "changestart", null, self
.data
);
4755 // count elements to animate
4756 self
.running
= toHide
.size() === 0 ? toShow
.size() : toHide
.size();
4758 if ( options
.animated
) {
4759 var animOptions
= {};
4761 if ( options
.collapsible
&& clickedIsActive
) {
4767 autoHeight
: options
.autoHeight
|| options
.fillSpace
4775 autoHeight
: options
.autoHeight
|| options
.fillSpace
4779 if ( !options
.proxied
) {
4780 options
.proxied
= options
.animated
;
4783 if ( !options
.proxiedDuration
) {
4784 options
.proxiedDuration
= options
.duration
;
4787 options
.animated
= $.isFunction( options
.proxied
) ?
4788 options
.proxied( animOptions
) :
4791 options
.duration
= $.isFunction( options
.proxiedDuration
) ?
4792 options
.proxiedDuration( animOptions
) :
4793 options
.proxiedDuration
;
4795 var animations
= $.ui
.accordion
.animations
,
4796 duration
= options
.duration
,
4797 easing
= options
.animated
;
4799 if ( easing
&& !animations
[ easing
] && !$.easing
[ easing
] ) {
4802 if ( !animations
[ easing
] ) {
4803 animations
[ easing
] = function( options
) {
4804 this.slide( options
, {
4806 duration
: duration
|| 700
4811 animations
[ easing
]( animOptions
);
4813 if ( options
.collapsible
&& clickedIsActive
) {
4823 // TODO assert that the blur and focus triggers are really necessary, remove otherwise
4826 "aria-expanded": "false",
4827 "aria-selected": "false",
4833 "aria-expanded": "true",
4834 "aria-selected": "true",
4840 _completed: function( cancel
) {
4841 this.running
= cancel
? 0 : --this.running
;
4842 if ( this.running
) {
4846 if ( this.options
.clearStyle
) {
4847 this.toShow
.add( this.toHide
).css({
4853 // other classes are removed before the animation; this one needs to stay until completed
4854 this.toHide
.removeClass( "ui-accordion-content-active" );
4855 // Work around for rendering bug in IE (#5421)
4856 if ( this.toHide
.length
) {
4857 this.toHide
.parent()[0].className
= this.toHide
.parent()[0].className
;
4860 this._trigger( "change", null, this.data
);
4864 $.extend( $.ui
.accordion
, {
4867 slide: function( options
, additions
) {
4868 options
= $.extend({
4871 }, options
, additions
);
4872 if ( !options
.toHide
.size() ) {
4873 options
.toShow
.animate({
4876 paddingBottom
: "show"
4880 if ( !options
.toShow
.size() ) {
4881 options
.toHide
.animate({
4884 paddingBottom
: "hide"
4888 var overflow
= options
.toShow
.css( "overflow" ),
4892 fxAttrs
= [ "height", "paddingTop", "paddingBottom" ],
4894 // fix width before calculating height of hidden element
4895 var s
= options
.toShow
;
4896 originalWidth
= s
[0].style
.width
;
4897 s
.width( s
.parent().width()
4898 - parseFloat( s
.css( "paddingLeft" ) )
4899 - parseFloat( s
.css( "paddingRight" ) )
4900 - ( parseFloat( s
.css( "borderLeftWidth" ) ) || 0 )
4901 - ( parseFloat( s
.css( "borderRightWidth" ) ) || 0 ) );
4903 $.each( fxAttrs
, function( i
, prop
) {
4904 hideProps
[ prop
] = "hide";
4906 var parts
= ( "" + $.css( options
.toShow
[0], prop
) ).match( /^([\d+-.]+)(.*)$/ );
4907 showProps
[ prop
] = {
4909 unit
: parts
[ 2 ] || "px"
4912 options
.toShow
.css({ height
: 0, overflow
: "hidden" }).show();
4914 .filter( ":hidden" )
4915 .each( options
.complete
)
4917 .filter( ":visible" )
4918 .animate( hideProps
, {
4919 step: function( now
, settings
) {
4920 // only calculate the percent when animating height
4921 // IE gets very inconsistent results when animating elements
4922 // with small values, which is common for padding
4923 if ( settings
.prop
== "height" ) {
4924 percentDone
= ( settings
.end
- settings
.start
=== 0 ) ? 0 :
4925 ( settings
.now
- settings
.start
) / ( settings
.end
- settings
.start
);
4928 options
.toShow
[ 0 ].style
[ settings
.prop
] =
4929 ( percentDone
* showProps
[ settings
.prop
].value
)
4930 + showProps
[ settings
.prop
].unit
;
4932 duration
: options
.duration
,
4933 easing
: options
.easing
,
4934 complete: function() {
4935 if ( !options
.autoHeight
) {
4936 options
.toShow
.css( "height", "" );
4938 options
.toShow
.css({
4939 width
: originalWidth
,
4946 bounceslide: function( options
) {
4947 this.slide( options
, {
4948 easing
: options
.down
? "easeOutBounce" : "swing",
4949 duration
: options
.down
? 1000 : 200
4957 * jQuery UI Autocomplete 1.8.21
4959 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
4960 * Dual licensed under the MIT or GPL Version 2 licenses.
4961 * http://jquery.org/license
4963 * http://docs.jquery.com/UI/Autocomplete
4967 * jquery.ui.widget.js
4968 * jquery.ui.position.js
4970 (function( $, undefined ) {
4972 // used to prevent race conditions with remote data sources
4973 var requestIndex
= 0;
4975 $.widget( "ui.autocomplete", {
4991 _create: function() {
4993 doc
= this.element
[ 0 ].ownerDocument
,
4995 this.isMultiLine
= this.element
.is( "textarea" );
4998 .addClass( "ui-autocomplete-input" )
4999 .attr( "autocomplete", "off" )
5000 // TODO verify these actually work as intended
5003 "aria-autocomplete": "list",
5004 "aria-haspopup": "true"
5006 .bind( "keydown.autocomplete", function( event
) {
5007 if ( self
.options
.disabled
|| self
.element
.propAttr( "readOnly" ) ) {
5011 suppressKeyPress
= false;
5012 var keyCode
= $.ui
.keyCode
;
5013 switch( event
.keyCode
) {
5014 case keyCode
.PAGE_UP
:
5015 self
._move( "previousPage", event
);
5017 case keyCode
.PAGE_DOWN
:
5018 self
._move( "nextPage", event
);
5021 self
._keyEvent( "previous", event
);
5024 self
._keyEvent( "next", event
);
5027 case keyCode
.NUMPAD_ENTER
:
5028 // when menu is open and has focus
5029 if ( self
.menu
.active
) {
5030 // #6055 - Opera still allows the keypress to occur
5031 // which causes forms to submit
5032 suppressKeyPress
= true;
5033 event
.preventDefault();
5035 //passthrough - ENTER and TAB both select the current element
5037 if ( !self
.menu
.active
) {
5040 self
.menu
.select( event
);
5042 case keyCode
.ESCAPE
:
5043 self
.element
.val( self
.term
);
5044 self
.close( event
);
5047 // keypress is triggered before the input value is changed
5048 clearTimeout( self
.searching
);
5049 self
.searching
= setTimeout(function() {
5050 // only search if the value has changed
5051 if ( self
.term
!= self
.element
.val() ) {
5052 self
.selectedItem
= null;
5053 self
.search( null, event
);
5055 }, self
.options
.delay
);
5059 .bind( "keypress.autocomplete", function( event
) {
5060 if ( suppressKeyPress
) {
5061 suppressKeyPress
= false;
5062 event
.preventDefault();
5065 .bind( "focus.autocomplete", function() {
5066 if ( self
.options
.disabled
) {
5070 self
.selectedItem
= null;
5071 self
.previous
= self
.element
.val();
5073 .bind( "blur.autocomplete", function( event
) {
5074 if ( self
.options
.disabled
) {
5078 clearTimeout( self
.searching
);
5079 // clicks on the menu (or a button to trigger a search) will cause a blur event
5080 self
.closing
= setTimeout(function() {
5081 self
.close( event
);
5082 self
._change( event
);
5086 this.menu
= $( "<ul></ul>" )
5087 .addClass( "ui-autocomplete" )
5088 .appendTo( $( this.options
.appendTo
|| "body", doc
)[0] )
5089 // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown)
5090 .mousedown(function( event
) {
5091 // clicking on the scrollbar causes focus to shift to the body
5092 // but we can't detect a mouseup or a click immediately afterward
5093 // so we have to track the next mousedown and close the menu if
5094 // the user clicks somewhere outside of the autocomplete
5095 var menuElement
= self
.menu
.element
[ 0 ];
5096 if ( !$( event
.target
).closest( ".ui-menu-item" ).length
) {
5097 setTimeout(function() {
5098 $( document
).one( 'mousedown', function( event
) {
5099 if ( event
.target
!== self
.element
[ 0 ] &&
5100 event
.target
!== menuElement
&&
5101 !$.ui
.contains( menuElement
, event
.target
) ) {
5108 // use another timeout to make sure the blur-event-handler on the input was already triggered
5109 setTimeout(function() {
5110 clearTimeout( self
.closing
);
5114 focus: function( event
, ui
) {
5115 var item
= ui
.item
.data( "item.autocomplete" );
5116 if ( false !== self
._trigger( "focus", event
, { item
: item
} ) ) {
5117 // use value to match what will end up in the input, if it was a key event
5118 if ( /^key/.test(event
.originalEvent
.type
) ) {
5119 self
.element
.val( item
.value
);
5123 selected: function( event
, ui
) {
5124 var item
= ui
.item
.data( "item.autocomplete" ),
5125 previous
= self
.previous
;
5127 // only trigger when focus was lost (click on menu)
5128 if ( self
.element
[0] !== doc
.activeElement
) {
5129 self
.element
.focus();
5130 self
.previous
= previous
;
5131 // #6109 - IE triggers two focus events and the second
5132 // is asynchronous, so we need to reset the previous
5133 // term synchronously and asynchronously :-(
5134 setTimeout(function() {
5135 self
.previous
= previous
;
5136 self
.selectedItem
= item
;
5140 if ( false !== self
._trigger( "select", event
, { item
: item
} ) ) {
5141 self
.element
.val( item
.value
);
5143 // reset the term after the select event
5144 // this allows custom select handling to work properly
5145 self
.term
= self
.element
.val();
5147 self
.close( event
);
5148 self
.selectedItem
= item
;
5150 blur: function( event
, ui
) {
5151 // don't set the value of the text field if it's already correct
5152 // this prevents moving the cursor unnecessarily
5153 if ( self
.menu
.element
.is(":visible") &&
5154 ( self
.element
.val() !== self
.term
) ) {
5155 self
.element
.val( self
.term
);
5159 .zIndex( this.element
.zIndex() + 1 )
5160 // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
5161 .css({ top
: 0, left
: 0 })
5164 if ( $.fn
.bgiframe
) {
5165 this.menu
.element
.bgiframe();
5167 // turning off autocomplete prevents the browser from remembering the
5168 // value when navigating through history, so we re-enable autocomplete
5169 // if the page is unloaded before the widget is destroyed. #7790
5170 self
.beforeunloadHandler = function() {
5171 self
.element
.removeAttr( "autocomplete" );
5173 $( window
).bind( "beforeunload", self
.beforeunloadHandler
);
5176 destroy: function() {
5178 .removeClass( "ui-autocomplete-input" )
5179 .removeAttr( "autocomplete" )
5180 .removeAttr( "role" )
5181 .removeAttr( "aria-autocomplete" )
5182 .removeAttr( "aria-haspopup" );
5183 this.menu
.element
.remove();
5184 $( window
).unbind( "beforeunload", this.beforeunloadHandler
);
5185 $.Widget
.prototype.destroy
.call( this );
5188 _setOption: function( key
, value
) {
5189 $.Widget
.prototype._setOption
.apply( this, arguments
);
5190 if ( key
=== "source" ) {
5193 if ( key
=== "appendTo" ) {
5194 this.menu
.element
.appendTo( $( value
|| "body", this.element
[0].ownerDocument
)[0] )
5196 if ( key
=== "disabled" && value
&& this.xhr
) {
5201 _initSource: function() {
5205 if ( $.isArray(this.options
.source
) ) {
5206 array
= this.options
.source
;
5207 this.source = function( request
, response
) {
5208 response( $.ui
.autocomplete
.filter(array
, request
.term
) );
5210 } else if ( typeof this.options
.source
=== "string" ) {
5211 url
= this.options
.source
;
5212 this.source = function( request
, response
) {
5220 success: function( data
, status
) {
5229 this.source
= this.options
.source
;
5233 search: function( value
, event
) {
5234 value
= value
!= null ? value
: this.element
.val();
5236 // always save the actual value, not the one passed as an argument
5237 this.term
= this.element
.val();
5239 if ( value
.length
< this.options
.minLength
) {
5240 return this.close( event
);
5243 clearTimeout( this.closing
);
5244 if ( this._trigger( "search", event
) === false ) {
5248 return this._search( value
);
5251 _search: function( value
) {
5253 this.element
.addClass( "ui-autocomplete-loading" );
5255 this.source( { term
: value
}, this._response() );
5258 _response: function() {
5260 index
= ++requestIndex
;
5262 return function( content
) {
5263 if ( index
=== requestIndex
) {
5264 that
.__response( content
);
5268 if ( !that
.pending
) {
5269 that
.element
.removeClass( "ui-autocomplete-loading" );
5274 __response: function( content
) {
5275 if ( !this.options
.disabled
&& content
&& content
.length
) {
5276 content
= this._normalize( content
);
5277 this._suggest( content
);
5278 this._trigger( "open" );
5284 close: function( event
) {
5285 clearTimeout( this.closing
);
5286 if ( this.menu
.element
.is(":visible") ) {
5287 this.menu
.element
.hide();
5288 this.menu
.deactivate();
5289 this._trigger( "close", event
);
5293 _change: function( event
) {
5294 if ( this.previous
!== this.element
.val() ) {
5295 this._trigger( "change", event
, { item
: this.selectedItem
} );
5299 _normalize: function( items
) {
5300 // assume all items have the right format when the first item is complete
5301 if ( items
.length
&& items
[0].label
&& items
[0].value
) {
5304 return $.map( items
, function(item
) {
5305 if ( typeof item
=== "string" ) {
5312 label
: item
.label
|| item
.value
,
5313 value
: item
.value
|| item
.label
5318 _suggest: function( items
) {
5319 var ul
= this.menu
.element
5321 .zIndex( this.element
.zIndex() + 1 );
5322 this._renderMenu( ul
, items
);
5323 // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate
5324 this.menu
.deactivate();
5325 this.menu
.refresh();
5327 // size and position menu
5330 ul
.position( $.extend({
5332 }, this.options
.position
));
5334 if ( this.options
.autoFocus
) {
5335 this.menu
.next( new $.Event("mouseover") );
5339 _resizeMenu: function() {
5340 var ul
= this.menu
.element
;
5341 ul
.outerWidth( Math
.max(
5342 // Firefox wraps long text (possibly a rounding bug)
5343 // so we add 1px to avoid the wrapping (#7513)
5344 ul
.width( "" ).outerWidth() + 1,
5345 this.element
.outerWidth()
5349 _renderMenu: function( ul
, items
) {
5351 $.each( items
, function( index
, item
) {
5352 self
._renderItem( ul
, item
);
5356 _renderItem: function( ul
, item
) {
5357 return $( "<li></li>" )
5358 .data( "item.autocomplete", item
)
5359 .append( $( "<a></a>" ).text( item
.label
) )
5363 _move: function( direction
, event
) {
5364 if ( !this.menu
.element
.is(":visible") ) {
5365 this.search( null, event
);
5368 if ( this.menu
.first() && /^previous/.test(direction
) ||
5369 this.menu
.last() && /^next/.test(direction
) ) {
5370 this.element
.val( this.term
);
5371 this.menu
.deactivate();
5374 this.menu
[ direction
]( event
);
5377 widget: function() {
5378 return this.menu
.element
;
5380 _keyEvent: function( keyEvent
, event
) {
5381 if ( !this.isMultiLine
|| this.menu
.element
.is( ":visible" ) ) {
5382 this._move( keyEvent
, event
);
5384 // prevents moving cursor to beginning/end of the text field in some browsers
5385 event
.preventDefault();
5390 $.extend( $.ui
.autocomplete
, {
5391 escapeRegex: function( value
) {
5392 return value
.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
5394 filter: function(array
, term
) {
5395 var matcher
= new RegExp( $.ui
.autocomplete
.escapeRegex(term
), "i" );
5396 return $.grep( array
, function(value
) {
5397 return matcher
.test( value
.label
|| value
.value
|| value
);
5405 * jQuery UI Menu (not officially released)
5407 * This widget isn't yet finished and the API is subject to change. We plan to finish
5408 * it for the next release. You're welcome to give it a try anyway and give us feedback,
5409 * as long as you're okay with migrating your code later on. We can help with that, too.
5411 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5412 * Dual licensed under the MIT or GPL Version 2 licenses.
5413 * http://jquery.org/license
5415 * http://docs.jquery.com/UI/Menu
5419 * jquery.ui.widget.js
5423 $.widget("ui.menu", {
5424 _create: function() {
5427 .addClass("ui-menu ui-widget ui-widget-content ui-corner-all")
5430 "aria-activedescendant": "ui-active-menuitem"
5432 .click(function( event
) {
5433 if ( !$( event
.target
).closest( ".ui-menu-item a" ).length
) {
5437 event
.preventDefault();
5438 self
.select( event
);
5443 refresh: function() {
5446 // don't refresh list items that are already adapted
5447 var items
= this.element
.children("li:not(.ui-menu-item):has(a)")
5448 .addClass("ui-menu-item")
5449 .attr("role", "menuitem");
5452 .addClass("ui-corner-all")
5453 .attr("tabindex", -1)
5454 // mouseenter doesn't work with event delegation
5455 .mouseenter(function( event
) {
5456 self
.activate( event
, $(this).parent() );
5458 .mouseleave(function() {
5463 activate: function( event
, item
) {
5465 if (this.hasScroll()) {
5466 var offset
= item
.offset().top
- this.element
.offset().top
,
5467 scroll
= this.element
.scrollTop(),
5468 elementHeight
= this.element
.height();
5470 this.element
.scrollTop( scroll
+ offset
);
5471 } else if (offset
>= elementHeight
) {
5472 this.element
.scrollTop( scroll
+ offset
- elementHeight
+ item
.height());
5475 this.active
= item
.eq(0)
5477 .addClass("ui-state-hover")
5478 .attr("id", "ui-active-menuitem")
5480 this._trigger("focus", event
, { item
: item
});
5483 deactivate: function() {
5484 if (!this.active
) { return; }
5486 this.active
.children("a")
5487 .removeClass("ui-state-hover")
5489 this._trigger("blur");
5493 next: function(event
) {
5494 this.move("next", ".ui-menu-item:first", event
);
5497 previous: function(event
) {
5498 this.move("prev", ".ui-menu-item:last", event
);
5502 return this.active
&& !this.active
.prevAll(".ui-menu-item").length
;
5506 return this.active
&& !this.active
.nextAll(".ui-menu-item").length
;
5509 move: function(direction
, edge
, event
) {
5511 this.activate(event
, this.element
.children(edge
));
5514 var next
= this.active
[direction
+ "All"](".ui-menu-item").eq(0);
5516 this.activate(event
, next
);
5518 this.activate(event
, this.element
.children(edge
));
5522 // TODO merge with previousPage
5523 nextPage: function(event
) {
5524 if (this.hasScroll()) {
5525 // TODO merge with no-scroll-else
5526 if (!this.active
|| this.last()) {
5527 this.activate(event
, this.element
.children(".ui-menu-item:first"));
5530 var base
= this.active
.offset().top
,
5531 height
= this.element
.height(),
5532 result
= this.element
.children(".ui-menu-item").filter(function() {
5533 var close
= $(this).offset().top
- base
- height
+ $(this).height();
5534 // TODO improve approximation
5535 return close
< 10 && close
> -10;
5538 // TODO try to catch this earlier when scrollTop indicates the last page anyway
5539 if (!result
.length
) {
5540 result
= this.element
.children(".ui-menu-item:last");
5542 this.activate(event
, result
);
5544 this.activate(event
, this.element
.children(".ui-menu-item")
5545 .filter(!this.active
|| this.last() ? ":first" : ":last"));
5549 // TODO merge with nextPage
5550 previousPage: function(event
) {
5551 if (this.hasScroll()) {
5552 // TODO merge with no-scroll-else
5553 if (!this.active
|| this.first()) {
5554 this.activate(event
, this.element
.children(".ui-menu-item:last"));
5558 var base
= this.active
.offset().top
,
5559 height
= this.element
.height(),
5560 result
= this.element
.children(".ui-menu-item").filter(function() {
5561 var close
= $(this).offset().top
- base
+ height
- $(this).height();
5562 // TODO improve approximation
5563 return close
< 10 && close
> -10;
5566 // TODO try to catch this earlier when scrollTop indicates the last page anyway
5567 if (!result
.length
) {
5568 result
= this.element
.children(".ui-menu-item:first");
5570 this.activate(event
, result
);
5572 this.activate(event
, this.element
.children(".ui-menu-item")
5573 .filter(!this.active
|| this.first() ? ":last" : ":first"));
5577 hasScroll: function() {
5578 return this.element
.height() < this.element
[ $.fn
.prop
? "prop" : "attr" ]("scrollHeight");
5581 select: function( event
) {
5582 this._trigger("selected", event
, { item
: this.active
});
5588 * jQuery UI Button 1.8.21
5590 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
5591 * Dual licensed under the MIT or GPL Version 2 licenses.
5592 * http://jquery.org/license
5594 * http://docs.jquery.com/UI/Button
5598 * jquery.ui.widget.js
5600 (function( $, undefined ) {
5602 var lastActive
, startXPos
, startYPos
, clickDragged
,
5603 baseClasses
= "ui-button ui-widget ui-state-default ui-corner-all",
5604 stateClasses
= "ui-state-hover ui-state-active ",
5605 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",
5606 formResetHandler = function() {
5607 var buttons
= $( this ).find( ":ui-button" );
5608 setTimeout(function() {
5609 buttons
.button( "refresh" );
5612 radioGroup = function( radio
) {
5613 var name
= radio
.name
,
5618 radios
= $( form
).find( "[name='" + name
+ "']" );
5620 radios
= $( "[name='" + name
+ "']", radio
.ownerDocument
)
5621 .filter(function() {
5629 $.widget( "ui.button", {
5639 _create: function() {
5640 this.element
.closest( "form" )
5641 .unbind( "reset.button" )
5642 .bind( "reset.button", formResetHandler
);
5644 if ( typeof this.options
.disabled
!== "boolean" ) {
5645 this.options
.disabled
= !!this.element
.propAttr( "disabled" );
5647 this.element
.propAttr( "disabled", this.options
.disabled
);
5650 this._determineButtonType();
5651 this.hasTitle
= !!this.buttonElement
.attr( "title" );
5654 options
= this.options
,
5655 toggleButton
= this.type
=== "checkbox" || this.type
=== "radio",
5656 hoverClass
= "ui-state-hover" + ( !toggleButton
? " ui-state-active" : "" ),
5657 focusClass
= "ui-state-focus";
5659 if ( options
.label
=== null ) {
5660 options
.label
= this.buttonElement
.html();
5664 .addClass( baseClasses
)
5665 .attr( "role", "button" )
5666 .bind( "mouseenter.button", function() {
5667 if ( options
.disabled
) {
5670 $( this ).addClass( "ui-state-hover" );
5671 if ( this === lastActive
) {
5672 $( this ).addClass( "ui-state-active" );
5675 .bind( "mouseleave.button", function() {
5676 if ( options
.disabled
) {
5679 $( this ).removeClass( hoverClass
);
5681 .bind( "click.button", function( event
) {
5682 if ( options
.disabled
) {
5683 event
.preventDefault();
5684 event
.stopImmediatePropagation();
5689 .bind( "focus.button", function() {
5690 // no need to check disabled, focus won't be triggered anyway
5691 self
.buttonElement
.addClass( focusClass
);
5693 .bind( "blur.button", function() {
5694 self
.buttonElement
.removeClass( focusClass
);
5697 if ( toggleButton
) {
5698 this.element
.bind( "change.button", function() {
5699 if ( clickDragged
) {
5704 // if mouse moves between mousedown and mouseup (drag) set clickDragged flag
5705 // prevents issue where button state changes but checkbox/radio checked state
5706 // does not in Firefox (see ticket #6970)
5708 .bind( "mousedown.button", function( event
) {
5709 if ( options
.disabled
) {
5712 clickDragged
= false;
5713 startXPos
= event
.pageX
;
5714 startYPos
= event
.pageY
;
5716 .bind( "mouseup.button", function( event
) {
5717 if ( options
.disabled
) {
5720 if ( startXPos
!== event
.pageX
|| startYPos
!== event
.pageY
) {
5721 clickDragged
= true;
5726 if ( this.type
=== "checkbox" ) {
5727 this.buttonElement
.bind( "click.button", function() {
5728 if ( options
.disabled
|| clickDragged
) {
5731 $( this ).toggleClass( "ui-state-active" );
5732 self
.buttonElement
.attr( "aria-pressed", self
.element
[0].checked
);
5734 } else if ( this.type
=== "radio" ) {
5735 this.buttonElement
.bind( "click.button", function() {
5736 if ( options
.disabled
|| clickDragged
) {
5739 $( this ).addClass( "ui-state-active" );
5740 self
.buttonElement
.attr( "aria-pressed", "true" );
5742 var radio
= self
.element
[ 0 ];
5746 return $( this ).button( "widget" )[ 0 ];
5748 .removeClass( "ui-state-active" )
5749 .attr( "aria-pressed", "false" );
5753 .bind( "mousedown.button", function() {
5754 if ( options
.disabled
) {
5757 $( this ).addClass( "ui-state-active" );
5759 $( document
).one( "mouseup", function() {
5763 .bind( "mouseup.button", function() {
5764 if ( options
.disabled
) {
5767 $( this ).removeClass( "ui-state-active" );
5769 .bind( "keydown.button", function(event
) {
5770 if ( options
.disabled
) {
5773 if ( event
.keyCode
== $.ui
.keyCode
.SPACE
|| event
.keyCode
== $.ui
.keyCode
.ENTER
) {
5774 $( this ).addClass( "ui-state-active" );
5777 .bind( "keyup.button", function() {
5778 $( this ).removeClass( "ui-state-active" );
5781 if ( this.buttonElement
.is("a") ) {
5782 this.buttonElement
.keyup(function(event
) {
5783 if ( event
.keyCode
=== $.ui
.keyCode
.SPACE
) {
5784 // TODO pass through original event correctly (just as 2nd argument doesn't work)
5791 // TODO: pull out $.Widget's handling for the disabled option into
5792 // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
5793 // be overridden by individual plugins
5794 this._setOption( "disabled", options
.disabled
);
5795 this._resetButton();
5798 _determineButtonType: function() {
5800 if ( this.element
.is(":checkbox") ) {
5801 this.type
= "checkbox";
5802 } else if ( this.element
.is(":radio") ) {
5803 this.type
= "radio";
5804 } else if ( this.element
.is("input") ) {
5805 this.type
= "input";
5807 this.type
= "button";
5810 if ( this.type
=== "checkbox" || this.type
=== "radio" ) {
5811 // we don't search against the document in case the element
5812 // is disconnected from the DOM
5813 var ancestor
= this.element
.parents().filter(":last"),
5814 labelSelector
= "label[for='" + this.element
.attr("id") + "']";
5815 this.buttonElement
= ancestor
.find( labelSelector
);
5816 if ( !this.buttonElement
.length
) {
5817 ancestor
= ancestor
.length
? ancestor
.siblings() : this.element
.siblings();
5818 this.buttonElement
= ancestor
.filter( labelSelector
);
5819 if ( !this.buttonElement
.length
) {
5820 this.buttonElement
= ancestor
.find( labelSelector
);
5823 this.element
.addClass( "ui-helper-hidden-accessible" );
5825 var checked
= this.element
.is( ":checked" );
5827 this.buttonElement
.addClass( "ui-state-active" );
5829 this.buttonElement
.attr( "aria-pressed", checked
);
5831 this.buttonElement
= this.element
;
5835 widget: function() {
5836 return this.buttonElement
;
5839 destroy: function() {
5841 .removeClass( "ui-helper-hidden-accessible" );
5843 .removeClass( baseClasses
+ " " + stateClasses
+ " " + typeClasses
)
5844 .removeAttr( "role" )
5845 .removeAttr( "aria-pressed" )
5846 .html( this.buttonElement
.find(".ui-button-text").html() );
5848 if ( !this.hasTitle
) {
5849 this.buttonElement
.removeAttr( "title" );
5852 $.Widget
.prototype.destroy
.call( this );
5855 _setOption: function( key
, value
) {
5856 $.Widget
.prototype._setOption
.apply( this, arguments
);
5857 if ( key
=== "disabled" ) {
5859 this.element
.propAttr( "disabled", true );
5861 this.element
.propAttr( "disabled", false );
5865 this._resetButton();
5868 refresh: function() {
5869 var isDisabled
= this.element
.is( ":disabled" );
5870 if ( isDisabled
!== this.options
.disabled
) {
5871 this._setOption( "disabled", isDisabled
);
5873 if ( this.type
=== "radio" ) {
5874 radioGroup( this.element
[0] ).each(function() {
5875 if ( $( this ).is( ":checked" ) ) {
5876 $( this ).button( "widget" )
5877 .addClass( "ui-state-active" )
5878 .attr( "aria-pressed", "true" );
5880 $( this ).button( "widget" )
5881 .removeClass( "ui-state-active" )
5882 .attr( "aria-pressed", "false" );
5885 } else if ( this.type
=== "checkbox" ) {
5886 if ( this.element
.is( ":checked" ) ) {
5888 .addClass( "ui-state-active" )
5889 .attr( "aria-pressed", "true" );
5892 .removeClass( "ui-state-active" )
5893 .attr( "aria-pressed", "false" );
5898 _resetButton: function() {
5899 if ( this.type
=== "input" ) {
5900 if ( this.options
.label
) {
5901 this.element
.val( this.options
.label
);
5905 var buttonElement
= this.buttonElement
.removeClass( typeClasses
),
5906 buttonText
= $( "<span></span>", this.element
[0].ownerDocument
)
5907 .addClass( "ui-button-text" )
5908 .html( this.options
.label
)
5909 .appendTo( buttonElement
.empty() )
5911 icons
= this.options
.icons
,
5912 multipleIcons
= icons
.primary
&& icons
.secondary
,
5915 if ( icons
.primary
|| icons
.secondary
) {
5916 if ( this.options
.text
) {
5917 buttonClasses
.push( "ui-button-text-icon" + ( multipleIcons
? "s" : ( icons
.primary
? "-primary" : "-secondary" ) ) );
5920 if ( icons
.primary
) {
5921 buttonElement
.prepend( "<span class='ui-button-icon-primary ui-icon " + icons
.primary
+ "'></span>" );
5924 if ( icons
.secondary
) {
5925 buttonElement
.append( "<span class='ui-button-icon-secondary ui-icon " + icons
.secondary
+ "'></span>" );
5928 if ( !this.options
.text
) {
5929 buttonClasses
.push( multipleIcons
? "ui-button-icons-only" : "ui-button-icon-only" );
5931 if ( !this.hasTitle
) {
5932 buttonElement
.attr( "title", buttonText
);
5936 buttonClasses
.push( "ui-button-text-only" );
5938 buttonElement
.addClass( buttonClasses
.join( " " ) );
5942 $.widget( "ui.buttonset", {
5944 items
: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)"
5947 _create: function() {
5948 this.element
.addClass( "ui-buttonset" );
5955 _setOption: function( key
, value
) {
5956 if ( key
=== "disabled" ) {
5957 this.buttons
.button( "option", key
, value
);
5960 $.Widget
.prototype._setOption
.apply( this, arguments
);
5963 refresh: function() {
5964 var rtl
= this.element
.css( "direction" ) === "rtl";
5966 this.buttons
= this.element
.find( this.options
.items
)
5967 .filter( ":ui-button" )
5968 .button( "refresh" )
5970 .not( ":ui-button" )
5974 return $( this ).button( "widget" )[ 0 ];
5976 .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
5978 .addClass( rtl
? "ui-corner-right" : "ui-corner-left" )
5981 .addClass( rtl
? "ui-corner-left" : "ui-corner-right" )
5986 destroy: function() {
5987 this.element
.removeClass( "ui-buttonset" );
5990 return $( this ).button( "widget" )[ 0 ];
5992 .removeClass( "ui-corner-left ui-corner-right" )
5994 .button( "destroy" );
5996 $.Widget
.prototype.destroy
.call( this );
6002 * jQuery UI Dialog 1.8.21
6004 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
6005 * Dual licensed under the MIT or GPL Version 2 licenses.
6006 * http://jquery.org/license
6008 * http://docs.jquery.com/UI/Dialog
6012 * jquery.ui.widget.js
6013 * jquery.ui.button.js
6014 * jquery.ui.draggable.js
6015 * jquery.ui.mouse.js
6016 * jquery.ui.position.js
6017 * jquery.ui.resizable.js
6019 (function( $, undefined ) {
6021 var uiDialogClasses
=
6024 'ui-widget-content ' +
6026 sizeRelatedOptions
= {
6035 resizableRelatedOptions
= {
6041 // support for jQuery 1.3.2 - handle common attrFn methods for dialog
6042 attrFn
= $.attrFn
|| {
6054 $.widget("ui.dialog", {
6058 closeOnEscape
: true,
6073 // ensure that the titlebar is never outside the document
6074 using: function(pos
) {
6075 var topOffset
= $(this).css(pos
).offset().top
;
6076 if (topOffset
< 0) {
6077 $(this).css('top', pos
.top
- topOffset
);
6089 _create: function() {
6090 this.originalTitle
= this.element
.attr('title');
6091 // #5742 - .attr() might return a DOMElement
6092 if ( typeof this.originalTitle
!== "string" ) {
6093 this.originalTitle
= "";
6096 this.options
.title
= this.options
.title
|| this.originalTitle
;
6098 options
= self
.options
,
6100 title
= options
.title
|| ' ',
6101 titleId
= $.ui
.dialog
.getTitleId(self
.element
),
6103 uiDialog
= (self
.uiDialog
= $('<div></div>'))
6104 .appendTo(document
.body
)
6106 .addClass(uiDialogClasses
+ options
.dialogClass
)
6108 zIndex
: options
.zIndex
6110 // setting tabIndex makes the div focusable
6111 // setting outline to 0 prevents a border on focus in Mozilla
6112 .attr('tabIndex', -1).css('outline', 0).keydown(function(event
) {
6113 if (options
.closeOnEscape
&& !event
.isDefaultPrevented() && event
.keyCode
&&
6114 event
.keyCode
=== $.ui
.keyCode
.ESCAPE
) {
6117 event
.preventDefault();
6122 'aria-labelledby': titleId
6124 .mousedown(function(event
) {
6125 self
.moveToTop(false, event
);
6128 uiDialogContent
= self
.element
6130 .removeAttr('title')
6132 'ui-dialog-content ' +
6133 'ui-widget-content')
6134 .appendTo(uiDialog
),
6136 uiDialogTitlebar
= (self
.uiDialogTitlebar
= $('<div></div>'))
6138 'ui-dialog-titlebar ' +
6139 'ui-widget-header ' +
6141 'ui-helper-clearfix'
6143 .prependTo(uiDialog
),
6145 uiDialogTitlebarClose
= $('<a href="#"></a>')
6147 'ui-dialog-titlebar-close ' +
6150 .attr('role', 'button')
6153 uiDialogTitlebarClose
.addClass('ui-state-hover');
6156 uiDialogTitlebarClose
.removeClass('ui-state-hover');
6160 uiDialogTitlebarClose
.addClass('ui-state-focus');
6163 uiDialogTitlebarClose
.removeClass('ui-state-focus');
6165 .click(function(event
) {
6169 .appendTo(uiDialogTitlebar
),
6171 uiDialogTitlebarCloseText
= (self
.uiDialogTitlebarCloseText
= $('<span></span>'))
6174 'ui-icon-closethick'
6176 .text(options
.closeText
)
6177 .appendTo(uiDialogTitlebarClose
),
6179 uiDialogTitle
= $('<span></span>')
6180 .addClass('ui-dialog-title')
6181 .attr('id', titleId
)
6183 .prependTo(uiDialogTitlebar
);
6185 //handling of deprecated beforeclose (vs beforeClose) option
6186 //Ticket #4669 http://dev.jqueryui.com/ticket/4669
6187 //TODO: remove in 1.9pre
6188 if ($.isFunction(options
.beforeclose
) && !$.isFunction(options
.beforeClose
)) {
6189 options
.beforeClose
= options
.beforeclose
;
6192 uiDialogTitlebar
.find("*").add(uiDialogTitlebar
).disableSelection();
6194 if (options
.draggable
&& $.fn
.draggable
) {
6195 self
._makeDraggable();
6197 if (options
.resizable
&& $.fn
.resizable
) {
6198 self
._makeResizable();
6201 self
._createButtons(options
.buttons
);
6202 self
._isOpen
= false;
6204 if ($.fn
.bgiframe
) {
6205 uiDialog
.bgiframe();
6210 if ( this.options
.autoOpen
) {
6215 destroy: function() {
6219 self
.overlay
.destroy();
6221 self
.uiDialog
.hide();
6224 .removeData('dialog')
6225 .removeClass('ui-dialog-content ui-widget-content')
6226 .hide().appendTo('body');
6227 self
.uiDialog
.remove();
6229 if (self
.originalTitle
) {
6230 self
.element
.attr('title', self
.originalTitle
);
6236 widget: function() {
6237 return this.uiDialog
;
6240 close: function(event
) {
6244 if (false === self
._trigger('beforeClose', event
)) {
6249 self
.overlay
.destroy();
6251 self
.uiDialog
.unbind('keypress.ui-dialog');
6253 self
._isOpen
= false;
6255 if (self
.options
.hide
) {
6256 self
.uiDialog
.hide(self
.options
.hide
, function() {
6257 self
._trigger('close', event
);
6260 self
.uiDialog
.hide();
6261 self
._trigger('close', event
);
6264 $.ui
.dialog
.overlay
.resize();
6266 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
6267 if (self
.options
.modal
) {
6269 $('.ui-dialog').each(function() {
6270 if (this !== self
.uiDialog
[0]) {
6271 thisZ
= $(this).css('z-index');
6273 maxZ
= Math
.max(maxZ
, thisZ
);
6277 $.ui
.dialog
.maxZ
= maxZ
;
6283 isOpen: function() {
6284 return this._isOpen
;
6287 // the force parameter allows us to move modal dialogs to their correct
6289 moveToTop: function(force
, event
) {
6291 options
= self
.options
,
6294 if ((options
.modal
&& !force
) ||
6295 (!options
.stack
&& !options
.modal
)) {
6296 return self
._trigger('focus', event
);
6299 if (options
.zIndex
> $.ui
.dialog
.maxZ
) {
6300 $.ui
.dialog
.maxZ
= options
.zIndex
;
6303 $.ui
.dialog
.maxZ
+= 1;
6304 self
.overlay
.$el
.css('z-index', $.ui
.dialog
.overlay
.maxZ
= $.ui
.dialog
.maxZ
);
6307 //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed.
6308 // http://ui.jquery.com/bugs/ticket/3193
6309 saveScroll
= { scrollTop
: self
.element
.scrollTop(), scrollLeft
: self
.element
.scrollLeft() };
6310 $.ui
.dialog
.maxZ
+= 1;
6311 self
.uiDialog
.css('z-index', $.ui
.dialog
.maxZ
);
6312 self
.element
.attr(saveScroll
);
6313 self
._trigger('focus', event
);
6319 if (this._isOpen
) { return; }
6322 options
= self
.options
,
6323 uiDialog
= self
.uiDialog
;
6325 self
.overlay
= options
.modal
? new $.ui
.dialog
.overlay(self
) : null;
6327 self
._position(options
.position
);
6328 uiDialog
.show(options
.show
);
6329 self
.moveToTop(true);
6331 // prevent tabbing out of modal dialogs
6332 if ( options
.modal
) {
6333 uiDialog
.bind( "keydown.ui-dialog", function( event
) {
6334 if ( event
.keyCode
!== $.ui
.keyCode
.TAB
) {
6338 var tabbables
= $(':tabbable', this),
6339 first
= tabbables
.filter(':first'),
6340 last
= tabbables
.filter(':last');
6342 if (event
.target
=== last
[0] && !event
.shiftKey
) {
6345 } else if (event
.target
=== first
[0] && event
.shiftKey
) {
6352 // set focus to the first tabbable element in the content area or the first button
6353 // if there are no tabbable elements, set focus on the dialog itself
6354 $(self
.element
.find(':tabbable').get().concat(
6355 uiDialog
.find('.ui-dialog-buttonpane :tabbable').get().concat(
6356 uiDialog
.get()))).eq(0).focus();
6358 self
._isOpen
= true;
6359 self
._trigger('open');
6364 _createButtons: function(buttons
) {
6367 uiDialogButtonPane
= $('<div></div>')
6369 'ui-dialog-buttonpane ' +
6370 'ui-widget-content ' +
6371 'ui-helper-clearfix'
6373 uiButtonSet
= $( "<div></div>" )
6374 .addClass( "ui-dialog-buttonset" )
6375 .appendTo( uiDialogButtonPane
);
6377 // if we already have a button pane, remove it
6378 self
.uiDialog
.find('.ui-dialog-buttonpane').remove();
6380 if (typeof buttons
=== 'object' && buttons
!== null) {
6381 $.each(buttons
, function() {
6382 return !(hasButtons
= true);
6386 $.each(buttons
, function(name
, props
) {
6387 props
= $.isFunction( props
) ?
6388 { click
: props
, text
: name
} :
6390 var button
= $('<button type="button"></button>')
6392 props
.click
.apply(self
.element
[0], arguments
);
6394 .appendTo(uiButtonSet
);
6395 // can't use .attr( props, true ) with jQuery 1.3.2.
6396 $.each( props
, function( key
, value
) {
6397 if ( key
=== "click" ) {
6400 if ( key
in attrFn
) {
6401 button
[ key
]( value
);
6403 button
.attr( key
, value
);
6410 uiDialogButtonPane
.appendTo(self
.uiDialog
);
6414 _makeDraggable: function() {
6416 options
= self
.options
,
6420 function filteredUi(ui
) {
6422 position
: ui
.position
,
6427 self
.uiDialog
.draggable({
6428 cancel
: '.ui-dialog-content, .ui-dialog-titlebar-close',
6429 handle
: '.ui-dialog-titlebar',
6430 containment
: 'document',
6431 start: function(event
, ui
) {
6432 heightBeforeDrag
= options
.height
=== "auto" ? "auto" : $(this).height();
6433 $(this).height($(this).height()).addClass("ui-dialog-dragging");
6434 self
._trigger('dragStart', event
, filteredUi(ui
));
6436 drag: function(event
, ui
) {
6437 self
._trigger('drag', event
, filteredUi(ui
));
6439 stop: function(event
, ui
) {
6440 options
.position
= [ui
.position
.left
- doc
.scrollLeft(),
6441 ui
.position
.top
- doc
.scrollTop()];
6442 $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag
);
6443 self
._trigger('dragStop', event
, filteredUi(ui
));
6444 $.ui
.dialog
.overlay
.resize();
6449 _makeResizable: function(handles
) {
6450 handles
= (handles
=== undefined ? this.options
.resizable
: handles
);
6452 options
= self
.options
,
6453 // .ui-resizable has position: relative defined in the stylesheet
6454 // but dialogs have to use absolute or fixed positioning
6455 position
= self
.uiDialog
.css('position'),
6456 resizeHandles
= (typeof handles
=== 'string' ?
6458 'n,e,s,w,se,sw,ne,nw'
6461 function filteredUi(ui
) {
6463 originalPosition
: ui
.originalPosition
,
6464 originalSize
: ui
.originalSize
,
6465 position
: ui
.position
,
6470 self
.uiDialog
.resizable({
6471 cancel
: '.ui-dialog-content',
6472 containment
: 'document',
6473 alsoResize
: self
.element
,
6474 maxWidth
: options
.maxWidth
,
6475 maxHeight
: options
.maxHeight
,
6476 minWidth
: options
.minWidth
,
6477 minHeight
: self
._minHeight(),
6478 handles
: resizeHandles
,
6479 start: function(event
, ui
) {
6480 $(this).addClass("ui-dialog-resizing");
6481 self
._trigger('resizeStart', event
, filteredUi(ui
));
6483 resize: function(event
, ui
) {
6484 self
._trigger('resize', event
, filteredUi(ui
));
6486 stop: function(event
, ui
) {
6487 $(this).removeClass("ui-dialog-resizing");
6488 options
.height
= $(this).height();
6489 options
.width
= $(this).width();
6490 self
._trigger('resizeStop', event
, filteredUi(ui
));
6491 $.ui
.dialog
.overlay
.resize();
6494 .css('position', position
)
6495 .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se');
6498 _minHeight: function() {
6499 var options
= this.options
;
6501 if (options
.height
=== 'auto') {
6502 return options
.minHeight
;
6504 return Math
.min(options
.minHeight
, options
.height
);
6508 _position: function(position
) {
6514 // deep extending converts arrays to objects in jQuery <= 1.3.2 :-(
6515 // if (typeof position == 'string' || $.isArray(position)) {
6516 // myAt = $.isArray(position) ? position : position.split(' ');
6518 if (typeof position
=== 'string' || (typeof position
=== 'object' && '0' in position
)) {
6519 myAt
= position
.split
? position
.split(' ') : [position
[0], position
[1]];
6520 if (myAt
.length
=== 1) {
6524 $.each(['left', 'top'], function(i
, offsetPosition
) {
6525 if (+myAt
[i
] === myAt
[i
]) {
6526 offset
[i
] = myAt
[i
];
6527 myAt
[i
] = offsetPosition
;
6534 offset
: offset
.join(" ")
6538 position
= $.extend({}, $.ui
.dialog
.prototype.options
.position
, position
);
6540 position
= $.ui
.dialog
.prototype.options
.position
;
6543 // need to show the dialog to get the actual offset in the position plugin
6544 isVisible
= this.uiDialog
.is(':visible');
6546 this.uiDialog
.show();
6549 // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781
6550 .css({ top
: 0, left
: 0 })
6551 .position($.extend({ of: window
}, position
));
6553 this.uiDialog
.hide();
6557 _setOptions: function( options
) {
6559 resizableOptions
= {},
6562 $.each( options
, function( key
, value
) {
6563 self
._setOption( key
, value
);
6565 if ( key
in sizeRelatedOptions
) {
6568 if ( key
in resizableRelatedOptions
) {
6569 resizableOptions
[ key
] = value
;
6576 if ( this.uiDialog
.is( ":data(resizable)" ) ) {
6577 this.uiDialog
.resizable( "option", resizableOptions
);
6581 _setOption: function(key
, value
){
6583 uiDialog
= self
.uiDialog
;
6586 //handling of deprecated beforeclose (vs beforeClose) option
6587 //Ticket #4669 http://dev.jqueryui.com/ticket/4669
6588 //TODO: remove in 1.9pre
6590 key
= "beforeClose";
6593 self
._createButtons(value
);
6596 // ensure that we always pass a string
6597 self
.uiDialogTitlebarCloseText
.text("" + value
);
6601 .removeClass(self
.options
.dialogClass
)
6602 .addClass(uiDialogClasses
+ value
);
6606 uiDialog
.addClass('ui-dialog-disabled');
6608 uiDialog
.removeClass('ui-dialog-disabled');
6612 var isDraggable
= uiDialog
.is( ":data(draggable)" );
6613 if ( isDraggable
&& !value
) {
6614 uiDialog
.draggable( "destroy" );
6617 if ( !isDraggable
&& value
) {
6618 self
._makeDraggable();
6622 self
._position(value
);
6625 // currently resizable, becoming non-resizable
6626 var isResizable
= uiDialog
.is( ":data(resizable)" );
6627 if (isResizable
&& !value
) {
6628 uiDialog
.resizable('destroy');
6631 // currently resizable, changing handles
6632 if (isResizable
&& typeof value
=== 'string') {
6633 uiDialog
.resizable('option', 'handles', value
);
6636 // currently non-resizable, becoming resizable
6637 if (!isResizable
&& value
!== false) {
6638 self
._makeResizable(value
);
6642 // convert whatever was passed in o a string, for html() to not throw up
6643 $(".ui-dialog-title", self
.uiDialogTitlebar
).html("" + (value
|| ' '));
6647 $.Widget
.prototype._setOption
.apply(self
, arguments
);
6651 /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
6652 * divs will both have width and height set, so we need to reset them
6654 var options
= this.options
,
6657 isVisible
= this.uiDialog
.is( ":visible" );
6659 // reset content sizing
6660 this.element
.show().css({
6666 if (options
.minWidth
> options
.width
) {
6667 options
.width
= options
.minWidth
;
6670 // reset wrapper sizing
6671 // determine the height of all the non-content elements
6672 nonContentHeight
= this.uiDialog
.css({
6674 width
: options
.width
6677 minContentHeight
= Math
.max( 0, options
.minHeight
- nonContentHeight
);
6679 if ( options
.height
=== "auto" ) {
6680 // only needed for IE6 support
6681 if ( $.support
.minHeight
) {
6683 minHeight
: minContentHeight
,
6687 this.uiDialog
.show();
6688 var autoHeight
= this.element
.css( "height", "auto" ).height();
6690 this.uiDialog
.hide();
6692 this.element
.height( Math
.max( autoHeight
, minContentHeight
) );
6695 this.element
.height( Math
.max( options
.height
- nonContentHeight
, 0 ) );
6698 if (this.uiDialog
.is(':data(resizable)')) {
6699 this.uiDialog
.resizable('option', 'minHeight', this._minHeight());
6704 $.extend($.ui
.dialog
, {
6710 getTitleId: function($el
) {
6711 var id
= $el
.attr('id');
6716 return 'ui-dialog-title-' + id
;
6719 overlay: function(dialog
) {
6720 this.$el
= $.ui
.dialog
.overlay
.create(dialog
);
6724 $.extend($.ui
.dialog
.overlay
, {
6726 // reuse old instances due to IE memory leak with alpha transparency (see #5185)
6729 events
: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','),
6730 function(event
) { return event
+ '.dialog-overlay'; }).join(' '),
6731 create: function(dialog
) {
6732 if (this.instances
.length
=== 0) {
6733 // prevent use of anchors and inputs
6734 // we use a setTimeout in case the overlay is created from an
6735 // event that we're going to be cancelling (see #2804)
6736 setTimeout(function() {
6737 // handle $(el).dialog().dialog('close') (see #4065)
6738 if ($.ui
.dialog
.overlay
.instances
.length
) {
6739 $(document
).bind($.ui
.dialog
.overlay
.events
, function(event
) {
6740 // stop events if the z-index of the target is < the z-index of the overlay
6741 // we cannot return true when we don't want to cancel the event (#3523)
6742 if ($(event
.target
).zIndex() < $.ui
.dialog
.overlay
.maxZ
) {
6749 // allow closing by pressing the escape key
6750 $(document
).bind('keydown.dialog-overlay', function(event
) {
6751 if (dialog
.options
.closeOnEscape
&& !event
.isDefaultPrevented() && event
.keyCode
&&
6752 event
.keyCode
=== $.ui
.keyCode
.ESCAPE
) {
6754 dialog
.close(event
);
6755 event
.preventDefault();
6759 // handle window resize
6760 $(window
).bind('resize.dialog-overlay', $.ui
.dialog
.overlay
.resize
);
6763 var $el
= (this.oldInstances
.pop() || $('<div></div>').addClass('ui-widget-overlay'))
6764 .appendTo(document
.body
)
6766 width
: this.width(),
6767 height
: this.height()
6770 if ($.fn
.bgiframe
) {
6774 this.instances
.push($el
);
6778 destroy: function($el
) {
6779 var indexOf
= $.inArray($el
, this.instances
);
6781 this.oldInstances
.push(this.instances
.splice(indexOf
, 1)[0]);
6784 if (this.instances
.length
=== 0) {
6785 $([document
, window
]).unbind('.dialog-overlay');
6790 // adjust the maxZ to allow other modal dialogs to continue to work (see #4309)
6792 $.each(this.instances
, function() {
6793 maxZ
= Math
.max(maxZ
, this.css('z-index'));
6798 height: function() {
6802 if ($.browser
.msie
&& $.browser
.version
< 7) {
6803 scrollHeight
= Math
.max(
6804 document
.documentElement
.scrollHeight
,
6805 document
.body
.scrollHeight
6807 offsetHeight
= Math
.max(
6808 document
.documentElement
.offsetHeight
,
6809 document
.body
.offsetHeight
6812 if (scrollHeight
< offsetHeight
) {
6813 return $(window
).height() + 'px';
6815 return scrollHeight
+ 'px';
6817 // handle "good" browsers
6819 return $(document
).height() + 'px';
6827 if ( $.browser
.msie
) {
6828 scrollWidth
= Math
.max(
6829 document
.documentElement
.scrollWidth
,
6830 document
.body
.scrollWidth
6832 offsetWidth
= Math
.max(
6833 document
.documentElement
.offsetWidth
,
6834 document
.body
.offsetWidth
6837 if (scrollWidth
< offsetWidth
) {
6838 return $(window
).width() + 'px';
6840 return scrollWidth
+ 'px';
6842 // handle "good" browsers
6844 return $(document
).width() + 'px';
6848 resize: function() {
6849 /* If the dialog is draggable and the user drags it past the
6850 * right edge of the window, the document becomes wider so we
6851 * need to stretch the overlay. If the user then drags the
6852 * dialog back to the left, the document will become narrower,
6853 * so we need to shrink the overlay to the appropriate size.
6854 * This is handled by shrinking the overlay before setting it
6855 * to the full document size.
6857 var $overlays
= $([]);
6858 $.each($.ui
.dialog
.overlay
.instances
, function() {
6859 $overlays
= $overlays
.add(this);
6866 width
: $.ui
.dialog
.overlay
.width(),
6867 height
: $.ui
.dialog
.overlay
.height()
6872 $.extend($.ui
.dialog
.overlay
.prototype, {
6873 destroy: function() {
6874 $.ui
.dialog
.overlay
.destroy(this.$el
);
6880 * jQuery UI Slider 1.8.21
6882 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
6883 * Dual licensed under the MIT or GPL Version 2 licenses.
6884 * http://jquery.org/license
6886 * http://docs.jquery.com/UI/Slider
6890 * jquery.ui.mouse.js
6891 * jquery.ui.widget.js
6893 (function( $, undefined ) {
6895 // number of pages in a slider
6896 // (how many times can you page up/down to go through the whole range)
6899 $.widget( "ui.slider", $.ui
.mouse
, {
6901 widgetEventPrefix
: "slide",
6908 orientation
: "horizontal",
6915 _create: function() {
6918 existingHandles
= this.element
.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
6919 handle
= "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
6920 handleCount
= ( o
.values
&& o
.values
.length
) || 1,
6923 this._keySliding
= false;
6924 this._mouseSliding
= false;
6925 this._animateOff
= true;
6926 this._handleIndex
= null;
6927 this._detectOrientation();
6931 .addClass( "ui-slider" +
6932 " ui-slider-" + this.orientation
+
6934 " ui-widget-content" +
6936 ( o
.disabled
? " ui-slider-disabled ui-disabled" : "" ) );
6941 if ( o
.range
=== true ) {
6943 o
.values
= [ this._valueMin(), this._valueMin() ];
6945 if ( o
.values
.length
&& o
.values
.length
!== 2 ) {
6946 o
.values
= [ o
.values
[0], o
.values
[0] ];
6950 this.range
= $( "<div></div>" )
6951 .appendTo( this.element
)
6952 .addClass( "ui-slider-range" +
6953 // note: this isn't the most fittingly semantic framework class for this element,
6954 // but worked best visually with a variety of themes
6955 " ui-widget-header" +
6956 ( ( o
.range
=== "min" || o
.range
=== "max" ) ? " ui-slider-range-" + o
.range
: "" ) );
6959 for ( var i
= existingHandles
.length
; i
< handleCount
; i
+= 1 ) {
6960 handles
.push( handle
);
6963 this.handles
= existingHandles
.add( $( handles
.join( "" ) ).appendTo( self
.element
) );
6965 this.handle
= this.handles
.eq( 0 );
6967 this.handles
.add( this.range
).filter( "a" )
6968 .click(function( event
) {
6969 event
.preventDefault();
6972 if ( !o
.disabled
) {
6973 $( this ).addClass( "ui-state-hover" );
6976 $( this ).removeClass( "ui-state-hover" );
6979 if ( !o
.disabled
) {
6980 $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
6981 $( this ).addClass( "ui-state-focus" );
6987 $( this ).removeClass( "ui-state-focus" );
6990 this.handles
.each(function( i
) {
6991 $( this ).data( "index.ui-slider-handle", i
);
6995 .keydown(function( event
) {
6996 var index
= $( this ).data( "index.ui-slider-handle" ),
7002 if ( self
.options
.disabled
) {
7006 switch ( event
.keyCode
) {
7007 case $.ui
.keyCode
.HOME
:
7008 case $.ui
.keyCode
.END
:
7009 case $.ui
.keyCode
.PAGE_UP
:
7010 case $.ui
.keyCode
.PAGE_DOWN
:
7011 case $.ui
.keyCode
.UP
:
7012 case $.ui
.keyCode
.RIGHT
:
7013 case $.ui
.keyCode
.DOWN
:
7014 case $.ui
.keyCode
.LEFT
:
7015 event
.preventDefault();
7016 if ( !self
._keySliding
) {
7017 self
._keySliding
= true;
7018 $( this ).addClass( "ui-state-active" );
7019 allowed
= self
._start( event
, index
);
7020 if ( allowed
=== false ) {
7027 step
= self
.options
.step
;
7028 if ( self
.options
.values
&& self
.options
.values
.length
) {
7029 curVal
= newVal
= self
.values( index
);
7031 curVal
= newVal
= self
.value();
7034 switch ( event
.keyCode
) {
7035 case $.ui
.keyCode
.HOME
:
7036 newVal
= self
._valueMin();
7038 case $.ui
.keyCode
.END
:
7039 newVal
= self
._valueMax();
7041 case $.ui
.keyCode
.PAGE_UP
:
7042 newVal
= self
._trimAlignValue( curVal
+ ( (self
._valueMax() - self
._valueMin()) / numPages
) );
7044 case $.ui
.keyCode
.PAGE_DOWN
:
7045 newVal
= self
._trimAlignValue( curVal
- ( (self
._valueMax() - self
._valueMin()) / numPages
) );
7047 case $.ui
.keyCode
.UP
:
7048 case $.ui
.keyCode
.RIGHT
:
7049 if ( curVal
=== self
._valueMax() ) {
7052 newVal
= self
._trimAlignValue( curVal
+ step
);
7054 case $.ui
.keyCode
.DOWN
:
7055 case $.ui
.keyCode
.LEFT
:
7056 if ( curVal
=== self
._valueMin() ) {
7059 newVal
= self
._trimAlignValue( curVal
- step
);
7063 self
._slide( event
, index
, newVal
);
7065 .keyup(function( event
) {
7066 var index
= $( this ).data( "index.ui-slider-handle" );
7068 if ( self
._keySliding
) {
7069 self
._keySliding
= false;
7070 self
._stop( event
, index
);
7071 self
._change( event
, index
);
7072 $( this ).removeClass( "ui-state-active" );
7077 this._refreshValue();
7079 this._animateOff
= false;
7082 destroy: function() {
7083 this.handles
.remove();
7084 this.range
.remove();
7087 .removeClass( "ui-slider" +
7088 " ui-slider-horizontal" +
7089 " ui-slider-vertical" +
7090 " ui-slider-disabled" +
7092 " ui-widget-content" +
7094 .removeData( "slider" )
7095 .unbind( ".slider" );
7097 this._mouseDestroy();
7102 _mouseCapture: function( event
) {
7103 var o
= this.options
,
7118 this.elementSize
= {
7119 width
: this.element
.outerWidth(),
7120 height
: this.element
.outerHeight()
7122 this.elementOffset
= this.element
.offset();
7124 position
= { x
: event
.pageX
, y
: event
.pageY
};
7125 normValue
= this._normValueFromMouse( position
);
7126 distance
= this._valueMax() - this._valueMin() + 1;
7128 this.handles
.each(function( i
) {
7129 var thisDistance
= Math
.abs( normValue
- self
.values(i
) );
7130 if ( distance
> thisDistance
) {
7131 distance
= thisDistance
;
7132 closestHandle
= $( this );
7137 // workaround for bug #3736 (if both handles of a range are at 0,
7138 // the first is always used as the one with least distance,
7139 // and moving it is obviously prevented by preventing negative ranges)
7140 if( o
.range
=== true && this.values(1) === o
.min
) {
7142 closestHandle
= $( this.handles
[index
] );
7145 allowed
= this._start( event
, index
);
7146 if ( allowed
=== false ) {
7149 this._mouseSliding
= true;
7151 self
._handleIndex
= index
;
7154 .addClass( "ui-state-active" )
7157 offset
= closestHandle
.offset();
7158 mouseOverHandle
= !$( event
.target
).parents().andSelf().is( ".ui-slider-handle" );
7159 this._clickOffset
= mouseOverHandle
? { left
: 0, top
: 0 } : {
7160 left
: event
.pageX
- offset
.left
- ( closestHandle
.width() / 2 ),
7161 top
: event
.pageY
- offset
.top
-
7162 ( closestHandle
.height() / 2 ) -
7163 ( parseInt( closestHandle
.css("borderTopWidth"), 10 ) || 0 ) -
7164 ( parseInt( closestHandle
.css("borderBottomWidth"), 10 ) || 0) +
7165 ( parseInt( closestHandle
.css("marginTop"), 10 ) || 0)
7168 if ( !this.handles
.hasClass( "ui-state-hover" ) ) {
7169 this._slide( event
, index
, normValue
);
7171 this._animateOff
= true;
7175 _mouseStart: function( event
) {
7179 _mouseDrag: function( event
) {
7180 var position
= { x
: event
.pageX
, y
: event
.pageY
},
7181 normValue
= this._normValueFromMouse( position
);
7183 this._slide( event
, this._handleIndex
, normValue
);
7188 _mouseStop: function( event
) {
7189 this.handles
.removeClass( "ui-state-active" );
7190 this._mouseSliding
= false;
7192 this._stop( event
, this._handleIndex
);
7193 this._change( event
, this._handleIndex
);
7195 this._handleIndex
= null;
7196 this._clickOffset
= null;
7197 this._animateOff
= false;
7202 _detectOrientation: function() {
7203 this.orientation
= ( this.options
.orientation
=== "vertical" ) ? "vertical" : "horizontal";
7206 _normValueFromMouse: function( position
) {
7213 if ( this.orientation
=== "horizontal" ) {
7214 pixelTotal
= this.elementSize
.width
;
7215 pixelMouse
= position
.x
- this.elementOffset
.left
- ( this._clickOffset
? this._clickOffset
.left
: 0 );
7217 pixelTotal
= this.elementSize
.height
;
7218 pixelMouse
= position
.y
- this.elementOffset
.top
- ( this._clickOffset
? this._clickOffset
.top
: 0 );
7221 percentMouse
= ( pixelMouse
/ pixelTotal
);
7222 if ( percentMouse
> 1 ) {
7225 if ( percentMouse
< 0 ) {
7228 if ( this.orientation
=== "vertical" ) {
7229 percentMouse
= 1 - percentMouse
;
7232 valueTotal
= this._valueMax() - this._valueMin();
7233 valueMouse
= this._valueMin() + percentMouse
* valueTotal
;
7235 return this._trimAlignValue( valueMouse
);
7238 _start: function( event
, index
) {
7240 handle
: this.handles
[ index
],
7243 if ( this.options
.values
&& this.options
.values
.length
) {
7244 uiHash
.value
= this.values( index
);
7245 uiHash
.values
= this.values();
7247 return this._trigger( "start", event
, uiHash
);
7250 _slide: function( event
, index
, newVal
) {
7255 if ( this.options
.values
&& this.options
.values
.length
) {
7256 otherVal
= this.values( index
? 0 : 1 );
7258 if ( ( this.options
.values
.length
=== 2 && this.options
.range
=== true ) &&
7259 ( ( index
=== 0 && newVal
> otherVal
) || ( index
=== 1 && newVal
< otherVal
) )
7264 if ( newVal
!== this.values( index
) ) {
7265 newValues
= this.values();
7266 newValues
[ index
] = newVal
;
7267 // A slide can be canceled by returning false from the slide callback
7268 allowed
= this._trigger( "slide", event
, {
7269 handle
: this.handles
[ index
],
7273 otherVal
= this.values( index
? 0 : 1 );
7274 if ( allowed
!== false ) {
7275 this.values( index
, newVal
, true );
7279 if ( newVal
!== this.value() ) {
7280 // A slide can be canceled by returning false from the slide callback
7281 allowed
= this._trigger( "slide", event
, {
7282 handle
: this.handles
[ index
],
7285 if ( allowed
!== false ) {
7286 this.value( newVal
);
7292 _stop: function( event
, index
) {
7294 handle
: this.handles
[ index
],
7297 if ( this.options
.values
&& this.options
.values
.length
) {
7298 uiHash
.value
= this.values( index
);
7299 uiHash
.values
= this.values();
7302 this._trigger( "stop", event
, uiHash
);
7305 _change: function( event
, index
) {
7306 if ( !this._keySliding
&& !this._mouseSliding
) {
7308 handle
: this.handles
[ index
],
7311 if ( this.options
.values
&& this.options
.values
.length
) {
7312 uiHash
.value
= this.values( index
);
7313 uiHash
.values
= this.values();
7316 this._trigger( "change", event
, uiHash
);
7320 value: function( newValue
) {
7321 if ( arguments
.length
) {
7322 this.options
.value
= this._trimAlignValue( newValue
);
7323 this._refreshValue();
7324 this._change( null, 0 );
7328 return this._value();
7331 values: function( index
, newValue
) {
7336 if ( arguments
.length
> 1 ) {
7337 this.options
.values
[ index
] = this._trimAlignValue( newValue
);
7338 this._refreshValue();
7339 this._change( null, index
);
7343 if ( arguments
.length
) {
7344 if ( $.isArray( arguments
[ 0 ] ) ) {
7345 vals
= this.options
.values
;
7346 newValues
= arguments
[ 0 ];
7347 for ( i
= 0; i
< vals
.length
; i
+= 1 ) {
7348 vals
[ i
] = this._trimAlignValue( newValues
[ i
] );
7349 this._change( null, i
);
7351 this._refreshValue();
7353 if ( this.options
.values
&& this.options
.values
.length
) {
7354 return this._values( index
);
7356 return this.value();
7360 return this._values();
7364 _setOption: function( key
, value
) {
7368 if ( $.isArray( this.options
.values
) ) {
7369 valsLength
= this.options
.values
.length
;
7372 $.Widget
.prototype._setOption
.apply( this, arguments
);
7377 this.handles
.filter( ".ui-state-focus" ).blur();
7378 this.handles
.removeClass( "ui-state-hover" );
7379 this.handles
.propAttr( "disabled", true );
7380 this.element
.addClass( "ui-disabled" );
7382 this.handles
.propAttr( "disabled", false );
7383 this.element
.removeClass( "ui-disabled" );
7387 this._detectOrientation();
7389 .removeClass( "ui-slider-horizontal ui-slider-vertical" )
7390 .addClass( "ui-slider-" + this.orientation
);
7391 this._refreshValue();
7394 this._animateOff
= true;
7395 this._refreshValue();
7396 this._change( null, 0 );
7397 this._animateOff
= false;
7400 this._animateOff
= true;
7401 this._refreshValue();
7402 for ( i
= 0; i
< valsLength
; i
+= 1 ) {
7403 this._change( null, i
);
7405 this._animateOff
= false;
7410 //internal value getter
7411 // _value() returns value trimmed by min and max, aligned by step
7412 _value: function() {
7413 var val
= this.options
.value
;
7414 val
= this._trimAlignValue( val
);
7419 //internal values getter
7420 // _values() returns array of values trimmed by min and max, aligned by step
7421 // _values( index ) returns single value trimmed by min and max, aligned by step
7422 _values: function( index
) {
7427 if ( arguments
.length
) {
7428 val
= this.options
.values
[ index
];
7429 val
= this._trimAlignValue( val
);
7433 // .slice() creates a copy of the array
7434 // this copy gets trimmed by min and max and then returned
7435 vals
= this.options
.values
.slice();
7436 for ( i
= 0; i
< vals
.length
; i
+= 1) {
7437 vals
[ i
] = this._trimAlignValue( vals
[ i
] );
7444 // returns the step-aligned value that val is closest to, between (inclusive) min and max
7445 _trimAlignValue: function( val
) {
7446 if ( val
<= this._valueMin() ) {
7447 return this._valueMin();
7449 if ( val
>= this._valueMax() ) {
7450 return this._valueMax();
7452 var step
= ( this.options
.step
> 0 ) ? this.options
.step
: 1,
7453 valModStep
= (val
- this._valueMin()) % step
,
7454 alignValue
= val
- valModStep
;
7456 if ( Math
.abs(valModStep
) * 2 >= step
) {
7457 alignValue
+= ( valModStep
> 0 ) ? step
: ( -step
);
7460 // Since JavaScript has problems with large floats, round
7461 // the final value to 5 digits after the decimal point (see #4124)
7462 return parseFloat( alignValue
.toFixed(5) );
7465 _valueMin: function() {
7466 return this.options
.min
;
7469 _valueMax: function() {
7470 return this.options
.max
;
7473 _refreshValue: function() {
7474 var oRange
= this.options
.range
,
7477 animate
= ( !this._animateOff
) ? o
.animate
: false,
7485 if ( this.options
.values
&& this.options
.values
.length
) {
7486 this.handles
.each(function( i
, j
) {
7487 valPercent
= ( self
.values(i
) - self
._valueMin() ) / ( self
._valueMax() - self
._valueMin() ) * 100;
7488 _set
[ self
.orientation
=== "horizontal" ? "left" : "bottom" ] = valPercent
+ "%";
7489 $( this ).stop( 1, 1 )[ animate
? "animate" : "css" ]( _set
, o
.animate
);
7490 if ( self
.options
.range
=== true ) {
7491 if ( self
.orientation
=== "horizontal" ) {
7493 self
.range
.stop( 1, 1 )[ animate
? "animate" : "css" ]( { left
: valPercent
+ "%" }, o
.animate
);
7496 self
.range
[ animate
? "animate" : "css" ]( { width
: ( valPercent
- lastValPercent
) + "%" }, { queue
: false, duration
: o
.animate
} );
7500 self
.range
.stop( 1, 1 )[ animate
? "animate" : "css" ]( { bottom
: ( valPercent
) + "%" }, o
.animate
);
7503 self
.range
[ animate
? "animate" : "css" ]( { height
: ( valPercent
- lastValPercent
) + "%" }, { queue
: false, duration
: o
.animate
} );
7507 lastValPercent
= valPercent
;
7510 value
= this.value();
7511 valueMin
= this._valueMin();
7512 valueMax
= this._valueMax();
7513 valPercent
= ( valueMax
!== valueMin
) ?
7514 ( value
- valueMin
) / ( valueMax
- valueMin
) * 100 :
7516 _set
[ self
.orientation
=== "horizontal" ? "left" : "bottom" ] = valPercent
+ "%";
7517 this.handle
.stop( 1, 1 )[ animate
? "animate" : "css" ]( _set
, o
.animate
);
7519 if ( oRange
=== "min" && this.orientation
=== "horizontal" ) {
7520 this.range
.stop( 1, 1 )[ animate
? "animate" : "css" ]( { width
: valPercent
+ "%" }, o
.animate
);
7522 if ( oRange
=== "max" && this.orientation
=== "horizontal" ) {
7523 this.range
[ animate
? "animate" : "css" ]( { width
: ( 100 - valPercent
) + "%" }, { queue
: false, duration
: o
.animate
} );
7525 if ( oRange
=== "min" && this.orientation
=== "vertical" ) {
7526 this.range
.stop( 1, 1 )[ animate
? "animate" : "css" ]( { height
: valPercent
+ "%" }, o
.animate
);
7528 if ( oRange
=== "max" && this.orientation
=== "vertical" ) {
7529 this.range
[ animate
? "animate" : "css" ]( { height
: ( 100 - valPercent
) + "%" }, { queue
: false, duration
: o
.animate
} );
7536 $.extend( $.ui
.slider
, {
7542 * jQuery UI Tabs 1.8.21
7544 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
7545 * Dual licensed under the MIT or GPL Version 2 licenses.
7546 * http://jquery.org/license
7548 * http://docs.jquery.com/UI/Tabs
7552 * jquery.ui.widget.js
7554 (function( $, undefined ) {
7559 function getNextTabId() {
7563 function getNextListId() {
7567 $.widget( "ui.tabs", {
7572 cookie
: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
7578 fx
: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
7579 idPrefix
: "ui-tabs-",
7581 panelTemplate
: "<div></div>",
7585 spinner
: "<em>Loading…</em>",
7586 tabTemplate
: "<li><a href='#{href}'><span>#{label}</span></a></li>"
7589 _create: function() {
7590 this._tabify( true );
7593 _setOption: function( key
, value
) {
7594 if ( key
== "selected" ) {
7595 if (this.options
.collapsible
&& value
== this.options
.selected
) {
7598 this.select( value
);
7600 this.options
[ key
] = value
;
7605 _tabId: function( a
) {
7606 return a
.title
&& a
.title
.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
7607 this.options
.idPrefix
+ getNextTabId();
7610 _sanitizeSelector: function( hash
) {
7611 // we need this because an id may contain a ":"
7612 return hash
.replace( /:/g
, "\\:" );
7615 _cookie: function() {
7616 var cookie
= this.cookie
||
7617 ( this.cookie
= this.options
.cookie
.name
|| "ui-tabs-" + getNextListId() );
7618 return $.cookie
.apply( null, [ cookie
].concat( $.makeArray( arguments
) ) );
7621 _ui: function( tab
, panel
) {
7625 index
: this.anchors
.index( tab
)
7629 _cleanup: function() {
7630 // restore all former loading tabs labels
7631 this.lis
.filter( ".ui-state-processing" )
7632 .removeClass( "ui-state-processing" )
7633 .find( "span:data(label.tabs)" )
7636 el
.html( el
.data( "label.tabs" ) ).removeData( "label.tabs" );
7640 _tabify: function( init
) {
7643 fragmentId
= /^#.+/; // Safari 2 reports '#' for an empty hash
7645 this.list
= this.element
.find( "ol,ul" ).eq( 0 );
7646 this.lis
= $( " > li:has(a[href])", this.list
);
7647 this.anchors
= this.lis
.map(function() {
7648 return $( "a", this )[ 0 ];
7650 this.panels
= $( [] );
7652 this.anchors
.each(function( i
, a
) {
7653 var href
= $( a
).attr( "href" );
7654 // For dynamically created HTML that contains a hash as href IE < 8 expands
7655 // such href to the full page url with hash and then misinterprets tab as ajax.
7656 // Same consideration applies for an added tab with a fragment identifier
7657 // since a[href=#fragment-identifier] does unexpectedly not match.
7658 // Thus normalize href attribute...
7659 var hrefBase
= href
.split( "#" )[ 0 ],
7661 if ( hrefBase
&& ( hrefBase
=== location
.toString().split( "#" )[ 0 ] ||
7662 ( baseEl
= $( "base" )[ 0 ]) && hrefBase
=== baseEl
.href
) ) {
7668 if ( fragmentId
.test( href
) ) {
7669 self
.panels
= self
.panels
.add( self
.element
.find( self
._sanitizeSelector( href
) ) );
7671 // prevent loading the page itself if href is just "#"
7672 } else if ( href
&& href
!== "#" ) {
7673 // required for restore on destroy
7674 $.data( a
, "href.tabs", href
);
7676 // TODO until #3808 is fixed strip fragment identifier from url
7677 // (IE fails to load from such url)
7678 $.data( a
, "load.tabs", href
.replace( /#.*$/, "" ) );
7680 var id
= self
._tabId( a
);
7682 var $panel
= self
.element
.find( "#" + id
);
7683 if ( !$panel
.length
) {
7684 $panel
= $( o
.panelTemplate
)
7686 .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
7687 .insertAfter( self
.panels
[ i
- 1 ] || self
.list
);
7688 $panel
.data( "destroy.tabs", true );
7690 self
.panels
= self
.panels
.add( $panel
);
7693 o
.disabled
.push( i
);
7697 // initialization from scratch
7699 // attach necessary classes for styling
7700 this.element
.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" );
7701 this.list
.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
7702 this.lis
.addClass( "ui-state-default ui-corner-top" );
7703 this.panels
.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" );
7706 // use "selected" option or try to retrieve:
7707 // 1. from fragment identifier in url
7709 // 3. from selected class attribute on <li>
7710 if ( o
.selected
=== undefined ) {
7711 if ( location
.hash
) {
7712 this.anchors
.each(function( i
, a
) {
7713 if ( a
.hash
== location
.hash
) {
7719 if ( typeof o
.selected
!== "number" && o
.cookie
) {
7720 o
.selected
= parseInt( self
._cookie(), 10 );
7722 if ( typeof o
.selected
!== "number" && this.lis
.filter( ".ui-tabs-selected" ).length
) {
7723 o
.selected
= this.lis
.index( this.lis
.filter( ".ui-tabs-selected" ) );
7725 o
.selected
= o
.selected
|| ( this.lis
.length
? 0 : -1 );
7726 } else if ( o
.selected
=== null ) { // usage of null is deprecated, TODO remove in next release
7730 // sanity check - default to first tab...
7731 o
.selected
= ( ( o
.selected
>= 0 && this.anchors
[ o
.selected
] ) || o
.selected
< 0 )
7735 // Take disabling tabs via class attribute from HTML
7736 // into account and update option properly.
7737 // A selected tab cannot become disabled.
7738 o
.disabled
= $.unique( o
.disabled
.concat(
7739 $.map( this.lis
.filter( ".ui-state-disabled" ), function( n
, i
) {
7740 return self
.lis
.index( n
);
7744 if ( $.inArray( o
.selected
, o
.disabled
) != -1 ) {
7745 o
.disabled
.splice( $.inArray( o
.selected
, o
.disabled
), 1 );
7748 // highlight selected tab
7749 this.panels
.addClass( "ui-tabs-hide" );
7750 this.lis
.removeClass( "ui-tabs-selected ui-state-active" );
7751 // check for length avoids error when initializing empty list
7752 if ( o
.selected
>= 0 && this.anchors
.length
) {
7753 self
.element
.find( self
._sanitizeSelector( self
.anchors
[ o
.selected
].hash
) ).removeClass( "ui-tabs-hide" );
7754 this.lis
.eq( o
.selected
).addClass( "ui-tabs-selected ui-state-active" );
7756 // seems to be expected behavior that the show callback is fired
7757 self
.element
.queue( "tabs", function() {
7758 self
._trigger( "show", null,
7759 self
._ui( self
.anchors
[ o
.selected
], self
.element
.find( self
._sanitizeSelector( self
.anchors
[ o
.selected
].hash
) )[ 0 ] ) );
7762 this.load( o
.selected
);
7765 // clean up to avoid memory leaks in certain versions of IE 6
7766 // TODO: namespace this event
7767 $( window
).bind( "unload", function() {
7768 self
.lis
.add( self
.anchors
).unbind( ".tabs" );
7769 self
.lis
= self
.anchors
= self
.panels
= null;
7771 // update selected after add/remove
7773 o
.selected
= this.lis
.index( this.lis
.filter( ".ui-tabs-selected" ) );
7776 // update collapsible
7777 // TODO: use .toggleClass()
7778 this.element
[ o
.collapsible
? "addClass" : "removeClass" ]( "ui-tabs-collapsible" );
7780 // set or update cookie after init and add/remove respectively
7782 this._cookie( o
.selected
, o
.cookie
);
7786 for ( var i
= 0, li
; ( li
= this.lis
[ i
] ); i
++ ) {
7787 $( li
)[ $.inArray( i
, o
.disabled
) != -1 &&
7788 // TODO: use .toggleClass()
7789 !$( li
).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" );
7792 // reset cache if switching from cached to not cached
7793 if ( o
.cache
=== false ) {
7794 this.anchors
.removeData( "cache.tabs" );
7797 // remove all handlers before, tabify may run on existing tabs after add or option change
7798 this.lis
.add( this.anchors
).unbind( ".tabs" );
7800 if ( o
.event
!== "mouseover" ) {
7801 var addState = function( state
, el
) {
7802 if ( el
.is( ":not(.ui-state-disabled)" ) ) {
7803 el
.addClass( "ui-state-" + state
);
7806 var removeState = function( state
, el
) {
7807 el
.removeClass( "ui-state-" + state
);
7809 this.lis
.bind( "mouseover.tabs" , function() {
7810 addState( "hover", $( this ) );
7812 this.lis
.bind( "mouseout.tabs", function() {
7813 removeState( "hover", $( this ) );
7815 this.anchors
.bind( "focus.tabs", function() {
7816 addState( "focus", $( this ).closest( "li" ) );
7818 this.anchors
.bind( "blur.tabs", function() {
7819 removeState( "focus", $( this ).closest( "li" ) );
7823 // set up animations
7826 if ( $.isArray( o
.fx
) ) {
7830 hideFx
= showFx
= o
.fx
;
7834 // Reset certain styles left over from animation
7835 // and prevent IE's ClearType bug...
7836 function resetStyle( $el
, fx
) {
7837 $el
.css( "display", "" );
7838 if ( !$.support
.opacity
&& fx
.opacity
) {
7839 $el
[ 0 ].style
.removeAttribute( "filter" );
7844 var showTab
= showFx
7845 ? function( clicked
, $show
) {
7846 $( clicked
).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
7847 $show
.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way
7848 .animate( showFx
, showFx
.duration
|| "normal", function() {
7849 resetStyle( $show
, showFx
);
7850 self
._trigger( "show", null, self
._ui( clicked
, $show
[ 0 ] ) );
7853 : function( clicked
, $show
) {
7854 $( clicked
).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" );
7855 $show
.removeClass( "ui-tabs-hide" );
7856 self
._trigger( "show", null, self
._ui( clicked
, $show
[ 0 ] ) );
7859 // Hide a tab, $show is optional...
7860 var hideTab
= hideFx
7861 ? function( clicked
, $hide
) {
7862 $hide
.animate( hideFx
, hideFx
.duration
|| "normal", function() {
7863 self
.lis
.removeClass( "ui-tabs-selected ui-state-active" );
7864 $hide
.addClass( "ui-tabs-hide" );
7865 resetStyle( $hide
, hideFx
);
7866 self
.element
.dequeue( "tabs" );
7869 : function( clicked
, $hide
, $show
) {
7870 self
.lis
.removeClass( "ui-tabs-selected ui-state-active" );
7871 $hide
.addClass( "ui-tabs-hide" );
7872 self
.element
.dequeue( "tabs" );
7875 // attach tab event handler, unbind to avoid duplicates from former tabifying...
7876 this.anchors
.bind( o
.event
+ ".tabs", function() {
7878 $li
= $(el
).closest( "li" ),
7879 $hide
= self
.panels
.filter( ":not(.ui-tabs-hide)" ),
7880 $show
= self
.element
.find( self
._sanitizeSelector( el
.hash
) );
7882 // If tab is already selected and not collapsible or tab disabled or
7883 // or is already loading or click callback returns false stop here.
7884 // Check if click handler returns false last so that it is not executed
7885 // for a disabled or loading tab!
7886 if ( ( $li
.hasClass( "ui-tabs-selected" ) && !o
.collapsible
) ||
7887 $li
.hasClass( "ui-state-disabled" ) ||
7888 $li
.hasClass( "ui-state-processing" ) ||
7889 self
.panels
.filter( ":animated" ).length
||
7890 self
._trigger( "select", null, self
._ui( this, $show
[ 0 ] ) ) === false ) {
7895 o
.selected
= self
.anchors
.index( this );
7899 // if tab may be closed
7900 if ( o
.collapsible
) {
7901 if ( $li
.hasClass( "ui-tabs-selected" ) ) {
7905 self
._cookie( o
.selected
, o
.cookie
);
7908 self
.element
.queue( "tabs", function() {
7909 hideTab( el
, $hide
);
7910 }).dequeue( "tabs" );
7914 } else if ( !$hide
.length
) {
7916 self
._cookie( o
.selected
, o
.cookie
);
7919 self
.element
.queue( "tabs", function() {
7920 showTab( el
, $show
);
7923 // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
7924 self
.load( self
.anchors
.index( this ) );
7932 self
._cookie( o
.selected
, o
.cookie
);
7936 if ( $show
.length
) {
7937 if ( $hide
.length
) {
7938 self
.element
.queue( "tabs", function() {
7939 hideTab( el
, $hide
);
7942 self
.element
.queue( "tabs", function() {
7943 showTab( el
, $show
);
7946 self
.load( self
.anchors
.index( this ) );
7948 throw "jQuery UI Tabs: Mismatching fragment identifier.";
7951 // Prevent IE from keeping other link focussed when using the back button
7952 // and remove dotted border from clicked link. This is controlled via CSS
7953 // in modern browsers; blur() removes focus from address bar in Firefox
7954 // which can become a usability and annoying problem with tabs('rotate').
7955 if ( $.browser
.msie
) {
7960 // disable click in any case
7961 this.anchors
.bind( "click.tabs", function(){
7966 _getIndex: function( index
) {
7967 // meta-function to give users option to provide a href string instead of a numerical index.
7968 // also sanitizes numerical indexes to valid values.
7969 if ( typeof index
== "string" ) {
7970 index
= this.anchors
.index( this.anchors
.filter( "[href$='" + index
+ "']" ) );
7976 destroy: function() {
7977 var o
= this.options
;
7983 .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" )
7984 .removeData( "tabs" );
7986 this.list
.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
7988 this.anchors
.each(function() {
7989 var href
= $.data( this, "href.tabs" );
7993 var $this = $( this ).unbind( ".tabs" );
7994 $.each( [ "href", "load", "cache" ], function( i
, prefix
) {
7995 $this.removeData( prefix
+ ".tabs" );
7999 this.lis
.unbind( ".tabs" ).add( this.panels
).each(function() {
8000 if ( $.data( this, "destroy.tabs" ) ) {
8003 $( this ).removeClass([
8010 "ui-state-disabled",
8012 "ui-widget-content",
8020 this._cookie( null, o
.cookie
);
8026 add: function( url
, label
, index
) {
8027 if ( index
=== undefined ) {
8028 index
= this.anchors
.length
;
8033 $li
= $( o
.tabTemplate
.replace( /#\{href\}/g, url
).replace( /#\{label\}/g, label
) ),
8034 id
= !url
.indexOf( "#" ) ? url
.replace( "#", "" ) : this._tabId( $( "a", $li
)[ 0 ] );
8036 $li
.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true );
8038 // try to find an existing element before creating a new one
8039 var $panel
= self
.element
.find( "#" + id
);
8040 if ( !$panel
.length
) {
8041 $panel
= $( o
.panelTemplate
)
8043 .data( "destroy.tabs", true );
8045 $panel
.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" );
8047 if ( index
>= this.lis
.length
) {
8048 $li
.appendTo( this.list
);
8049 $panel
.appendTo( this.list
[ 0 ].parentNode
);
8051 $li
.insertBefore( this.lis
[ index
] );
8052 $panel
.insertBefore( this.panels
[ index
] );
8055 o
.disabled
= $.map( o
.disabled
, function( n
, i
) {
8056 return n
>= index
? ++n
: n
;
8061 if ( this.anchors
.length
== 1 ) {
8063 $li
.addClass( "ui-tabs-selected ui-state-active" );
8064 $panel
.removeClass( "ui-tabs-hide" );
8065 this.element
.queue( "tabs", function() {
8066 self
._trigger( "show", null, self
._ui( self
.anchors
[ 0 ], self
.panels
[ 0 ] ) );
8072 this._trigger( "add", null, this._ui( this.anchors
[ index
], this.panels
[ index
] ) );
8076 remove: function( index
) {
8077 index
= this._getIndex( index
);
8078 var o
= this.options
,
8079 $li
= this.lis
.eq( index
).remove(),
8080 $panel
= this.panels
.eq( index
).remove();
8082 // If selected tab was removed focus tab to the right or
8083 // in case the last tab was removed the tab to the left.
8084 if ( $li
.hasClass( "ui-tabs-selected" ) && this.anchors
.length
> 1) {
8085 this.select( index
+ ( index
+ 1 < this.anchors
.length
? 1 : -1 ) );
8089 $.grep( o
.disabled
, function(n
, i
) {
8093 return n
>= index
? --n
: n
;
8098 this._trigger( "remove", null, this._ui( $li
.find( "a" )[ 0 ], $panel
[ 0 ] ) );
8102 enable: function( index
) {
8103 index
= this._getIndex( index
);
8104 var o
= this.options
;
8105 if ( $.inArray( index
, o
.disabled
) == -1 ) {
8109 this.lis
.eq( index
).removeClass( "ui-state-disabled" );
8110 o
.disabled
= $.grep( o
.disabled
, function( n
, i
) {
8114 this._trigger( "enable", null, this._ui( this.anchors
[ index
], this.panels
[ index
] ) );
8118 disable: function( index
) {
8119 index
= this._getIndex( index
);
8120 var self
= this, o
= this.options
;
8121 // cannot disable already selected tab
8122 if ( index
!= o
.selected
) {
8123 this.lis
.eq( index
).addClass( "ui-state-disabled" );
8125 o
.disabled
.push( index
);
8128 this._trigger( "disable", null, this._ui( this.anchors
[ index
], this.panels
[ index
] ) );
8134 select: function( index
) {
8135 index
= this._getIndex( index
);
8136 if ( index
== -1 ) {
8137 if ( this.options
.collapsible
&& this.options
.selected
!= -1 ) {
8138 index
= this.options
.selected
;
8143 this.anchors
.eq( index
).trigger( this.options
.event
+ ".tabs" );
8147 load: function( index
) {
8148 index
= this._getIndex( index
);
8151 a
= this.anchors
.eq( index
)[ 0 ],
8152 url
= $.data( a
, "load.tabs" );
8156 // not remote or from cache
8157 if ( !url
|| this.element
.queue( "tabs" ).length
!== 0 && $.data( a
, "cache.tabs" ) ) {
8158 this.element
.dequeue( "tabs" );
8162 // load remote from here on
8163 this.lis
.eq( index
).addClass( "ui-state-processing" );
8166 var span
= $( "span", a
);
8167 span
.data( "label.tabs", span
.html() ).html( o
.spinner
);
8170 this.xhr
= $.ajax( $.extend( {}, o
.ajaxOptions
, {
8172 success: function( r
, s
) {
8173 self
.element
.find( self
._sanitizeSelector( a
.hash
) ).html( r
);
8175 // take care of tab labels
8179 $.data( a
, "cache.tabs", true );
8182 self
._trigger( "load", null, self
._ui( self
.anchors
[ index
], self
.panels
[ index
] ) );
8184 o
.ajaxOptions
.success( r
, s
);
8188 error: function( xhr
, s
, e
) {
8189 // take care of tab labels
8192 self
._trigger( "load", null, self
._ui( self
.anchors
[ index
], self
.panels
[ index
] ) );
8194 // Passing index avoid a race condition when this method is
8195 // called after the user has selected another tab.
8196 // Pass the anchor that initiated this request allows
8197 // loadError to manipulate the tab content panel via $(a.hash)
8198 o
.ajaxOptions
.error( xhr
, s
, index
, a
);
8204 // last, so that load event is fired before show...
8205 self
.element
.dequeue( "tabs" );
8211 // stop possibly running animations
8212 this.element
.queue( [] );
8213 this.panels
.stop( false, true );
8215 // "tabs" queue must not contain more than two elements,
8216 // which are the callbacks for the latest clicked tab...
8217 this.element
.queue( "tabs", this.element
.queue( "tabs" ).splice( -2, 2 ) );
8219 // terminate pending requests from other tabs
8225 // take care of tab labels
8230 url: function( index
, url
) {
8231 this.anchors
.eq( index
).removeData( "cache.tabs" ).data( "load.tabs", url
);
8235 length: function() {
8236 return this.anchors
.length
;
8240 $.extend( $.ui
.tabs
, {
8251 $.extend( $.ui
.tabs
.prototype, {
8253 rotate: function( ms
, continuing
) {
8257 var rotate
= self
._rotate
|| ( self
._rotate = function( e
) {
8258 clearTimeout( self
.rotation
);
8259 self
.rotation
= setTimeout(function() {
8261 self
.select( ++t
< self
.anchors
.length
? t
: 0 );
8265 e
.stopPropagation();
8269 var stop
= self
._unrotate
|| ( self
._unrotate
= !continuing
8271 if (e
.clientX
) { // in case of a true click
8281 this.element
.bind( "tabsshow", rotate
);
8282 this.anchors
.bind( o
.event
+ ".tabs", stop
);
8286 clearTimeout( self
.rotation
);
8287 this.element
.unbind( "tabsshow", rotate
);
8288 this.anchors
.unbind( o
.event
+ ".tabs", stop
);
8289 delete this._rotate
;
8290 delete this._unrotate
;
8299 * jQuery UI Datepicker 1.8.21
8301 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
8302 * Dual licensed under the MIT or GPL Version 2 licenses.
8303 * http://jquery.org/license
8305 * http://docs.jquery.com/UI/Datepicker
8310 (function( $, undefined ) {
8312 $.extend($.ui
, { datepicker
: { version
: "1.8.21" } });
8314 var PROP_NAME
= 'datepicker';
8315 var dpuuid
= new Date().getTime();
8318 /* Date picker manager.
8319 Use the singleton instance of this class, $.datepicker, to interact with the date picker.
8320 Settings for (groups of) date pickers are maintained in an instance object,
8321 allowing multiple different settings on the same page. */
8323 function Datepicker() {
8324 this.debug
= false; // Change this to true to start debugging
8325 this._curInst
= null; // The current instance in use
8326 this._keyEvent
= false; // If the last event was a key event
8327 this._disabledInputs
= []; // List of date picker inputs that have been disabled
8328 this._datepickerShowing
= false; // True if the popup picker is showing , false if not
8329 this._inDialog
= false; // True if showing within a "dialog", false if not
8330 this._mainDivId
= 'ui-datepicker-div'; // The ID of the main datepicker division
8331 this._inlineClass
= 'ui-datepicker-inline'; // The name of the inline marker class
8332 this._appendClass
= 'ui-datepicker-append'; // The name of the append marker class
8333 this._triggerClass
= 'ui-datepicker-trigger'; // The name of the trigger marker class
8334 this._dialogClass
= 'ui-datepicker-dialog'; // The name of the dialog marker class
8335 this._disableClass
= 'ui-datepicker-disabled'; // The name of the disabled covering marker class
8336 this._unselectableClass
= 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class
8337 this._currentClass
= 'ui-datepicker-current-day'; // The name of the current day marker class
8338 this._dayOverClass
= 'ui-datepicker-days-cell-over'; // The name of the day hover marker class
8339 this.regional
= []; // Available regional settings, indexed by language code
8340 this.regional
[''] = { // Default regional settings
8341 closeText
: 'Done', // Display text for close link
8342 prevText
: 'Prev', // Display text for previous month link
8343 nextText
: 'Next', // Display text for next month link
8344 currentText
: 'Today', // Display text for current month link
8345 monthNames
: ['January','February','March','April','May','June',
8346 'July','August','September','October','November','December'], // Names of months for drop-down and formatting
8347 monthNamesShort
: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
8348 dayNames
: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
8349 dayNamesShort
: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
8350 dayNamesMin
: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
8351 weekHeader
: 'Wk', // Column header for week of the year
8352 dateFormat
: 'mm/dd/yy', // See format options on parseDate
8353 firstDay
: 0, // The first day of the week, Sun = 0, Mon = 1, ...
8354 isRTL
: false, // True if right-to-left language, false if left-to-right
8355 showMonthAfterYear
: false, // True if the year select precedes month, false for month then year
8356 yearSuffix
: '' // Additional text to append to the year in the month headers
8358 this._defaults
= { // Global defaults for all the date picker instances
8359 showOn
: 'focus', // 'focus' for popup on focus,
8360 // 'button' for trigger button, or 'both' for either
8361 showAnim
: 'fadeIn', // Name of jQuery animation for popup
8362 showOptions
: {}, // Options for enhanced animations
8363 defaultDate
: null, // Used when field is blank: actual date,
8364 // +/-number for offset from today, null for today
8365 appendText
: '', // Display text following the input box, e.g. showing the format
8366 buttonText
: '...', // Text for trigger button
8367 buttonImage
: '', // URL for trigger button image
8368 buttonImageOnly
: false, // True if the image appears alone, false if it appears on a button
8369 hideIfNoPrevNext
: false, // True to hide next/previous month links
8370 // if not applicable, false to just disable them
8371 navigationAsDateFormat
: false, // True if date formatting applied to prev/today/next links
8372 gotoCurrent
: false, // True if today link goes back to current selection instead
8373 changeMonth
: false, // True if month can be selected directly, false if only prev/next
8374 changeYear
: false, // True if year can be selected directly, false if only prev/next
8375 yearRange
: 'c-10:c+10', // Range of years to display in drop-down,
8376 // either relative to today's year (-nn:+nn), relative to currently displayed year
8377 // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
8378 showOtherMonths
: false, // True to show dates in other months, false to leave blank
8379 selectOtherMonths
: false, // True to allow selection of dates in other months, false for unselectable
8380 showWeek
: false, // True to show week of the year, false to not show it
8381 calculateWeek
: this.iso8601Week
, // How to calculate the week of the year,
8382 // takes a Date and returns the number of the week for it
8383 shortYearCutoff
: '+10', // Short year values < this are in the current century,
8384 // > this are in the previous century,
8385 // string value starting with '+' for current year + value
8386 minDate
: null, // The earliest selectable date, or null for no limit
8387 maxDate
: null, // The latest selectable date, or null for no limit
8388 duration
: 'fast', // Duration of display/closure
8389 beforeShowDay
: null, // Function that takes a date and returns an array with
8390 // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '',
8391 // [2] = cell title (optional), e.g. $.datepicker.noWeekends
8392 beforeShow
: null, // Function that takes an input field and
8393 // returns a set of custom settings for the date picker
8394 onSelect
: null, // Define a callback function when a date is selected
8395 onChangeMonthYear
: null, // Define a callback function when the month or year is changed
8396 onClose
: null, // Define a callback function when the datepicker is closed
8397 numberOfMonths
: 1, // Number of months to show at a time
8398 showCurrentAtPos
: 0, // The position in multipe months at which to show the current month (starting at 0)
8399 stepMonths
: 1, // Number of months to step back/forward
8400 stepBigMonths
: 12, // Number of months to step back/forward for the big links
8401 altField
: '', // Selector for an alternate field to store selected dates into
8402 altFormat
: '', // The date format to use for the alternate field
8403 constrainInput
: true, // The input is constrained by the current date format
8404 showButtonPanel
: false, // True to show button panel, false to not show it
8405 autoSize
: false, // True to size the input for the date format, false to leave as is
8406 disabled
: false // The initial disabled state
8408 $.extend(this._defaults
, this.regional
['']);
8409 this.dpDiv
= bindHover($('<div id="' + this._mainDivId
+ '" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'));
8412 $.extend(Datepicker
.prototype, {
8413 /* Class name added to elements to indicate already configured with a date picker. */
8414 markerClassName
: 'hasDatepicker',
8416 //Keep track of the maximum number of rows displayed (see #7043)
8419 /* Debug logging (if enabled). */
8422 console
.log
.apply('', arguments
);
8425 // TODO rename to "widget" when switching to widget factory
8426 _widgetDatepicker: function() {
8430 /* Override the default settings for all instances of the date picker.
8431 @param settings object - the new settings to use as defaults (anonymous object)
8432 @return the manager object */
8433 setDefaults: function(settings
) {
8434 extendRemove(this._defaults
, settings
|| {});
8438 /* Attach the date picker to a jQuery selection.
8439 @param target element - the target input field or division or span
8440 @param settings object - the new settings to use for this date picker instance (anonymous) */
8441 _attachDatepicker: function(target
, settings
) {
8442 // check for settings on the control itself - in namespace 'date:'
8443 var inlineSettings
= null;
8444 for (var attrName
in this._defaults
) {
8445 var attrValue
= target
.getAttribute('date:' + attrName
);
8447 inlineSettings
= inlineSettings
|| {};
8449 inlineSettings
[attrName
] = eval(attrValue
);
8451 inlineSettings
[attrName
] = attrValue
;
8455 var nodeName
= target
.nodeName
.toLowerCase();
8456 var inline
= (nodeName
== 'div' || nodeName
== 'span');
8459 target
.id
= 'dp' + this.uuid
;
8461 var inst
= this._newInst($(target
), inline
);
8462 inst
.settings
= $.extend({}, settings
|| {}, inlineSettings
|| {});
8463 if (nodeName
== 'input') {
8464 this._connectDatepicker(target
, inst
);
8465 } else if (inline
) {
8466 this._inlineDatepicker(target
, inst
);
8470 /* Create a new instance object. */
8471 _newInst: function(target
, inline
) {
8472 var id
= target
[0].id
.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars
8473 return {id
: id
, input
: target
, // associated target
8474 selectedDay
: 0, selectedMonth
: 0, selectedYear
: 0, // current selection
8475 drawMonth
: 0, drawYear
: 0, // month being drawn
8476 inline
: inline
, // is datepicker inline or not
8477 dpDiv
: (!inline
? this.dpDiv
: // presentation div
8478 bindHover($('<div class="' + this._inlineClass
+ ' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')))};
8481 /* Attach the date picker to an input field. */
8482 _connectDatepicker: function(target
, inst
) {
8483 var input
= $(target
);
8484 inst
.append
= $([]);
8485 inst
.trigger
= $([]);
8486 if (input
.hasClass(this.markerClassName
))
8488 this._attachments(input
, inst
);
8489 input
.addClass(this.markerClassName
).keydown(this._doKeyDown
).
8490 keypress(this._doKeyPress
).keyup(this._doKeyUp
).
8491 bind("setData.datepicker", function(event
, key
, value
) {
8492 inst
.settings
[key
] = value
;
8493 }).bind("getData.datepicker", function(event
, key
) {
8494 return this._get(inst
, key
);
8496 this._autoSize(inst
);
8497 $.data(target
, PROP_NAME
, inst
);
8498 //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
8499 if( inst
.settings
.disabled
) {
8500 this._disableDatepicker( target
);
8504 /* Make attachments based on settings. */
8505 _attachments: function(input
, inst
) {
8506 var appendText
= this._get(inst
, 'appendText');
8507 var isRTL
= this._get(inst
, 'isRTL');
8509 inst
.append
.remove();
8511 inst
.append
= $('<span class="' + this._appendClass
+ '">' + appendText
+ '</span>');
8512 input
[isRTL
? 'before' : 'after'](inst
.append
);
8514 input
.unbind('focus', this._showDatepicker
);
8516 inst
.trigger
.remove();
8517 var showOn
= this._get(inst
, 'showOn');
8518 if (showOn
== 'focus' || showOn
== 'both') // pop-up date picker when in the marked field
8519 input
.focus(this._showDatepicker
);
8520 if (showOn
== 'button' || showOn
== 'both') { // pop-up date picker when button clicked
8521 var buttonText
= this._get(inst
, 'buttonText');
8522 var buttonImage
= this._get(inst
, 'buttonImage');
8523 inst
.trigger
= $(this._get(inst
, 'buttonImageOnly') ?
8524 $('<img/>').addClass(this._triggerClass
).
8525 attr({ src
: buttonImage
, alt
: buttonText
, title
: buttonText
}) :
8526 $('<button type="button"></button>').addClass(this._triggerClass
).
8527 html(buttonImage
== '' ? buttonText
: $('<img/>').attr(
8528 { src
:buttonImage
, alt
:buttonText
, title
:buttonText
})));
8529 input
[isRTL
? 'before' : 'after'](inst
.trigger
);
8530 inst
.trigger
.click(function() {
8531 if ($.datepicker
._datepickerShowing
&& $.datepicker
._lastInput
== input
[0])
8532 $.datepicker
._hideDatepicker();
8533 else if ($.datepicker
._datepickerShowing
&& $.datepicker
._lastInput
!= input
[0]) {
8534 $.datepicker
._hideDatepicker();
8535 $.datepicker
._showDatepicker(input
[0]);
8537 $.datepicker
._showDatepicker(input
[0]);
8543 /* Apply the maximum length for the date format. */
8544 _autoSize: function(inst
) {
8545 if (this._get(inst
, 'autoSize') && !inst
.inline
) {
8546 var date
= new Date(2009, 12 - 1, 20); // Ensure double digits
8547 var dateFormat
= this._get(inst
, 'dateFormat');
8548 if (dateFormat
.match(/[DM]/)) {
8549 var findMax = function(names
) {
8552 for (var i
= 0; i
< names
.length
; i
++) {
8553 if (names
[i
].length
> max
) {
8554 max
= names
[i
].length
;
8560 date
.setMonth(findMax(this._get(inst
, (dateFormat
.match(/MM/) ?
8561 'monthNames' : 'monthNamesShort'))));
8562 date
.setDate(findMax(this._get(inst
, (dateFormat
.match(/DD/) ?
8563 'dayNames' : 'dayNamesShort'))) + 20 - date
.getDay());
8565 inst
.input
.attr('size', this._formatDate(inst
, date
).length
);
8569 /* Attach an inline date picker to a div. */
8570 _inlineDatepicker: function(target
, inst
) {
8571 var divSpan
= $(target
);
8572 if (divSpan
.hasClass(this.markerClassName
))
8574 divSpan
.addClass(this.markerClassName
).append(inst
.dpDiv
).
8575 bind("setData.datepicker", function(event
, key
, value
){
8576 inst
.settings
[key
] = value
;
8577 }).bind("getData.datepicker", function(event
, key
){
8578 return this._get(inst
, key
);
8580 $.data(target
, PROP_NAME
, inst
);
8581 this._setDate(inst
, this._getDefaultDate(inst
), true);
8582 this._updateDatepicker(inst
);
8583 this._updateAlternate(inst
);
8584 //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
8585 if( inst
.settings
.disabled
) {
8586 this._disableDatepicker( target
);
8588 // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
8589 // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
8590 inst
.dpDiv
.css( "display", "block" );
8593 /* Pop-up the date picker in a "dialog" box.
8594 @param input element - ignored
8595 @param date string or Date - the initial date to display
8596 @param onSelect function - the function to call when a date is selected
8597 @param settings object - update the dialog date picker instance's settings (anonymous object)
8598 @param pos int[2] - coordinates for the dialog's position within the screen or
8599 event - with x/y coordinates or
8600 leave empty for default (screen centre)
8601 @return the manager object */
8602 _dialogDatepicker: function(input
, date
, onSelect
, settings
, pos
) {
8603 var inst
= this._dialogInst
; // internal instance
8606 var id
= 'dp' + this.uuid
;
8607 this._dialogInput
= $('<input type="text" id="' + id
+
8608 '" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>');
8609 this._dialogInput
.keydown(this._doKeyDown
);
8610 $('body').append(this._dialogInput
);
8611 inst
= this._dialogInst
= this._newInst(this._dialogInput
, false);
8613 $.data(this._dialogInput
[0], PROP_NAME
, inst
);
8615 extendRemove(inst
.settings
, settings
|| {});
8616 date
= (date
&& date
.constructor == Date
? this._formatDate(inst
, date
) : date
);
8617 this._dialogInput
.val(date
);
8619 this._pos
= (pos
? (pos
.length
? pos
: [pos
.pageX
, pos
.pageY
]) : null);
8621 var browserWidth
= document
.documentElement
.clientWidth
;
8622 var browserHeight
= document
.documentElement
.clientHeight
;
8623 var scrollX
= document
.documentElement
.scrollLeft
|| document
.body
.scrollLeft
;
8624 var scrollY
= document
.documentElement
.scrollTop
|| document
.body
.scrollTop
;
8625 this._pos
= // should use actual width/height below
8626 [(browserWidth
/ 2) - 100 + scrollX
, (browserHeight
/ 2) - 150 + scrollY
];
8629 // move input on screen for focus, but hidden behind dialog
8630 this._dialogInput
.css('left', (this._pos
[0] + 20) + 'px').css('top', this._pos
[1] + 'px');
8631 inst
.settings
.onSelect
= onSelect
;
8632 this._inDialog
= true;
8633 this.dpDiv
.addClass(this._dialogClass
);
8634 this._showDatepicker(this._dialogInput
[0]);
8636 $.blockUI(this.dpDiv
);
8637 $.data(this._dialogInput
[0], PROP_NAME
, inst
);
8641 /* Detach a datepicker from its control.
8642 @param target element - the target input field or division or span */
8643 _destroyDatepicker: function(target
) {
8644 var $target
= $(target
);
8645 var inst
= $.data(target
, PROP_NAME
);
8646 if (!$target
.hasClass(this.markerClassName
)) {
8649 var nodeName
= target
.nodeName
.toLowerCase();
8650 $.removeData(target
, PROP_NAME
);
8651 if (nodeName
== 'input') {
8652 inst
.append
.remove();
8653 inst
.trigger
.remove();
8654 $target
.removeClass(this.markerClassName
).
8655 unbind('focus', this._showDatepicker
).
8656 unbind('keydown', this._doKeyDown
).
8657 unbind('keypress', this._doKeyPress
).
8658 unbind('keyup', this._doKeyUp
);
8659 } else if (nodeName
== 'div' || nodeName
== 'span')
8660 $target
.removeClass(this.markerClassName
).empty();
8663 /* Enable the date picker to a jQuery selection.
8664 @param target element - the target input field or division or span */
8665 _enableDatepicker: function(target
) {
8666 var $target
= $(target
);
8667 var inst
= $.data(target
, PROP_NAME
);
8668 if (!$target
.hasClass(this.markerClassName
)) {
8671 var nodeName
= target
.nodeName
.toLowerCase();
8672 if (nodeName
== 'input') {
8673 target
.disabled
= false;
8674 inst
.trigger
.filter('button').
8675 each(function() { this.disabled
= false; }).end().
8676 filter('img').css({opacity
: '1.0', cursor
: ''});
8678 else if (nodeName
== 'div' || nodeName
== 'span') {
8679 var inline
= $target
.children('.' + this._inlineClass
);
8680 inline
.children().removeClass('ui-state-disabled');
8681 inline
.find("select.ui-datepicker-month, select.ui-datepicker-year").
8682 removeAttr("disabled");
8684 this._disabledInputs
= $.map(this._disabledInputs
,
8685 function(value
) { return (value
== target
? null : value
); }); // delete entry
8688 /* Disable the date picker to a jQuery selection.
8689 @param target element - the target input field or division or span */
8690 _disableDatepicker: function(target
) {
8691 var $target
= $(target
);
8692 var inst
= $.data(target
, PROP_NAME
);
8693 if (!$target
.hasClass(this.markerClassName
)) {
8696 var nodeName
= target
.nodeName
.toLowerCase();
8697 if (nodeName
== 'input') {
8698 target
.disabled
= true;
8699 inst
.trigger
.filter('button').
8700 each(function() { this.disabled
= true; }).end().
8701 filter('img').css({opacity
: '0.5', cursor
: 'default'});
8703 else if (nodeName
== 'div' || nodeName
== 'span') {
8704 var inline
= $target
.children('.' + this._inlineClass
);
8705 inline
.children().addClass('ui-state-disabled');
8706 inline
.find("select.ui-datepicker-month, select.ui-datepicker-year").
8707 attr("disabled", "disabled");
8709 this._disabledInputs
= $.map(this._disabledInputs
,
8710 function(value
) { return (value
== target
? null : value
); }); // delete entry
8711 this._disabledInputs
[this._disabledInputs
.length
] = target
;
8714 /* Is the first field in a jQuery collection disabled as a datepicker?
8715 @param target element - the target input field or division or span
8716 @return boolean - true if disabled, false if enabled */
8717 _isDisabledDatepicker: function(target
) {
8721 for (var i
= 0; i
< this._disabledInputs
.length
; i
++) {
8722 if (this._disabledInputs
[i
] == target
)
8728 /* Retrieve the instance data for the target control.
8729 @param target element - the target input field or division or span
8730 @return object - the associated instance data
8731 @throws error if a jQuery problem getting data */
8732 _getInst: function(target
) {
8734 return $.data(target
, PROP_NAME
);
8737 throw 'Missing instance data for this datepicker';
8741 /* Update or retrieve the settings for a date picker attached to an input field or division.
8742 @param target element - the target input field or division or span
8743 @param name object - the new settings to update or
8744 string - the name of the setting to change or retrieve,
8745 when retrieving also 'all' for all instance settings or
8746 'defaults' for all global defaults
8747 @param value any - the new value for the setting
8748 (omit if above is an object or to retrieve a value) */
8749 _optionDatepicker: function(target
, name
, value
) {
8750 var inst
= this._getInst(target
);
8751 if (arguments
.length
== 2 && typeof name
== 'string') {
8752 return (name
== 'defaults' ? $.extend({}, $.datepicker
._defaults
) :
8753 (inst
? (name
== 'all' ? $.extend({}, inst
.settings
) :
8754 this._get(inst
, name
)) : null));
8756 var settings
= name
|| {};
8757 if (typeof name
== 'string') {
8759 settings
[name
] = value
;
8762 if (this._curInst
== inst
) {
8763 this._hideDatepicker();
8765 var date
= this._getDateDatepicker(target
, true);
8766 var minDate
= this._getMinMaxDate(inst
, 'min');
8767 var maxDate
= this._getMinMaxDate(inst
, 'max');
8768 extendRemove(inst
.settings
, settings
);
8769 // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8770 if (minDate
!== null && settings
['dateFormat'] !== undefined && settings
['minDate'] === undefined)
8771 inst
.settings
.minDate
= this._formatDate(inst
, minDate
);
8772 if (maxDate
!== null && settings
['dateFormat'] !== undefined && settings
['maxDate'] === undefined)
8773 inst
.settings
.maxDate
= this._formatDate(inst
, maxDate
);
8774 this._attachments($(target
), inst
);
8775 this._autoSize(inst
);
8776 this._setDate(inst
, date
);
8777 this._updateAlternate(inst
);
8778 this._updateDatepicker(inst
);
8782 // change method deprecated
8783 _changeDatepicker: function(target
, name
, value
) {
8784 this._optionDatepicker(target
, name
, value
);
8787 /* Redraw the date picker attached to an input field or division.
8788 @param target element - the target input field or division or span */
8789 _refreshDatepicker: function(target
) {
8790 var inst
= this._getInst(target
);
8792 this._updateDatepicker(inst
);
8796 /* Set the dates for a jQuery selection.
8797 @param target element - the target input field or division or span
8798 @param date Date - the new date */
8799 _setDateDatepicker: function(target
, date
) {
8800 var inst
= this._getInst(target
);
8802 this._setDate(inst
, date
);
8803 this._updateDatepicker(inst
);
8804 this._updateAlternate(inst
);
8808 /* Get the date(s) for the first entry in a jQuery selection.
8809 @param target element - the target input field or division or span
8810 @param noDefault boolean - true if no default date is to be used
8811 @return Date - the current date */
8812 _getDateDatepicker: function(target
, noDefault
) {
8813 var inst
= this._getInst(target
);
8814 if (inst
&& !inst
.inline
)
8815 this._setDateFromField(inst
, noDefault
);
8816 return (inst
? this._getDate(inst
) : null);
8819 /* Handle keystrokes. */
8820 _doKeyDown: function(event
) {
8821 var inst
= $.datepicker
._getInst(event
.target
);
8823 var isRTL
= inst
.dpDiv
.is('.ui-datepicker-rtl');
8824 inst
._keyEvent
= true;
8825 if ($.datepicker
._datepickerShowing
)
8826 switch (event
.keyCode
) {
8827 case 9: $.datepicker
._hideDatepicker();
8829 break; // hide on tab out
8830 case 13: var sel
= $('td.' + $.datepicker
._dayOverClass
+ ':not(.' +
8831 $.datepicker
._currentClass
+ ')', inst
.dpDiv
);
8833 $.datepicker
._selectDay(event
.target
, inst
.selectedMonth
, inst
.selectedYear
, sel
[0]);
8834 var onSelect
= $.datepicker
._get(inst
, 'onSelect');
8836 var dateStr
= $.datepicker
._formatDate(inst
);
8838 // trigger custom callback
8839 onSelect
.apply((inst
.input
? inst
.input
[0] : null), [dateStr
, inst
]);
8842 $.datepicker
._hideDatepicker();
8843 return false; // don't submit the form
8844 break; // select the value on enter
8845 case 27: $.datepicker
._hideDatepicker();
8846 break; // hide on escape
8847 case 33: $.datepicker
._adjustDate(event
.target
, (event
.ctrlKey
?
8848 -$.datepicker
._get(inst
, 'stepBigMonths') :
8849 -$.datepicker
._get(inst
, 'stepMonths')), 'M');
8850 break; // previous month/year on page up/+ ctrl
8851 case 34: $.datepicker
._adjustDate(event
.target
, (event
.ctrlKey
?
8852 +$.datepicker
._get(inst
, 'stepBigMonths') :
8853 +$.datepicker
._get(inst
, 'stepMonths')), 'M');
8854 break; // next month/year on page down/+ ctrl
8855 case 35: if (event
.ctrlKey
|| event
.metaKey
) $.datepicker
._clearDate(event
.target
);
8856 handled
= event
.ctrlKey
|| event
.metaKey
;
8857 break; // clear on ctrl or command +end
8858 case 36: if (event
.ctrlKey
|| event
.metaKey
) $.datepicker
._gotoToday(event
.target
);
8859 handled
= event
.ctrlKey
|| event
.metaKey
;
8860 break; // current on ctrl or command +home
8861 case 37: if (event
.ctrlKey
|| event
.metaKey
) $.datepicker
._adjustDate(event
.target
, (isRTL
? +1 : -1), 'D');
8862 handled
= event
.ctrlKey
|| event
.metaKey
;
8863 // -1 day on ctrl or command +left
8864 if (event
.originalEvent
.altKey
) $.datepicker
._adjustDate(event
.target
, (event
.ctrlKey
?
8865 -$.datepicker
._get(inst
, 'stepBigMonths') :
8866 -$.datepicker
._get(inst
, 'stepMonths')), 'M');
8867 // next month/year on alt +left on Mac
8869 case 38: if (event
.ctrlKey
|| event
.metaKey
) $.datepicker
._adjustDate(event
.target
, -7, 'D');
8870 handled
= event
.ctrlKey
|| event
.metaKey
;
8871 break; // -1 week on ctrl or command +up
8872 case 39: if (event
.ctrlKey
|| event
.metaKey
) $.datepicker
._adjustDate(event
.target
, (isRTL
? -1 : +1), 'D');
8873 handled
= event
.ctrlKey
|| event
.metaKey
;
8874 // +1 day on ctrl or command +right
8875 if (event
.originalEvent
.altKey
) $.datepicker
._adjustDate(event
.target
, (event
.ctrlKey
?
8876 +$.datepicker
._get(inst
, 'stepBigMonths') :
8877 +$.datepicker
._get(inst
, 'stepMonths')), 'M');
8878 // next month/year on alt +right
8880 case 40: if (event
.ctrlKey
|| event
.metaKey
) $.datepicker
._adjustDate(event
.target
, +7, 'D');
8881 handled
= event
.ctrlKey
|| event
.metaKey
;
8882 break; // +1 week on ctrl or command +down
8883 default: handled
= false;
8885 else if (event
.keyCode
== 36 && event
.ctrlKey
) // display the date picker on ctrl+home
8886 $.datepicker
._showDatepicker(this);
8891 event
.preventDefault();
8892 event
.stopPropagation();
8896 /* Filter entered characters - based on date format. */
8897 _doKeyPress: function(event
) {
8898 var inst
= $.datepicker
._getInst(event
.target
);
8899 if ($.datepicker
._get(inst
, 'constrainInput')) {
8900 var chars
= $.datepicker
._possibleChars($.datepicker
._get(inst
, 'dateFormat'));
8901 var chr
= String
.fromCharCode(event
.charCode
== undefined ? event
.keyCode
: event
.charCode
);
8902 return event
.ctrlKey
|| event
.metaKey
|| (chr
< ' ' || !chars
|| chars
.indexOf(chr
) > -1);
8906 /* Synchronise manual entry and field/alternate field. */
8907 _doKeyUp: function(event) {
8908 var inst = $.datepicker._getInst(event.target);
8909 if (inst.input.val() != inst.lastVal) {
8911 var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'),
8912 (inst.input ? inst.input.val() : null),
8913 $.datepicker._getFormatConfig(inst));
8914 if (date) { // only if valid
8915 $.datepicker._setDateFromField(inst);
8916 $.datepicker._updateAlternate(inst);
8917 $.datepicker._updateDatepicker(inst);
8921 $.datepicker.log(err);
8927 /* Pop-up the date picker for a given input field.
8928 If false returned from beforeShow event handler do not show.
8929 @param input element - the input field attached to the date picker or
8930 event - if triggered by focus */
8931 _showDatepicker: function(input
) {
8932 input
= input
.target
|| input
;
8933 if (input
.nodeName
.toLowerCase() != 'input') // find from button/image trigger
8934 input
= $('input', input
.parentNode
)[0];
8935 if ($.datepicker
._isDisabledDatepicker(input
) || $.datepicker
._lastInput
== input
) // already here
8937 var inst
= $.datepicker
._getInst(input
);
8938 if ($.datepicker
._curInst
&& $.datepicker
._curInst
!= inst
) {
8939 $.datepicker
._curInst
.dpDiv
.stop(true, true);
8940 if ( inst
&& $.datepicker
._datepickerShowing
) {
8941 $.datepicker
._hideDatepicker( $.datepicker
._curInst
.input
[0] );
8944 var beforeShow
= $.datepicker
._get(inst
, 'beforeShow');
8945 var beforeShowSettings
= beforeShow
? beforeShow
.apply(input
, [input
, inst
]) : {};
8946 if(beforeShowSettings
=== false){
8950 extendRemove(inst
.settings
, beforeShowSettings
);
8951 inst
.lastVal
= null;
8952 $.datepicker
._lastInput
= input
;
8953 $.datepicker
._setDateFromField(inst
);
8954 if ($.datepicker
._inDialog
) // hide cursor
8956 if (!$.datepicker
._pos
) { // position below input
8957 $.datepicker
._pos
= $.datepicker
._findPos(input
);
8958 $.datepicker
._pos
[1] += input
.offsetHeight
; // add the height
8960 var isFixed
= false;
8961 $(input
).parents().each(function() {
8962 isFixed
|= $(this).css('position') == 'fixed';
8965 if (isFixed
&& $.browser
.opera
) { // correction for Opera when fixed and scrolled
8966 $.datepicker
._pos
[0] -= document
.documentElement
.scrollLeft
;
8967 $.datepicker
._pos
[1] -= document
.documentElement
.scrollTop
;
8969 var offset
= {left
: $.datepicker
._pos
[0], top
: $.datepicker
._pos
[1]};
8970 $.datepicker
._pos
= null;
8971 //to avoid flashes on Firefox
8973 // determine sizing offscreen
8974 inst
.dpDiv
.css({position
: 'absolute', display
: 'block', top
: '-1000px'});
8975 $.datepicker
._updateDatepicker(inst
);
8976 // fix width for dynamic number of date pickers
8977 // and adjust position before showing
8978 offset
= $.datepicker
._checkOffset(inst
, offset
, isFixed
);
8979 inst
.dpDiv
.css({position
: ($.datepicker
._inDialog
&& $.blockUI
?
8980 'static' : (isFixed
? 'fixed' : 'absolute')), display
: 'none',
8981 left
: offset
.left
+ 'px', top
: offset
.top
+ 'px'});
8983 var showAnim
= $.datepicker
._get(inst
, 'showAnim');
8984 var duration
= $.datepicker
._get(inst
, 'duration');
8985 var postProcess = function() {
8986 var cover
= inst
.dpDiv
.find('iframe.ui-datepicker-cover'); // IE6- only
8987 if( !! cover
.length
){
8988 var borders
= $.datepicker
._getBorders(inst
.dpDiv
);
8989 cover
.css({left
: -borders
[0], top
: -borders
[1],
8990 width
: inst
.dpDiv
.outerWidth(), height
: inst
.dpDiv
.outerHeight()});
8993 inst
.dpDiv
.zIndex($(input
).zIndex()+1);
8994 $.datepicker
._datepickerShowing
= true;
8995 if ($.effects
&& $.effects
[showAnim
])
8996 inst
.dpDiv
.show(showAnim
, $.datepicker
._get(inst
, 'showOptions'), duration
, postProcess
);
8998 inst
.dpDiv
[showAnim
|| 'show']((showAnim
? duration
: null), postProcess
);
8999 if (!showAnim
|| !duration
)
9001 if (inst
.input
.is(':visible') && !inst
.input
.is(':disabled'))
9003 $.datepicker
._curInst
= inst
;
9007 /* Generate the date picker content. */
9008 _updateDatepicker: function(inst
) {
9010 self
.maxRows
= 4; //Reset the max number of rows being displayed (see #7043)
9011 var borders
= $.datepicker
._getBorders(inst
.dpDiv
);
9012 instActive
= inst
; // for delegate hover events
9013 inst
.dpDiv
.empty().append(this._generateHTML(inst
));
9014 var cover
= inst
.dpDiv
.find('iframe.ui-datepicker-cover'); // IE6- only
9015 if( !!cover
.length
){ //avoid call to outerXXXX() when not in IE6
9016 cover
.css({left
: -borders
[0], top
: -borders
[1], width
: inst
.dpDiv
.outerWidth(), height
: inst
.dpDiv
.outerHeight()})
9018 inst
.dpDiv
.find('.' + this._dayOverClass
+ ' a').mouseover();
9019 var numMonths
= this._getNumberOfMonths(inst
);
9020 var cols
= numMonths
[1];
9022 inst
.dpDiv
.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width('');
9024 inst
.dpDiv
.addClass('ui-datepicker-multi-' + cols
).css('width', (width
* cols
) + 'em');
9025 inst
.dpDiv
[(numMonths
[0] != 1 || numMonths
[1] != 1 ? 'add' : 'remove') +
9026 'Class']('ui-datepicker-multi');
9027 inst
.dpDiv
[(this._get(inst
, 'isRTL') ? 'add' : 'remove') +
9028 'Class']('ui-datepicker-rtl');
9029 if (inst
== $.datepicker
._curInst
&& $.datepicker
._datepickerShowing
&& inst
.input
&&
9030 // #6694 - don't focus the input if it's already focused
9031 // this breaks the change event in IE
9032 inst
.input
.is(':visible') && !inst
.input
.is(':disabled') && inst
.input
[0] != document
.activeElement
)
9034 // deffered render of the years select (to avoid flashes on Firefox)
9035 if( inst
.yearshtml
){
9036 var origyearshtml
= inst
.yearshtml
;
9037 setTimeout(function(){
9038 //assure that inst.yearshtml didn't change.
9039 if( origyearshtml
=== inst
.yearshtml
&& inst
.yearshtml
){
9040 inst
.dpDiv
.find('select.ui-datepicker-year:first').replaceWith(inst
.yearshtml
);
9042 origyearshtml
= inst
.yearshtml
= null;
9047 /* Retrieve the size of left and top borders for an element.
9048 @param elem (jQuery object) the element of interest
9049 @return (number[2]) the left and top borders */
9050 _getBorders: function(elem
) {
9051 var convert = function(value
) {
9052 return {thin
: 1, medium
: 2, thick
: 3}[value
] || value
;
9054 return [parseFloat(convert(elem
.css('border-left-width'))),
9055 parseFloat(convert(elem
.css('border-top-width')))];
9058 /* Check positioning to remain on screen. */
9059 _checkOffset: function(inst
, offset
, isFixed
) {
9060 var dpWidth
= inst
.dpDiv
.outerWidth();
9061 var dpHeight
= inst
.dpDiv
.outerHeight();
9062 var inputWidth
= inst
.input
? inst
.input
.outerWidth() : 0;
9063 var inputHeight
= inst
.input
? inst
.input
.outerHeight() : 0;
9064 var viewWidth
= document
.documentElement
.clientWidth
+ $(document
).scrollLeft();
9065 var viewHeight
= document
.documentElement
.clientHeight
+ $(document
).scrollTop();
9067 offset
.left
-= (this._get(inst
, 'isRTL') ? (dpWidth
- inputWidth
) : 0);
9068 offset
.left
-= (isFixed
&& offset
.left
== inst
.input
.offset().left
) ? $(document
).scrollLeft() : 0;
9069 offset
.top
-= (isFixed
&& offset
.top
== (inst
.input
.offset().top
+ inputHeight
)) ? $(document
).scrollTop() : 0;
9071 // now check if datepicker is showing outside window viewport - move to a better place if so.
9072 offset
.left
-= Math
.min(offset
.left
, (offset
.left
+ dpWidth
> viewWidth
&& viewWidth
> dpWidth
) ?
9073 Math
.abs(offset
.left
+ dpWidth
- viewWidth
) : 0);
9074 offset
.top
-= Math
.min(offset
.top
, (offset
.top
+ dpHeight
> viewHeight
&& viewHeight
> dpHeight
) ?
9075 Math
.abs(dpHeight
+ inputHeight
) : 0);
9080 /* Find an object's position on the screen. */
9081 _findPos: function(obj
) {
9082 var inst
= this._getInst(obj
);
9083 var isRTL
= this._get(inst
, 'isRTL');
9084 while (obj
&& (obj
.type
== 'hidden' || obj
.nodeType
!= 1 || $.expr
.filters
.hidden(obj
))) {
9085 obj
= obj
[isRTL
? 'previousSibling' : 'nextSibling'];
9087 var position
= $(obj
).offset();
9088 return [position
.left
, position
.top
];
9091 /* Hide the date picker from view.
9092 @param input element - the input field attached to the date picker */
9093 _hideDatepicker: function(input
) {
9094 var inst
= this._curInst
;
9095 if (!inst
|| (input
&& inst
!= $.data(input
, PROP_NAME
)))
9097 if (this._datepickerShowing
) {
9098 var showAnim
= this._get(inst
, 'showAnim');
9099 var duration
= this._get(inst
, 'duration');
9100 var postProcess = function() {
9101 $.datepicker
._tidyDialog(inst
);
9103 if ($.effects
&& $.effects
[showAnim
])
9104 inst
.dpDiv
.hide(showAnim
, $.datepicker
._get(inst
, 'showOptions'), duration
, postProcess
);
9106 inst
.dpDiv
[(showAnim
== 'slideDown' ? 'slideUp' :
9107 (showAnim
== 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim
? duration
: null), postProcess
);
9110 this._datepickerShowing
= false;
9111 var onClose
= this._get(inst
, 'onClose');
9113 onClose
.apply((inst
.input
? inst
.input
[0] : null),
9114 [(inst
.input
? inst
.input
.val() : ''), inst
]);
9115 this._lastInput
= null;
9116 if (this._inDialog
) {
9117 this._dialogInput
.css({ position
: 'absolute', left
: '0', top
: '-100px' });
9120 $('body').append(this.dpDiv
);
9123 this._inDialog
= false;
9127 /* Tidy up after a dialog display. */
9128 _tidyDialog: function(inst
) {
9129 inst
.dpDiv
.removeClass(this._dialogClass
).unbind('.ui-datepicker-calendar');
9132 /* Close date picker if clicked elsewhere. */
9133 _checkExternalClick: function(event
) {
9134 if (!$.datepicker
._curInst
)
9137 var $target
= $(event
.target
),
9138 inst
= $.datepicker
._getInst($target
[0]);
9140 if ( ( ( $target
[0].id
!= $.datepicker
._mainDivId
&&
9141 $target
.parents('#' + $.datepicker
._mainDivId
).length
== 0 &&
9142 !$target
.hasClass($.datepicker
.markerClassName
) &&
9143 !$target
.closest("." + $.datepicker
._triggerClass
).length
&&
9144 $.datepicker
._datepickerShowing
&& !($.datepicker
._inDialog
&& $.blockUI
) ) ) ||
9145 ( $target
.hasClass($.datepicker
.markerClassName
) && $.datepicker
._curInst
!= inst
) )
9146 $.datepicker
._hideDatepicker();
9149 /* Adjust one of the date sub-fields. */
9150 _adjustDate: function(id
, offset
, period
) {
9152 var inst
= this._getInst(target
[0]);
9153 if (this._isDisabledDatepicker(target
[0])) {
9156 this._adjustInstDate(inst
, offset
+
9157 (period
== 'M' ? this._get(inst
, 'showCurrentAtPos') : 0), // undo positioning
9159 this._updateDatepicker(inst
);
9162 /* Action for current link. */
9163 _gotoToday: function(id
) {
9165 var inst
= this._getInst(target
[0]);
9166 if (this._get(inst
, 'gotoCurrent') && inst
.currentDay
) {
9167 inst
.selectedDay
= inst
.currentDay
;
9168 inst
.drawMonth
= inst
.selectedMonth
= inst
.currentMonth
;
9169 inst
.drawYear
= inst
.selectedYear
= inst
.currentYear
;
9172 var date
= new Date();
9173 inst
.selectedDay
= date
.getDate();
9174 inst
.drawMonth
= inst
.selectedMonth
= date
.getMonth();
9175 inst
.drawYear
= inst
.selectedYear
= date
.getFullYear();
9177 this._notifyChange(inst
);
9178 this._adjustDate(target
);
9181 /* Action for selecting a new month/year. */
9182 _selectMonthYear: function(id, select, period) {
9184 var inst = this._getInst(target[0]);
9185 inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
9186 inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
9187 parseInt(select.options[select.selectedIndex].value,10);
9188 this._notifyChange(inst);
9189 this._adjustDate(target);
9192 /* Action for selecting a day. */
9193 _selectDay: function(id
, month
, year
, td
) {
9195 if ($(td
).hasClass(this._unselectableClass
) || this._isDisabledDatepicker(target
[0])) {
9198 var inst
= this._getInst(target
[0]);
9199 inst
.selectedDay
= inst
.currentDay
= $('a', td
).html();
9200 inst
.selectedMonth
= inst
.currentMonth
= month
;
9201 inst
.selectedYear
= inst
.currentYear
= year
;
9202 this._selectDate(id
, this._formatDate(inst
,
9203 inst
.currentDay
, inst
.currentMonth
, inst
.currentYear
));
9206 /* Erase the input field and hide the date picker. */
9207 _clearDate: function(id
) {
9209 var inst
= this._getInst(target
[0]);
9210 this._selectDate(target
, '');
9213 /* Update the input field with the selected date. */
9214 _selectDate: function(id
, dateStr
) {
9216 var inst
= this._getInst(target
[0]);
9217 dateStr
= (dateStr
!= null ? dateStr
: this._formatDate(inst
));
9219 inst
.input
.val(dateStr
);
9220 this._updateAlternate(inst
);
9221 var onSelect
= this._get(inst
, 'onSelect');
9223 onSelect
.apply((inst
.input
? inst
.input
[0] : null), [dateStr
, inst
]); // trigger custom callback
9224 else if (inst
.input
)
9225 inst
.input
.trigger('change'); // fire the change event
9227 this._updateDatepicker(inst
);
9229 this._hideDatepicker();
9230 this._lastInput
= inst
.input
[0];
9231 if (typeof(inst
.input
[0]) != 'object')
9232 inst
.input
.focus(); // restore focus
9233 this._lastInput
= null;
9237 /* Update any alternate field to synchronise with the main field. */
9238 _updateAlternate: function(inst
) {
9239 var altField
= this._get(inst
, 'altField');
9240 if (altField
) { // update alternate field too
9241 var altFormat
= this._get(inst
, 'altFormat') || this._get(inst
, 'dateFormat');
9242 var date
= this._getDate(inst
);
9243 var dateStr
= this.formatDate(altFormat
, date
, this._getFormatConfig(inst
));
9244 $(altField
).each(function() { $(this).val(dateStr
); });
9248 /* Set as beforeShowDay function to prevent selection of weekends.
9249 @param date Date - the date to customise
9250 @return [boolean, string] - is this date selectable?, what is its CSS class? */
9251 noWeekends: function(date
) {
9252 var day
= date
.getDay();
9253 return [(day
> 0 && day
< 6), ''];
9256 /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
9257 @param date Date - the date to get the week for
9258 @return number - the number of the week within the year that contains this date */
9259 iso8601Week: function(date
) {
9260 var checkDate
= new Date(date
.getTime());
9261 // Find Thursday of this week starting on Monday
9262 checkDate
.setDate(checkDate
.getDate() + 4 - (checkDate
.getDay() || 7));
9263 var time
= checkDate
.getTime();
9264 checkDate
.setMonth(0); // Compare with Jan 1
9265 checkDate
.setDate(1);
9266 return Math
.floor(Math
.round((time
- checkDate
) / 86400000) / 7) + 1;
9269 /* Parse a string value into a date object.
9270 See formatDate below for the possible formats.
9272 @param format string - the expected format of the date
9273 @param value string - the date in the above format
9274 @param settings Object - attributes include:
9275 shortYearCutoff number - the cutoff year for determining the century (optional)
9276 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
9277 dayNames string[7] - names of the days from Sunday (optional)
9278 monthNamesShort string[12] - abbreviated names of the months (optional)
9279 monthNames string[12] - names of the months (optional)
9280 @return Date - the extracted date value or null if value is blank */
9281 parseDate: function (format
, value
, settings
) {
9282 if (format
== null || value
== null)
9283 throw 'Invalid arguments';
9284 value
= (typeof value
== 'object' ? value
.toString() : value
+ '');
9287 var shortYearCutoff
= (settings
? settings
.shortYearCutoff
: null) || this._defaults
.shortYearCutoff
;
9288 shortYearCutoff
= (typeof shortYearCutoff
!= 'string' ? shortYearCutoff
:
9289 new Date().getFullYear() % 100 + parseInt(shortYearCutoff
, 10));
9290 var dayNamesShort
= (settings
? settings
.dayNamesShort
: null) || this._defaults
.dayNamesShort
;
9291 var dayNames
= (settings
? settings
.dayNames
: null) || this._defaults
.dayNames
;
9292 var monthNamesShort
= (settings
? settings
.monthNamesShort
: null) || this._defaults
.monthNamesShort
;
9293 var monthNames
= (settings
? settings
.monthNames
: null) || this._defaults
.monthNames
;
9298 var literal
= false;
9299 // Check whether a format character is doubled
9300 var lookAhead = function(match
) {
9301 var matches
= (iFormat
+ 1 < format
.length
&& format
.charAt(iFormat
+ 1) == match
);
9306 // Extract a number from the string value
9307 var getNumber = function(match
) {
9308 var isDoubled
= lookAhead(match
);
9309 var size
= (match
== '@' ? 14 : (match
== '!' ? 20 :
9310 (match
== 'y' && isDoubled
? 4 : (match
== 'o' ? 3 : 2))));
9311 var digits
= new RegExp('^\\d{1,' + size
+ '}');
9312 var num
= value
.substring(iValue
).match(digits
);
9314 throw 'Missing number at position ' + iValue
;
9315 iValue
+= num
[0].length
;
9316 return parseInt(num
[0], 10);
9318 // Extract a name from the string value and convert to an index
9319 var getName = function(match
, shortNames
, longNames
) {
9320 var names
= $.map(lookAhead(match
) ? longNames
: shortNames
, function (v
, k
) {
9322 }).sort(function (a
, b
) {
9323 return -(a
[1].length
- b
[1].length
);
9326 $.each(names
, function (i
, pair
) {
9328 if (value
.substr(iValue
, name
.length
).toLowerCase() == name
.toLowerCase()) {
9330 iValue
+= name
.length
;
9337 throw 'Unknown name at position ' + iValue
;
9339 // Confirm that a literal character matches the string value
9340 var checkLiteral = function() {
9341 if (value
.charAt(iValue
) != format
.charAt(iFormat
))
9342 throw 'Unexpected literal at position ' + iValue
;
9346 for (var iFormat
= 0; iFormat
< format
.length
; iFormat
++) {
9348 if (format
.charAt(iFormat
) == "'" && !lookAhead("'"))
9353 switch (format
.charAt(iFormat
)) {
9355 day
= getNumber('d');
9358 getName('D', dayNamesShort
, dayNames
);
9361 doy
= getNumber('o');
9364 month
= getNumber('m');
9367 month
= getName('M', monthNamesShort
, monthNames
);
9370 year
= getNumber('y');
9373 var date
= new Date(getNumber('@'));
9374 year
= date
.getFullYear();
9375 month
= date
.getMonth() + 1;
9376 day
= date
.getDate();
9379 var date
= new Date((getNumber('!') - this._ticksTo1970
) / 10000);
9380 year
= date
.getFullYear();
9381 month
= date
.getMonth() + 1;
9382 day
= date
.getDate();
9394 if (iValue
< value
.length
){
9395 throw "Extra/unparsed characters found in date: " + value
.substring(iValue
);
9398 year
= new Date().getFullYear();
9399 else if (year
< 100)
9400 year
+= new Date().getFullYear() - new Date().getFullYear() % 100 +
9401 (year
<= shortYearCutoff
? 0 : -100);
9406 var dim
= this._getDaysInMonth(year
, month
- 1);
9413 var date
= this._daylightSavingAdjust(new Date(year
, month
- 1, day
));
9414 if (date
.getFullYear() != year
|| date
.getMonth() + 1 != month
|| date
.getDate() != day
)
9415 throw 'Invalid date'; // E.g. 31/02/00
9419 /* Standard date formats. */
9420 ATOM
: 'yy-mm-dd', // RFC 3339 (ISO 8601)
9421 COOKIE
: 'D, dd M yy',
9422 ISO_8601
: 'yy-mm-dd',
9423 RFC_822
: 'D, d M y',
9424 RFC_850
: 'DD, dd-M-y',
9425 RFC_1036
: 'D, d M y',
9426 RFC_1123
: 'D, d M yy',
9427 RFC_2822
: 'D, d M yy',
9428 RSS
: 'D, d M y', // RFC 822
9431 W3C
: 'yy-mm-dd', // ISO 8601
9433 _ticksTo1970
: (((1970 - 1) * 365 + Math
.floor(1970 / 4) - Math
.floor(1970 / 100) +
9434 Math
.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
9436 /* Format a date object into a string value.
9437 The format can be combinations of the following:
9438 d - day of month (no leading zero)
9439 dd - day of month (two digit)
9440 o - day of year (no leading zeros)
9441 oo - day of year (three digit)
9444 m - month of year (no leading zero)
9445 mm - month of year (two digit)
9446 M - month name short
9447 MM - month name long
9448 y - year (two digit)
9449 yy - year (four digit)
9450 @ - Unix timestamp (ms since 01/01/1970)
9451 ! - Windows ticks (100ns since 01/01/0001)
9452 '...' - literal text
9455 @param format string - the desired format of the date
9456 @param date Date - the date value to format
9457 @param settings Object - attributes include:
9458 dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
9459 dayNames string[7] - names of the days from Sunday (optional)
9460 monthNamesShort string[12] - abbreviated names of the months (optional)
9461 monthNames string[12] - names of the months (optional)
9462 @return string - the date in the above format */
9463 formatDate: function (format
, date
, settings
) {
9466 var dayNamesShort
= (settings
? settings
.dayNamesShort
: null) || this._defaults
.dayNamesShort
;
9467 var dayNames
= (settings
? settings
.dayNames
: null) || this._defaults
.dayNames
;
9468 var monthNamesShort
= (settings
? settings
.monthNamesShort
: null) || this._defaults
.monthNamesShort
;
9469 var monthNames
= (settings
? settings
.monthNames
: null) || this._defaults
.monthNames
;
9470 // Check whether a format character is doubled
9471 var lookAhead = function(match
) {
9472 var matches
= (iFormat
+ 1 < format
.length
&& format
.charAt(iFormat
+ 1) == match
);
9477 // Format a number, with leading zero if necessary
9478 var formatNumber = function(match
, value
, len
) {
9479 var num
= '' + value
;
9480 if (lookAhead(match
))
9481 while (num
.length
< len
)
9485 // Format a name, short or long as requested
9486 var formatName = function(match
, value
, shortNames
, longNames
) {
9487 return (lookAhead(match
) ? longNames
[value
] : shortNames
[value
]);
9490 var literal
= false;
9492 for (var iFormat
= 0; iFormat
< format
.length
; iFormat
++) {
9494 if (format
.charAt(iFormat
) == "'" && !lookAhead("'"))
9497 output
+= format
.charAt(iFormat
);
9499 switch (format
.charAt(iFormat
)) {
9501 output
+= formatNumber('d', date
.getDate(), 2);
9504 output
+= formatName('D', date
.getDay(), dayNamesShort
, dayNames
);
9507 output
+= formatNumber('o',
9508 Math
.round((new Date(date
.getFullYear(), date
.getMonth(), date
.getDate()).getTime() - new Date(date
.getFullYear(), 0, 0).getTime()) / 86400000), 3);
9511 output
+= formatNumber('m', date
.getMonth() + 1, 2);
9514 output
+= formatName('M', date
.getMonth(), monthNamesShort
, monthNames
);
9517 output
+= (lookAhead('y') ? date
.getFullYear() :
9518 (date
.getYear() % 100 < 10 ? '0' : '') + date
.getYear() % 100);
9521 output
+= date
.getTime();
9524 output
+= date
.getTime() * 10000 + this._ticksTo1970
;
9533 output
+= format
.charAt(iFormat
);
9539 /* Extract all possible characters from the date format. */
9540 _possibleChars: function (format
) {
9542 var literal
= false;
9543 // Check whether a format character is doubled
9544 var lookAhead = function(match
) {
9545 var matches
= (iFormat
+ 1 < format
.length
&& format
.charAt(iFormat
+ 1) == match
);
9550 for (var iFormat
= 0; iFormat
< format
.length
; iFormat
++)
9552 if (format
.charAt(iFormat
) == "'" && !lookAhead("'"))
9555 chars
+= format
.charAt(iFormat
);
9557 switch (format
.charAt(iFormat
)) {
9558 case 'd': case 'm': case 'y': case '@':
9559 chars
+= '0123456789';
9562 return null; // Accept anything
9570 chars
+= format
.charAt(iFormat
);
9575 /* Get a setting value, defaulting if necessary. */
9576 _get: function(inst
, name
) {
9577 return inst
.settings
[name
] !== undefined ?
9578 inst
.settings
[name
] : this._defaults
[name
];
9581 /* Parse existing date and initialise date picker. */
9582 _setDateFromField: function(inst
, noDefault
) {
9583 if (inst
.input
.val() == inst
.lastVal
) {
9586 var dateFormat
= this._get(inst
, 'dateFormat');
9587 var dates
= inst
.lastVal
= inst
.input
? inst
.input
.val() : null;
9588 var date
, defaultDate
;
9589 date
= defaultDate
= this._getDefaultDate(inst
);
9590 var settings
= this._getFormatConfig(inst
);
9592 date
= this.parseDate(dateFormat
, dates
, settings
) || defaultDate
;
9595 dates
= (noDefault
? '' : dates
);
9597 inst
.selectedDay
= date
.getDate();
9598 inst
.drawMonth
= inst
.selectedMonth
= date
.getMonth();
9599 inst
.drawYear
= inst
.selectedYear
= date
.getFullYear();
9600 inst
.currentDay
= (dates
? date
.getDate() : 0);
9601 inst
.currentMonth
= (dates
? date
.getMonth() : 0);
9602 inst
.currentYear
= (dates
? date
.getFullYear() : 0);
9603 this._adjustInstDate(inst
);
9606 /* Retrieve the default date shown on opening. */
9607 _getDefaultDate: function(inst
) {
9608 return this._restrictMinMax(inst
,
9609 this._determineDate(inst
, this._get(inst
, 'defaultDate'), new Date()));
9612 /* A date may be specified as an exact value or a relative one. */
9613 _determineDate: function(inst
, date
, defaultDate
) {
9614 var offsetNumeric = function(offset
) {
9615 var date
= new Date();
9616 date
.setDate(date
.getDate() + offset
);
9619 var offsetString = function(offset
) {
9621 return $.datepicker
.parseDate($.datepicker
._get(inst
, 'dateFormat'),
9622 offset
, $.datepicker
._getFormatConfig(inst
));
9627 var date
= (offset
.toLowerCase().match(/^c/) ?
9628 $.datepicker
._getDate(inst
) : null) || new Date();
9629 var year
= date
.getFullYear();
9630 var month
= date
.getMonth();
9631 var day
= date
.getDate();
9632 var pattern
= /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;
9633 var matches
= pattern
.exec(offset
);
9635 switch (matches
[2] || 'd') {
9636 case 'd' : case 'D' :
9637 day
+= parseInt(matches
[1],10); break;
9638 case 'w' : case 'W' :
9639 day
+= parseInt(matches
[1],10) * 7; break;
9640 case 'm' : case 'M' :
9641 month
+= parseInt(matches
[1],10);
9642 day
= Math
.min(day
, $.datepicker
._getDaysInMonth(year
, month
));
9644 case 'y': case 'Y' :
9645 year
+= parseInt(matches
[1],10);
9646 day
= Math
.min(day
, $.datepicker
._getDaysInMonth(year
, month
));
9649 matches
= pattern
.exec(offset
);
9651 return new Date(year
, month
, day
);
9653 var newDate
= (date
== null || date
=== '' ? defaultDate
: (typeof date
== 'string' ? offsetString(date
) :
9654 (typeof date
== 'number' ? (isNaN(date
) ? defaultDate
: offsetNumeric(date
)) : new Date(date
.getTime()))));
9655 newDate
= (newDate
&& newDate
.toString() == 'Invalid Date' ? defaultDate
: newDate
);
9657 newDate
.setHours(0);
9658 newDate
.setMinutes(0);
9659 newDate
.setSeconds(0);
9660 newDate
.setMilliseconds(0);
9662 return this._daylightSavingAdjust(newDate
);
9665 /* Handle switch to/from daylight saving.
9666 Hours may be non-zero on daylight saving cut-over:
9667 > 12 when midnight changeover, but then cannot generate
9668 midnight datetime, so jump to 1AM, otherwise reset.
9669 @param date (Date) the date to check
9670 @return (Date) the corrected date */
9671 _daylightSavingAdjust: function(date
) {
9672 if (!date
) return null;
9673 date
.setHours(date
.getHours() > 12 ? date
.getHours() + 2 : 0);
9677 /* Set the date(s) directly. */
9678 _setDate: function(inst
, date
, noChange
) {
9680 var origMonth
= inst
.selectedMonth
;
9681 var origYear
= inst
.selectedYear
;
9682 var newDate
= this._restrictMinMax(inst
, this._determineDate(inst
, date
, new Date()));
9683 inst
.selectedDay
= inst
.currentDay
= newDate
.getDate();
9684 inst
.drawMonth
= inst
.selectedMonth
= inst
.currentMonth
= newDate
.getMonth();
9685 inst
.drawYear
= inst
.selectedYear
= inst
.currentYear
= newDate
.getFullYear();
9686 if ((origMonth
!= inst
.selectedMonth
|| origYear
!= inst
.selectedYear
) && !noChange
)
9687 this._notifyChange(inst
);
9688 this._adjustInstDate(inst
);
9690 inst
.input
.val(clear
? '' : this._formatDate(inst
));
9694 /* Retrieve the date(s) directly. */
9695 _getDate: function(inst
) {
9696 var startDate
= (!inst
.currentYear
|| (inst
.input
&& inst
.input
.val() == '') ? null :
9697 this._daylightSavingAdjust(new Date(
9698 inst
.currentYear
, inst
.currentMonth
, inst
.currentDay
)));
9702 /* Generate the HTML for the current state of the date picker. */
9703 _generateHTML: function(inst
) {
9704 var today
= new Date();
9705 today
= this._daylightSavingAdjust(
9706 new Date(today
.getFullYear(), today
.getMonth(), today
.getDate())); // clear time
9707 var isRTL
= this._get(inst
, 'isRTL');
9708 var showButtonPanel
= this._get(inst
, 'showButtonPanel');
9709 var hideIfNoPrevNext
= this._get(inst
, 'hideIfNoPrevNext');
9710 var navigationAsDateFormat
= this._get(inst
, 'navigationAsDateFormat');
9711 var numMonths
= this._getNumberOfMonths(inst
);
9712 var showCurrentAtPos
= this._get(inst
, 'showCurrentAtPos');
9713 var stepMonths
= this._get(inst
, 'stepMonths');
9714 var isMultiMonth
= (numMonths
[0] != 1 || numMonths
[1] != 1);
9715 var currentDate
= this._daylightSavingAdjust((!inst
.currentDay
? new Date(9999, 9, 9) :
9716 new Date(inst
.currentYear
, inst
.currentMonth
, inst
.currentDay
)));
9717 var minDate
= this._getMinMaxDate(inst
, 'min');
9718 var maxDate
= this._getMinMaxDate(inst
, 'max');
9719 var drawMonth
= inst
.drawMonth
- showCurrentAtPos
;
9720 var drawYear
= inst
.drawYear
;
9721 if (drawMonth
< 0) {
9726 var maxDraw
= this._daylightSavingAdjust(new Date(maxDate
.getFullYear(),
9727 maxDate
.getMonth() - (numMonths
[0] * numMonths
[1]) + 1, maxDate
.getDate()));
9728 maxDraw
= (minDate
&& maxDraw
< minDate
? minDate
: maxDraw
);
9729 while (this._daylightSavingAdjust(new Date(drawYear
, drawMonth
, 1)) > maxDraw
) {
9731 if (drawMonth
< 0) {
9737 inst
.drawMonth
= drawMonth
;
9738 inst
.drawYear
= drawYear
;
9739 var prevText
= this._get(inst
, 'prevText');
9740 prevText
= (!navigationAsDateFormat
? prevText
: this.formatDate(prevText
,
9741 this._daylightSavingAdjust(new Date(drawYear
, drawMonth
- stepMonths
, 1)),
9742 this._getFormatConfig(inst
)));
9743 var prev
= (this._canAdjustMonth(inst
, -1, drawYear
, drawMonth
) ?
9744 '<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_' + dpuuid
+
9745 '.datepicker._adjustDate(\'#' + inst
.id
+ '\', -' + stepMonths
+ ', \'M\');"' +
9746 ' title="' + prevText
+ '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL
? 'e' : 'w') + '">' + prevText
+ '</span></a>' :
9747 (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>'));
9748 var nextText
= this._get(inst
, 'nextText');
9749 nextText
= (!navigationAsDateFormat
? nextText
: this.formatDate(nextText
,
9750 this._daylightSavingAdjust(new Date(drawYear
, drawMonth
+ stepMonths
, 1)),
9751 this._getFormatConfig(inst
)));
9752 var next
= (this._canAdjustMonth(inst
, +1, drawYear
, drawMonth
) ?
9753 '<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_' + dpuuid
+
9754 '.datepicker._adjustDate(\'#' + inst
.id
+ '\', +' + stepMonths
+ ', \'M\');"' +
9755 ' title="' + nextText
+ '"><span class="ui-icon ui-icon-circle-triangle-' + ( isRTL
? 'w' : 'e') + '">' + nextText
+ '</span></a>' :
9756 (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>'));
9757 var currentText
= this._get(inst
, 'currentText');
9758 var gotoDate
= (this._get(inst
, 'gotoCurrent') && inst
.currentDay
? currentDate
: today
);
9759 currentText
= (!navigationAsDateFormat
? currentText
:
9760 this.formatDate(currentText
, gotoDate
, this._getFormatConfig(inst
)));
9761 var controls
= (!inst
.inline
? '<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_' + dpuuid
+
9762 '.datepicker._hideDatepicker();">' + this._get(inst
, 'closeText') + '</button>' : '');
9763 var buttonPanel
= (showButtonPanel
) ? '<div class="ui-datepicker-buttonpane ui-widget-content">' + (isRTL
? controls
: '') +
9764 (this._isInRange(inst
, gotoDate
) ? '<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_' + dpuuid
+
9765 '.datepicker._gotoToday(\'#' + inst
.id
+ '\');"' +
9766 '>' + currentText
+ '</button>' : '') + (isRTL
? '' : controls
) + '</div>' : '';
9767 var firstDay
= parseInt(this._get(inst
, 'firstDay'),10);
9768 firstDay
= (isNaN(firstDay
) ? 0 : firstDay
);
9769 var showWeek
= this._get(inst
, 'showWeek');
9770 var dayNames
= this._get(inst
, 'dayNames');
9771 var dayNamesShort
= this._get(inst
, 'dayNamesShort');
9772 var dayNamesMin
= this._get(inst
, 'dayNamesMin');
9773 var monthNames
= this._get(inst
, 'monthNames');
9774 var monthNamesShort
= this._get(inst
, 'monthNamesShort');
9775 var beforeShowDay
= this._get(inst
, 'beforeShowDay');
9776 var showOtherMonths
= this._get(inst
, 'showOtherMonths');
9777 var selectOtherMonths
= this._get(inst
, 'selectOtherMonths');
9778 var calculateWeek
= this._get(inst
, 'calculateWeek') || this.iso8601Week
;
9779 var defaultDate
= this._getDefaultDate(inst
);
9781 for (var row
= 0; row
< numMonths
[0]; row
++) {
9784 for (var col
= 0; col
< numMonths
[1]; col
++) {
9785 var selectedDate
= this._daylightSavingAdjust(new Date(drawYear
, drawMonth
, inst
.selectedDay
));
9786 var cornerClass
= ' ui-corner-all';
9789 calender
+= '<div class="ui-datepicker-group';
9790 if (numMonths
[1] > 1)
9792 case 0: calender
+= ' ui-datepicker-group-first';
9793 cornerClass
= ' ui-corner-' + (isRTL
? 'right' : 'left'); break;
9794 case numMonths
[1]-1: calender
+= ' ui-datepicker-group-last';
9795 cornerClass
= ' ui-corner-' + (isRTL
? 'left' : 'right'); break;
9796 default: calender
+= ' ui-datepicker-group-middle'; cornerClass
= ''; break;
9800 calender
+= '<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix' + cornerClass
+ '">' +
9801 (/all|left/.test(cornerClass
) && row
== 0 ? (isRTL
? next
: prev
) : '') +
9802 (/all|right/.test(cornerClass
) && row
== 0 ? (isRTL
? prev
: next
) : '') +
9803 this._generateMonthYearHeader(inst
, drawMonth
, drawYear
, minDate
, maxDate
,
9804 row
> 0 || col
> 0, monthNames
, monthNamesShort
) + // draw month headers
9805 '</div><table class="ui-datepicker-calendar"><thead>' +
9807 var thead
= (showWeek
? '<th class="ui-datepicker-week-col">' + this._get(inst
, 'weekHeader') + '</th>' : '');
9808 for (var dow
= 0; dow
< 7; dow
++) { // days of the week
9809 var day
= (dow
+ firstDay
) % 7;
9810 thead
+= '<th' + ((dow
+ firstDay
+ 6) % 7 >= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' +
9811 '<span title="' + dayNames
[day
] + '">' + dayNamesMin
[day
] + '</span></th>';
9813 calender
+= thead
+ '</tr></thead><tbody>';
9814 var daysInMonth
= this._getDaysInMonth(drawYear
, drawMonth
);
9815 if (drawYear
== inst
.selectedYear
&& drawMonth
== inst
.selectedMonth
)
9816 inst
.selectedDay
= Math
.min(inst
.selectedDay
, daysInMonth
);
9817 var leadDays
= (this._getFirstDayOfMonth(drawYear
, drawMonth
) - firstDay
+ 7) % 7;
9818 var curRows
= Math
.ceil((leadDays
+ daysInMonth
) / 7); // calculate the number of rows to generate
9819 var numRows
= (isMultiMonth
? this.maxRows
> curRows
? this.maxRows
: curRows
: curRows
); //If multiple months, use the higher number of rows (see #7043)
9820 this.maxRows
= numRows
;
9821 var printDate
= this._daylightSavingAdjust(new Date(drawYear
, drawMonth
, 1 - leadDays
));
9822 for (var dRow
= 0; dRow
< numRows
; dRow
++) { // create date picker rows
9824 var tbody
= (!showWeek
? '' : '<td class="ui-datepicker-week-col">' +
9825 this._get(inst
, 'calculateWeek')(printDate
) + '</td>');
9826 for (var dow
= 0; dow
< 7; dow
++) { // create date picker days
9827 var daySettings
= (beforeShowDay
?
9828 beforeShowDay
.apply((inst
.input
? inst
.input
[0] : null), [printDate
]) : [true, '']);
9829 var otherMonth
= (printDate
.getMonth() != drawMonth
);
9830 var unselectable
= (otherMonth
&& !selectOtherMonths
) || !daySettings
[0] ||
9831 (minDate
&& printDate
< minDate
) || (maxDate
&& printDate
> maxDate
);
9832 tbody
+= '<td class="' +
9833 ((dow
+ firstDay
+ 6) % 7 >= 5 ? ' ui-datepicker-week-end' : '') + // highlight weekends
9834 (otherMonth
? ' ui-datepicker-other-month' : '') + // highlight days from other months
9835 ((printDate
.getTime() == selectedDate
.getTime() && drawMonth
== inst
.selectedMonth
&& inst
._keyEvent
) || // user pressed key
9836 (defaultDate
.getTime() == printDate
.getTime() && defaultDate
.getTime() == selectedDate
.getTime()) ?
9837 // or defaultDate is current printedDate and defaultDate is selectedDate
9838 ' ' + this._dayOverClass
: '') + // highlight selected day
9839 (unselectable
? ' ' + this._unselectableClass
+ ' ui-state-disabled': '') + // highlight unselectable days
9840 (otherMonth
&& !showOtherMonths
? '' : ' ' + daySettings
[1] + // highlight custom dates
9841 (printDate
.getTime() == currentDate
.getTime() ? ' ' + this._currentClass
: '') + // highlight selected day
9842 (printDate
.getTime() == today
.getTime() ? ' ui-datepicker-today' : '')) + '"' + // highlight today (if different)
9843 ((!otherMonth
|| showOtherMonths
) && daySettings
[2] ? ' title="' + daySettings
[2] + '"' : '') + // cell title
9844 (unselectable
? '' : ' onclick="DP_jQuery_' + dpuuid
+ '.datepicker._selectDay(\'#' +
9845 inst
.id
+ '\',' + printDate
.getMonth() + ',' + printDate
.getFullYear() + ', this);return false;"') + '>' + // actions
9846 (otherMonth
&& !showOtherMonths
? ' ' : // display for other months
9847 (unselectable
? '<span class="ui-state-default">' + printDate
.getDate() + '</span>' : '<a class="ui-state-default' +
9848 (printDate
.getTime() == today
.getTime() ? ' ui-state-highlight' : '') +
9849 (printDate
.getTime() == currentDate
.getTime() ? ' ui-state-active' : '') + // highlight selected day
9850 (otherMonth
? ' ui-priority-secondary' : '') + // distinguish dates from other months
9851 '" href="#">' + printDate
.getDate() + '</a>')) + '</td>'; // display selectable date
9852 printDate
.setDate(printDate
.getDate() + 1);
9853 printDate
= this._daylightSavingAdjust(printDate
);
9855 calender
+= tbody
+ '</tr>';
9858 if (drawMonth
> 11) {
9862 calender
+= '</tbody></table>' + (isMultiMonth
? '</div>' +
9863 ((numMonths
[0] > 0 && col
== numMonths
[1]-1) ? '<div class="ui-datepicker-row-break"></div>' : '') : '');
9868 html
+= buttonPanel
+ ($.browser
.msie
&& parseInt($.browser
.version
,10) < 7 && !inst
.inline
?
9869 '<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>' : '');
9870 inst
._keyEvent
= false;
9874 /* Generate the month and year header. */
9875 _generateMonthYearHeader: function(inst
, drawMonth
, drawYear
, minDate
, maxDate
,
9876 secondary
, monthNames
, monthNamesShort
) {
9877 var changeMonth
= this._get(inst
, 'changeMonth');
9878 var changeYear
= this._get(inst
, 'changeYear');
9879 var showMonthAfterYear
= this._get(inst
, 'showMonthAfterYear');
9880 var html
= '<div class="ui-datepicker-title">';
9883 if (secondary
|| !changeMonth
)
9884 monthHtml
+= '<span class="ui-datepicker-month">' + monthNames
[drawMonth
] + '</span>';
9886 var inMinYear
= (minDate
&& minDate
.getFullYear() == drawYear
);
9887 var inMaxYear
= (maxDate
&& maxDate
.getFullYear() == drawYear
);
9888 monthHtml
+= '<select class="ui-datepicker-month" ' +
9889 'onchange="DP_jQuery_' + dpuuid
+ '.datepicker._selectMonthYear(\'#' + inst
.id
+ '\', this, \'M\');" ' +
9891 for (var month
= 0; month
< 12; month
++) {
9892 if ((!inMinYear
|| month
>= minDate
.getMonth()) &&
9893 (!inMaxYear
|| month
<= maxDate
.getMonth()))
9894 monthHtml
+= '<option value="' + month
+ '"' +
9895 (month
== drawMonth
? ' selected="selected"' : '') +
9896 '>' + monthNamesShort
[month
] + '</option>';
9898 monthHtml
+= '</select>';
9900 if (!showMonthAfterYear
)
9901 html
+= monthHtml
+ (secondary
|| !(changeMonth
&& changeYear
) ? ' ' : '');
9903 if ( !inst
.yearshtml
) {
9904 inst
.yearshtml
= '';
9905 if (secondary
|| !changeYear
)
9906 html
+= '<span class="ui-datepicker-year">' + drawYear
+ '</span>';
9908 // determine range of years to display
9909 var years
= this._get(inst
, 'yearRange').split(':');
9910 var thisYear
= new Date().getFullYear();
9911 var determineYear = function(value
) {
9912 var year
= (value
.match(/c[+-].*/) ? drawYear
+ parseInt(value
.substring(1), 10) :
9913 (value
.match(/[+-].*/) ? thisYear
+ parseInt(value
, 10) :
9914 parseInt(value
, 10)));
9915 return (isNaN(year
) ? thisYear
: year
);
9917 var year
= determineYear(years
[0]);
9918 var endYear
= Math
.max(year
, determineYear(years
[1] || ''));
9919 year
= (minDate
? Math
.max(year
, minDate
.getFullYear()) : year
);
9920 endYear
= (maxDate
? Math
.min(endYear
, maxDate
.getFullYear()) : endYear
);
9921 inst
.yearshtml
+= '<select class="ui-datepicker-year" ' +
9922 'onchange="DP_jQuery_' + dpuuid
+ '.datepicker._selectMonthYear(\'#' + inst
.id
+ '\', this, \'Y\');" ' +
9924 for (; year
<= endYear
; year
++) {
9925 inst
.yearshtml
+= '<option value="' + year
+ '"' +
9926 (year
== drawYear
? ' selected="selected"' : '') +
9927 '>' + year
+ '</option>';
9929 inst
.yearshtml
+= '</select>';
9931 html
+= inst
.yearshtml
;
9932 inst
.yearshtml
= null;
9935 html
+= this._get(inst
, 'yearSuffix');
9936 if (showMonthAfterYear
)
9937 html
+= (secondary
|| !(changeMonth
&& changeYear
) ? ' ' : '') + monthHtml
;
9938 html
+= '</div>'; // Close datepicker_header
9942 /* Adjust one of the date sub-fields. */
9943 _adjustInstDate: function(inst
, offset
, period
) {
9944 var year
= inst
.drawYear
+ (period
== 'Y' ? offset
: 0);
9945 var month
= inst
.drawMonth
+ (period
== 'M' ? offset
: 0);
9946 var day
= Math
.min(inst
.selectedDay
, this._getDaysInMonth(year
, month
)) +
9947 (period
== 'D' ? offset
: 0);
9948 var date
= this._restrictMinMax(inst
,
9949 this._daylightSavingAdjust(new Date(year
, month
, day
)));
9950 inst
.selectedDay
= date
.getDate();
9951 inst
.drawMonth
= inst
.selectedMonth
= date
.getMonth();
9952 inst
.drawYear
= inst
.selectedYear
= date
.getFullYear();
9953 if (period
== 'M' || period
== 'Y')
9954 this._notifyChange(inst
);
9957 /* Ensure a date is within any min/max bounds. */
9958 _restrictMinMax: function(inst, date) {
9959 var minDate = this._getMinMaxDate(inst, 'min');
9960 var maxDate = this._getMinMaxDate(inst, 'max');
9961 var newDate = (minDate && date < minDate ? minDate : date);
9962 newDate = (maxDate && newDate > maxDate ? maxDate : newDate);
9966 /* Notify change of month/year. */
9967 _notifyChange: function(inst) {
9968 var onChange = this._get(inst, 'onChangeMonthYear');
9970 onChange.apply((inst.input ? inst.input[0] : null),
9971 [inst.selectedYear, inst.selectedMonth + 1, inst]);
9974 /* Determine the number of months to show. */
9975 _getNumberOfMonths: function(inst
) {
9976 var numMonths
= this._get(inst
, 'numberOfMonths');
9977 return (numMonths
== null ? [1, 1] : (typeof numMonths
== 'number' ? [1, numMonths
] : numMonths
));
9980 /* Determine the current maximum date - ensure no time components are set. */
9981 _getMinMaxDate: function(inst
, minMax
) {
9982 return this._determineDate(inst
, this._get(inst
, minMax
+ 'Date'), null);
9985 /* Find the number of days in a given month. */
9986 _getDaysInMonth: function(year
, month
) {
9987 return 32 - this._daylightSavingAdjust(new Date(year
, month
, 32)).getDate();
9990 /* Find the day of the week of the first of a month. */
9991 _getFirstDayOfMonth: function(year
, month
) {
9992 return new Date(year
, month
, 1).getDay();
9995 /* Determines if we should allow a "next/prev" month display change. */
9996 _canAdjustMonth: function(inst, offset, curYear, curMonth) {
9997 var numMonths = this._getNumberOfMonths(inst);
9998 var date = this._daylightSavingAdjust(new Date(curYear,
9999 curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
10001 date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
10002 return this._isInRange(inst, date);
10005 /* Is the given date in the accepted range? */
10006 _isInRange: function(inst
, date
) {
10007 var minDate
= this._getMinMaxDate(inst
, 'min');
10008 var maxDate
= this._getMinMaxDate(inst
, 'max');
10009 return ((!minDate
|| date
.getTime() >= minDate
.getTime()) &&
10010 (!maxDate
|| date
.getTime() <= maxDate
.getTime()));
10013 /* Provide the configuration settings for formatting/parsing. */
10014 _getFormatConfig: function(inst) {
10015 var shortYearCutoff = this._get(inst, 'shortYearCutoff');
10016 shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
10017 new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
10018 return {shortYearCutoff: shortYearCutoff,
10019 dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'),
10020 monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')};
10023 /* Format the given date for display. */
10024 _formatDate: function(inst
, day
, month
, year
) {
10026 inst
.currentDay
= inst
.selectedDay
;
10027 inst
.currentMonth
= inst
.selectedMonth
;
10028 inst
.currentYear
= inst
.selectedYear
;
10030 var date
= (day
? (typeof day
== 'object' ? day
:
10031 this._daylightSavingAdjust(new Date(year
, month
, day
))) :
10032 this._daylightSavingAdjust(new Date(inst
.currentYear
, inst
.currentMonth
, inst
.currentDay
)));
10033 return this.formatDate(this._get(inst
, 'dateFormat'), date
, this._getFormatConfig(inst
));
10038 * Bind hover events for datepicker elements.
10039 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
10040 * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
10042 function bindHover(dpDiv
) {
10043 var selector
= 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a';
10044 return dpDiv
.bind('mouseout', function(event
) {
10045 var elem
= $( event
.target
).closest( selector
);
10046 if ( !elem
.length
) {
10049 elem
.removeClass( "ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover" );
10051 .bind('mouseover', function(event
) {
10052 var elem
= $( event
.target
).closest( selector
);
10053 if ($.datepicker
._isDisabledDatepicker( instActive
.inline
? dpDiv
.parent()[0] : instActive
.input
[0]) ||
10057 elem
.parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover');
10058 elem
.addClass('ui-state-hover');
10059 if (elem
.hasClass('ui-datepicker-prev')) elem
.addClass('ui-datepicker-prev-hover');
10060 if (elem
.hasClass('ui-datepicker-next')) elem
.addClass('ui-datepicker-next-hover');
10064 /* jQuery extend now ignores nulls! */
10065 function extendRemove(target
, props
) {
10066 $.extend(target
, props
);
10067 for (var name
in props
)
10068 if (props
[name
] == null || props
[name
] == undefined)
10069 target
[name
] = props
[name
];
10073 /* Determine whether an object is an array. */
10074 function isArray(a
) {
10075 return (a
&& (($.browser
.safari
&& typeof a
== 'object' && a
.length
) ||
10076 (a
.constructor && a
.constructor.toString().match(/\Array\(\)/))));
10079 /* Invoke the datepicker functionality.
10080 @param options string - a command, optionally followed by additional parameters or
10081 Object - settings for attaching new datepicker functionality
10082 @return jQuery object */
10083 $.fn
.datepicker = function(options
){
10085 /* Verify an empty collection wasn't passed - Fixes #6976 */
10086 if ( !this.length
) {
10090 /* Initialise the date picker. */
10091 if (!$.datepicker
.initialized
) {
10092 $(document
).mousedown($.datepicker
._checkExternalClick
).
10093 find('body').append($.datepicker
.dpDiv
);
10094 $.datepicker
.initialized
= true;
10097 var otherArgs
= Array
.prototype.slice
.call(arguments
, 1);
10098 if (typeof options
== 'string' && (options
== 'isDisabled' || options
== 'getDate' || options
== 'widget'))
10099 return $.datepicker
['_' + options
+ 'Datepicker'].
10100 apply($.datepicker
, [this[0]].concat(otherArgs
));
10101 if (options
== 'option' && arguments
.length
== 2 && typeof arguments
[1] == 'string')
10102 return $.datepicker
['_' + options
+ 'Datepicker'].
10103 apply($.datepicker
, [this[0]].concat(otherArgs
));
10104 return this.each(function() {
10105 typeof options
== 'string' ?
10106 $.datepicker
['_' + options
+ 'Datepicker'].
10107 apply($.datepicker
, [this].concat(otherArgs
)) :
10108 $.datepicker
._attachDatepicker(this, options
);
10112 $.datepicker
= new Datepicker(); // singleton instance
10113 $.datepicker
.initialized
= false;
10114 $.datepicker
.uuid
= new Date().getTime();
10115 $.datepicker
.version
= "1.8.21";
10117 // Workaround for #4055
10118 // Add another global to avoid noConflict issues with inline event handlers
10119 window
['DP_jQuery_' + dpuuid
] = $;
10123 * jQuery UI Progressbar 1.8.21
10125 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
10126 * Dual licensed under the MIT or GPL Version 2 licenses.
10127 * http://jquery.org/license
10129 * http://docs.jquery.com/UI/Progressbar
10132 * jquery.ui.core.js
10133 * jquery.ui.widget.js
10135 (function( $, undefined ) {
10137 $.widget( "ui.progressbar", {
10145 _create: function() {
10147 .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10149 role
: "progressbar",
10150 "aria-valuemin": this.min
,
10151 "aria-valuemax": this.options
.max
,
10152 "aria-valuenow": this._value()
10155 this.valueDiv
= $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
10156 .appendTo( this.element
);
10158 this.oldValue
= this._value();
10159 this._refreshValue();
10162 destroy: function() {
10164 .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
10165 .removeAttr( "role" )
10166 .removeAttr( "aria-valuemin" )
10167 .removeAttr( "aria-valuemax" )
10168 .removeAttr( "aria-valuenow" );
10170 this.valueDiv
.remove();
10172 $.Widget
.prototype.destroy
.apply( this, arguments
);
10175 value: function( newValue
) {
10176 if ( newValue
=== undefined ) {
10177 return this._value();
10180 this._setOption( "value", newValue
);
10184 _setOption: function( key
, value
) {
10185 if ( key
=== "value" ) {
10186 this.options
.value
= value
;
10187 this._refreshValue();
10188 if ( this._value() === this.options
.max
) {
10189 this._trigger( "complete" );
10193 $.Widget
.prototype._setOption
.apply( this, arguments
);
10196 _value: function() {
10197 var val
= this.options
.value
;
10198 // normalize invalid value
10199 if ( typeof val
!== "number" ) {
10202 return Math
.min( this.options
.max
, Math
.max( this.min
, val
) );
10205 _percentage: function() {
10206 return 100 * this._value() / this.options
.max
;
10209 _refreshValue: function() {
10210 var value
= this.value();
10211 var percentage
= this._percentage();
10213 if ( this.oldValue
!== value
) {
10214 this.oldValue
= value
;
10215 this._trigger( "change" );
10219 .toggle( value
> this.min
)
10220 .toggleClass( "ui-corner-right", value
=== this.options
.max
)
10221 .width( percentage
.toFixed(0) + "%" );
10222 this.element
.attr( "aria-valuenow", value
);
10226 $.extend( $.ui
.progressbar
, {
10232 * jQuery UI Effects 1.8.21
10234 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
10235 * Dual licensed under the MIT or GPL Version 2 licenses.
10236 * http://jquery.org/license
10238 * http://docs.jquery.com/UI/Effects/
10240 ;jQuery
.effects
|| (function($, undefined) {
10246 /******************************************************************************/
10247 /****************************** COLOR ANIMATIONS ******************************/
10248 /******************************************************************************/
10250 // override the animation for color styles
10251 $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
10252 'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
10253 function(i
, attr
) {
10254 $.fx
.step
[attr
] = function(fx
) {
10255 if (!fx
.colorInit
) {
10256 fx
.start
= getColor(fx
.elem
, attr
);
10257 fx
.end
= getRGB(fx
.end
);
10258 fx
.colorInit
= true;
10261 fx
.elem
.style
[attr
] = 'rgb(' +
10262 Math
.max(Math
.min(parseInt((fx
.pos
* (fx
.end
[0] - fx
.start
[0])) + fx
.start
[0], 10), 255), 0) + ',' +
10263 Math
.max(Math
.min(parseInt((fx
.pos
* (fx
.end
[1] - fx
.start
[1])) + fx
.start
[1], 10), 255), 0) + ',' +
10264 Math
.max(Math
.min(parseInt((fx
.pos
* (fx
.end
[2] - fx
.start
[2])) + fx
.start
[2], 10), 255), 0) + ')';
10268 // Color Conversion functions from highlightFade
10269 // By Blair Mitchelmore
10270 // http://jquery.offput.ca/highlightFade/
10272 // Parse strings looking for color tuples [255,255,255]
10273 function getRGB(color
) {
10276 // Check if we're already dealing with an array of colors
10277 if ( color
&& color
.constructor == Array
&& color
.length
== 3 )
10280 // Look for rgb(num,num,num)
10281 if (result
= /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color
))
10282 return [parseInt(result
[1],10), parseInt(result
[2],10), parseInt(result
[3],10)];
10284 // Look for rgb(num%,num%,num%)
10285 if (result
= /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color
))
10286 return [parseFloat(result
[1])*2.55, parseFloat(result
[2])*2.55, parseFloat(result
[3])*2.55];
10288 // Look for #a0b1c2
10289 if (result
= /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color
))
10290 return [parseInt(result
[1],16), parseInt(result
[2],16), parseInt(result
[3],16)];
10293 if (result
= /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color
))
10294 return [parseInt(result
[1]+result
[1],16), parseInt(result
[2]+result
[2],16), parseInt(result
[3]+result
[3],16)];
10296 // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
10297 if (result
= /rgba\(0, 0, 0, 0\)/.exec(color
))
10298 return colors
['transparent'];
10300 // Otherwise, we're most likely dealing with a named color
10301 return colors
[$.trim(color
).toLowerCase()];
10304 function getColor(elem
, attr
) {
10308 color
= $.curCSS(elem
, attr
);
10310 // Keep going until we find an element that has color, or we hit the body
10311 if ( color
!= '' && color
!= 'transparent' || $.nodeName(elem
, "body") )
10314 attr
= "backgroundColor";
10315 } while ( elem
= elem
.parentNode
);
10317 return getRGB(color
);
10320 // Some named colors to work with
10321 // From Interface by Stefan Petre
10322 // http://interface.eyecon.ro/
10326 azure
:[240,255,255],
10327 beige
:[245,245,220],
10332 darkblue
:[0,0,139],
10333 darkcyan
:[0,139,139],
10334 darkgrey
:[169,169,169],
10335 darkgreen
:[0,100,0],
10336 darkkhaki
:[189,183,107],
10337 darkmagenta
:[139,0,139],
10338 darkolivegreen
:[85,107,47],
10339 darkorange
:[255,140,0],
10340 darkorchid
:[153,50,204],
10342 darksalmon
:[233,150,122],
10343 darkviolet
:[148,0,211],
10344 fuchsia
:[255,0,255],
10348 khaki
:[240,230,140],
10349 lightblue
:[173,216,230],
10350 lightcyan
:[224,255,255],
10351 lightgreen
:[144,238,144],
10352 lightgrey
:[211,211,211],
10353 lightpink
:[255,182,193],
10354 lightyellow
:[255,255,224],
10356 magenta
:[255,0,255],
10360 orange
:[255,165,0],
10361 pink
:[255,192,203],
10362 purple
:[128,0,128],
10363 violet
:[128,0,128],
10365 silver
:[192,192,192],
10366 white
:[255,255,255],
10367 yellow
:[255,255,0],
10368 transparent
: [255,255,255]
10373 /******************************************************************************/
10374 /****************************** CLASS ANIMATIONS ******************************/
10375 /******************************************************************************/
10377 var classAnimationActions
= ['add', 'remove', 'toggle'],
10378 shorthandStyles
= {
10390 function getElementStyles() {
10391 var style
= document
.defaultView
10392 ? document
.defaultView
.getComputedStyle(this, null)
10393 : this.currentStyle
,
10398 // webkit enumerates style porperties
10399 if (style
&& style
.length
&& style
[0] && style
[style
[0]]) {
10400 var len
= style
.length
;
10403 if (typeof style
[key
] == 'string') {
10404 camelCase
= key
.replace(/\-(\w)/g, function(all
, letter
){
10405 return letter
.toUpperCase();
10407 newStyle
[camelCase
] = style
[key
];
10411 for (key
in style
) {
10412 if (typeof style
[key
] === 'string') {
10413 newStyle
[key
] = style
[key
];
10421 function filterStyles(styles
) {
10423 for (name
in styles
) {
10424 value
= styles
[name
];
10426 // ignore null and undefined values
10428 // ignore functions (when does this occur?)
10429 $.isFunction(value
) ||
10430 // shorthand styles that need to be expanded
10431 name
in shorthandStyles
||
10432 // ignore scrollbars (break in IE)
10433 (/scrollbar/).test(name
) ||
10435 // only colors or values that can be converted to numbers
10436 (!(/color/i).test(name
) && isNaN(parseFloat(value
)))
10438 delete styles
[name
];
10445 function styleDifference(oldStyle
, newStyle
) {
10446 var diff
= { _
: 0 }, // http://dev.jquery.com/ticket/5459
10449 for (name
in newStyle
) {
10450 if (oldStyle
[name
] != newStyle
[name
]) {
10451 diff
[name
] = newStyle
[name
];
10458 $.effects
.animateClass = function(value
, duration
, easing
, callback
) {
10459 if ($.isFunction(easing
)) {
10464 return this.queue(function() {
10465 var that
= $(this),
10466 originalStyleAttr
= that
.attr('style') || ' ',
10467 originalStyle
= filterStyles(getElementStyles
.call(this)),
10469 className
= that
.attr('class') || "";
10471 $.each(classAnimationActions
, function(i
, action
) {
10472 if (value
[action
]) {
10473 that
[action
+ 'Class'](value
[action
]);
10476 newStyle
= filterStyles(getElementStyles
.call(this));
10477 that
.attr('class', className
);
10479 that
.animate(styleDifference(originalStyle
, newStyle
), {
10481 duration
: duration
,
10483 complete: function() {
10484 $.each(classAnimationActions
, function(i
, action
) {
10485 if (value
[action
]) { that
[action
+ 'Class'](value
[action
]); }
10487 // work around bug in IE by clearing the cssText before setting it
10488 if (typeof that
.attr('style') == 'object') {
10489 that
.attr('style').cssText
= '';
10490 that
.attr('style').cssText
= originalStyleAttr
;
10492 that
.attr('style', originalStyleAttr
);
10494 if (callback
) { callback
.apply(this, arguments
); }
10502 _addClass
: $.fn
.addClass
,
10503 addClass: function(classNames
, speed
, easing
, callback
) {
10504 return speed
? $.effects
.animateClass
.apply(this, [{ add
: classNames
},speed
,easing
,callback
]) : this._addClass(classNames
);
10507 _removeClass
: $.fn
.removeClass
,
10508 removeClass: function(classNames
,speed
,easing
,callback
) {
10509 return speed
? $.effects
.animateClass
.apply(this, [{ remove
: classNames
},speed
,easing
,callback
]) : this._removeClass(classNames
);
10512 _toggleClass
: $.fn
.toggleClass
,
10513 toggleClass: function(classNames
, force
, speed
, easing
, callback
) {
10514 if ( typeof force
== "boolean" || force
=== undefined ) {
10516 // without speed parameter;
10517 return this._toggleClass(classNames
, force
);
10519 return $.effects
.animateClass
.apply(this, [(force
?{add
:classNames
}:{remove
:classNames
}),speed
,easing
,callback
]);
10522 // without switch parameter;
10523 return $.effects
.animateClass
.apply(this, [{ toggle
: classNames
},force
,speed
,easing
]);
10527 switchClass: function(remove
,add
,speed
,easing
,callback
) {
10528 return $.effects
.animateClass
.apply(this, [{ add
: add
, remove
: remove
},speed
,easing
,callback
]);
10534 /******************************************************************************/
10535 /*********************************** EFFECTS **********************************/
10536 /******************************************************************************/
10538 $.extend($.effects
, {
10541 // Saves a set of properties in a data storage
10542 save: function(element
, set) {
10543 for(var i
=0; i
< set.length
; i
++) {
10544 if(set[i
] !== null) element
.data("ec.storage."+set[i
], element
[0].style
[set[i
]]);
10548 // Restores a set of previously saved properties from a data storage
10549 restore: function(element
, set) {
10550 for(var i
=0; i
< set.length
; i
++) {
10551 if(set[i
] !== null) element
.css(set[i
], element
.data("ec.storage."+set[i
]));
10555 setMode: function(el
, mode
) {
10556 if (mode
== 'toggle') mode
= el
.is(':hidden') ? 'show' : 'hide'; // Set for toggle
10560 getBaseline: function(origin
, original
) { // Translates a [top,left] array into a baseline value
10561 // this should be a little more flexible in the future to handle a string & hash
10563 switch (origin
[0]) {
10564 case 'top': y
= 0; break;
10565 case 'middle': y
= 0.5; break;
10566 case 'bottom': y
= 1; break;
10567 default: y
= origin
[0] / original
.height
;
10569 switch (origin
[1]) {
10570 case 'left': x
= 0; break;
10571 case 'center': x
= 0.5; break;
10572 case 'right': x
= 1; break;
10573 default: x
= origin
[1] / original
.width
;
10575 return {x
: x
, y
: y
};
10578 // Wraps the element around a wrapper that copies position properties
10579 createWrapper: function(element
) {
10581 // if the element is already wrapped, return it
10582 if (element
.parent().is('.ui-effects-wrapper')) {
10583 return element
.parent();
10586 // wrap the element
10588 width
: element
.outerWidth(true),
10589 height
: element
.outerHeight(true),
10590 'float': element
.css('float')
10592 wrapper
= $('<div></div>')
10593 .addClass('ui-effects-wrapper')
10596 background
: 'transparent',
10601 active
= document
.activeElement
;
10603 // support: Firefox
10604 // Firefox incorrectly exposes anonymous content
10605 // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
10609 active
= document
.body
;
10612 element
.wrap( wrapper
);
10614 // Fixes #7595 - Elements lose focus when wrapped.
10615 if ( element
[ 0 ] === active
|| $.contains( element
[ 0 ], active
) ) {
10616 $( active
).focus();
10619 wrapper
= element
.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
10621 // transfer positioning properties to the wrapper
10622 if (element
.css('position') == 'static') {
10623 wrapper
.css({ position
: 'relative' });
10624 element
.css({ position
: 'relative' });
10627 position
: element
.css('position'),
10628 zIndex
: element
.css('z-index')
10630 $.each(['top', 'left', 'bottom', 'right'], function(i
, pos
) {
10631 props
[pos
] = element
.css(pos
);
10632 if (isNaN(parseInt(props
[pos
], 10))) {
10633 props
[pos
] = 'auto';
10636 element
.css({position
: 'relative', top
: 0, left
: 0, right
: 'auto', bottom
: 'auto' });
10639 return wrapper
.css(props
).show();
10642 removeWrapper: function(element
) {
10644 active
= document
.activeElement
;
10646 if (element
.parent().is('.ui-effects-wrapper')) {
10647 parent
= element
.parent().replaceWith(element
);
10648 // Fixes #7595 - Elements lose focus when wrapped.
10649 if ( element
[ 0 ] === active
|| $.contains( element
[ 0 ], active
) ) {
10650 $( active
).focus();
10658 setTransition: function(element
, list
, factor
, value
) {
10659 value
= value
|| {};
10660 $.each(list
, function(i
, x
){
10661 var unit
= element
.cssUnit(x
);
10662 if (unit
[0] > 0) value
[x
] = unit
[0] * factor
+ unit
[1];
10669 function _normalizeArguments(effect
, options
, speed
, callback
) {
10670 // shift params for method overloading
10671 if (typeof effect
== 'object') {
10672 callback
= options
;
10675 effect
= options
.effect
;
10677 if ($.isFunction(options
)) {
10678 callback
= options
;
10682 if (typeof options
== 'number' || $.fx
.speeds
[options
]) {
10687 if ($.isFunction(speed
)) {
10692 options
= options
|| {};
10694 speed
= speed
|| options
.duration
;
10695 speed
= $.fx
.off
? 0 : typeof speed
== 'number'
10696 ? speed
: speed
in $.fx
.speeds
? $.fx
.speeds
[speed
] : $.fx
.speeds
._default
;
10698 callback
= callback
|| options
.complete
;
10700 return [effect
, options
, speed
, callback
];
10703 function standardSpeed( speed
) {
10704 // valid standard speeds
10705 if ( !speed
|| typeof speed
=== "number" || $.fx
.speeds
[ speed
] ) {
10709 // invalid strings - treat as "normal" speed
10710 if ( typeof speed
=== "string" && !$.effects
[ speed
] ) {
10718 effect: function(effect
, options
, speed
, callback
) {
10719 var args
= _normalizeArguments
.apply(this, arguments
),
10720 // TODO: make effects take actual parameters instead of a hash
10726 mode
= args2
.options
.mode
,
10727 effectMethod
= $.effects
[effect
];
10729 if ( $.fx
.off
|| !effectMethod
) {
10730 // delegate to the original method (e.g., .show()) if possible
10732 return this[ mode
]( args2
.duration
, args2
.callback
);
10734 return this.each(function() {
10735 if ( args2
.callback
) {
10736 args2
.callback
.call( this );
10742 return effectMethod
.call(this, args2
);
10746 show: function(speed
) {
10747 if ( standardSpeed( speed
) ) {
10748 return this._show
.apply(this, arguments
);
10750 var args
= _normalizeArguments
.apply(this, arguments
);
10751 args
[1].mode
= 'show';
10752 return this.effect
.apply(this, args
);
10757 hide: function(speed
) {
10758 if ( standardSpeed( speed
) ) {
10759 return this._hide
.apply(this, arguments
);
10761 var args
= _normalizeArguments
.apply(this, arguments
);
10762 args
[1].mode
= 'hide';
10763 return this.effect
.apply(this, args
);
10767 // jQuery core overloads toggle and creates _toggle
10768 __toggle
: $.fn
.toggle
,
10769 toggle: function(speed
) {
10770 if ( standardSpeed( speed
) || typeof speed
=== "boolean" || $.isFunction( speed
) ) {
10771 return this.__toggle
.apply(this, arguments
);
10773 var args
= _normalizeArguments
.apply(this, arguments
);
10774 args
[1].mode
= 'toggle';
10775 return this.effect
.apply(this, args
);
10779 // helper functions
10780 cssUnit: function(key
) {
10781 var style
= this.css(key
), val
= [];
10782 $.each( ['em','px','%','pt'], function(i
, unit
){
10783 if(style
.indexOf(unit
) > 0)
10784 val
= [parseFloat(style
), unit
];
10792 /******************************************************************************/
10793 /*********************************** EASING ***********************************/
10794 /******************************************************************************/
10797 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
10799 * Uses the built in easing capabilities added In jQuery 1.1
10800 * to offer multiple easing options
10802 * TERMS OF USE - jQuery Easing
10804 * Open source under the BSD License.
10806 * Copyright 2008 George McGinley Smith
10807 * All rights reserved.
10809 * Redistribution and use in source and binary forms, with or without modification,
10810 * are permitted provided that the following conditions are met:
10812 * Redistributions of source code must retain the above copyright notice, this list of
10813 * conditions and the following disclaimer.
10814 * Redistributions in binary form must reproduce the above copyright notice, this list
10815 * of conditions and the following disclaimer in the documentation and/or other materials
10816 * provided with the distribution.
10818 * Neither the name of the author nor the names of contributors may be used to endorse
10819 * or promote products derived from this software without specific prior written permission.
10821 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
10822 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
10823 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
10824 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
10825 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
10826 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
10827 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
10828 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10829 * OF THE POSSIBILITY OF SUCH DAMAGE.
10833 // t: current time, b: begInnIng value, c: change In value, d: duration
10834 $.easing
.jswing
= $.easing
.swing
;
10838 def
: 'easeOutQuad',
10839 swing: function (x
, t
, b
, c
, d
) {
10840 //alert($.easing.default);
10841 return $.easing
[$.easing
.def
](x
, t
, b
, c
, d
);
10843 easeInQuad: function (x
, t
, b
, c
, d
) {
10844 return c
*(t
/=d
)*t
+ b
;
10846 easeOutQuad: function (x
, t
, b
, c
, d
) {
10847 return -c
*(t
/=d
)*(t
-2) + b
;
10849 easeInOutQuad: function (x
, t
, b
, c
, d
) {
10850 if ((t
/=d/2) < 1) return c
/2*t
*t
+ b
;
10851 return -c
/2 * ((--t
)*(t
-2) - 1) + b
;
10853 easeInCubic: function (x
, t
, b
, c
, d
) {
10854 return c
*(t
/=d
)*t
*t
+ b
;
10856 easeOutCubic: function (x
, t
, b
, c
, d
) {
10857 return c
*((t
=t
/d
-1)*t
*t
+ 1) + b
;
10859 easeInOutCubic: function (x
, t
, b
, c
, d
) {
10860 if ((t
/=d/2) < 1) return c
/2*t
*t
*t
+ b
;
10861 return c
/2*((t
-=2)*t
*t
+ 2) + b
;
10863 easeInQuart: function (x
, t
, b
, c
, d
) {
10864 return c
*(t
/=d
)*t
*t
*t
+ b
;
10866 easeOutQuart: function (x
, t
, b
, c
, d
) {
10867 return -c
* ((t
=t
/d
-1)*t
*t
*t
- 1) + b
;
10869 easeInOutQuart: function (x
, t
, b
, c
, d
) {
10870 if ((t
/=d/2) < 1) return c
/2*t
*t
*t
*t
+ b
;
10871 return -c
/2 * ((t
-=2)*t
*t
*t
- 2) + b
;
10873 easeInQuint: function (x
, t
, b
, c
, d
) {
10874 return c
*(t
/=d
)*t
*t
*t
*t
+ b
;
10876 easeOutQuint: function (x
, t
, b
, c
, d
) {
10877 return c
*((t
=t
/d
-1)*t
*t
*t
*t
+ 1) + b
;
10879 easeInOutQuint: function (x
, t
, b
, c
, d
) {
10880 if ((t
/=d/2) < 1) return c
/2*t
*t
*t
*t
*t
+ b
;
10881 return c
/2*((t
-=2)*t
*t
*t
*t
+ 2) + b
;
10883 easeInSine: function (x
, t
, b
, c
, d
) {
10884 return -c
* Math
.cos(t
/d * (Math.PI/2)) + c
+ b
;
10886 easeOutSine: function (x
, t
, b
, c
, d
) {
10887 return c
* Math
.sin(t
/d * (Math.PI/2)) + b
;
10889 easeInOutSine: function (x
, t
, b
, c
, d
) {
10890 return -c
/2 * (Math.cos(Math.PI*t/d) - 1) + b
;
10892 easeInExpo: function (x
, t
, b
, c
, d
) {
10893 return (t
==0) ? b
: c
* Math
.pow(2, 10 * (t
/d
- 1)) + b
;
10895 easeOutExpo: function (x
, t
, b
, c
, d
) {
10896 return (t
==d
) ? b
+c
: c
* (-Math
.pow(2, -10 * t
/d
) + 1) + b
;
10898 easeInOutExpo: function (x
, t
, b
, c
, d
) {
10899 if (t
==0) return b
;
10900 if (t
==d
) return b
+c
;
10901 if ((t
/=d/2) < 1) return c
/2 * Math
.pow(2, 10 * (t
- 1)) + b
;
10902 return c
/2 * (-Math
.pow(2, -10 * --t
) + 2) + b
;
10904 easeInCirc: function (x
, t
, b
, c
, d
) {
10905 return -c
* (Math
.sqrt(1 - (t
/=d
)*t
) - 1) + b
;
10907 easeOutCirc: function (x
, t
, b
, c
, d
) {
10908 return c
* Math
.sqrt(1 - (t
=t
/d
-1)*t
) + b
;
10910 easeInOutCirc: function (x
, t
, b
, c
, d
) {
10911 if ((t
/=d/2) < 1) return -c
/2 * (Math
.sqrt(1 - t
*t
) - 1) + b
;
10912 return c
/2 * (Math
.sqrt(1 - (t
-=2)*t
) + 1) + b
;
10914 easeInElastic: function (x
, t
, b
, c
, d
) {
10915 var s
=1.70158;var p
=0;var a
=c
;
10916 if (t
==0) return b
; if ((t
/=d
)==1) return b
+c
; if (!p
) p
=d
*.3;
10917 if (a
< Math
.abs(c
)) { a
=c
; var s
=p
/4; }
10918 else var s
= p
/(2*Math.PI) * Math.asin (c/a);
10919 return -(a
*Math
.pow(2,10*(t
-=1)) * Math
.sin( (t
*d
-s
)*(2*Math
.PI
)/p
)) + b
;
10921 easeOutElastic: function (x
, t
, b
, c
, d
) {
10922 var s
=1.70158;var p
=0;var a
=c
;
10923 if (t
==0) return b
; if ((t
/=d
)==1) return b
+c
; if (!p
) p
=d
*.3;
10924 if (a
< Math
.abs(c
)) { a
=c
; var s
=p
/4; }
10925 else var s
= p
/(2*Math.PI) * Math.asin (c/a);
10926 return a
*Math
.pow(2,-10*t
) * Math
.sin( (t
*d
-s
)*(2*Math
.PI
)/p
) + c
+ b
;
10928 easeInOutElastic: function (x
, t
, b
, c
, d
) {
10929 var s
=1.70158;var p
=0;var a
=c
;
10930 if (t
==0) return b
; if ((t
/=d/2)==2) return b
+c
; if (!p
) p
=d
*(.3*1.5);
10931 if (a
< Math
.abs(c
)) { a
=c
; var s
=p
/4; }
10932 else var s
= p
/(2*Math.PI) * Math.asin (c/a);
10933 if (t
< 1) return -.5*(a
*Math
.pow(2,10*(t
-=1)) * Math
.sin( (t
*d
-s
)*(2*Math
.PI
)/p
)) + b
;
10934 return a
*Math
.pow(2,-10*(t
-=1)) * Math
.sin( (t
*d
-s
)*(2*Math
.PI
)/p
)*.5 + c
+ b
;
10936 easeInBack: function (x
, t
, b
, c
, d
, s
) {
10937 if (s
== undefined) s
= 1.70158;
10938 return c
*(t
/=d
)*t
*((s
+1)*t
- s
) + b
;
10940 easeOutBack: function (x
, t
, b
, c
, d
, s
) {
10941 if (s
== undefined) s
= 1.70158;
10942 return c
*((t
=t
/d
-1)*t
*((s
+1)*t
+ s
) + 1) + b
;
10944 easeInOutBack: function (x
, t
, b
, c
, d
, s
) {
10945 if (s
== undefined) s
= 1.70158;
10946 if ((t
/=d/2) < 1) return c
/2*(t
*t
*(((s
*=(1.525))+1)*t
- s
)) + b
;
10947 return c
/2*((t
-=2)*t
*(((s
*=(1.525))+1)*t
+ s
) + 2) + b
;
10949 easeInBounce: function (x
, t
, b
, c
, d
) {
10950 return c
- $.easing
.easeOutBounce (x
, d
-t
, 0, c
, d
) + b
;
10952 easeOutBounce: function (x
, t
, b
, c
, d
) {
10953 if ((t
/=d) < (1/2.75)) {
10954 return c
*(7.5625*t
*t
) + b
;
10955 } else if (t
< (2/2.75)) {
10956 return c
*(7.5625*(t
-=(1.5/2.75))*t
+ .75) + b
;
10957 } else if (t
< (2.5/2.75)) {
10958 return c
*(7.5625*(t
-=(2.25/2.75))*t
+ .9375) + b
;
10960 return c
*(7.5625*(t
-=(2.625/2.75))*t
+ .984375) + b
;
10963 easeInOutBounce: function (x
, t
, b
, c
, d
) {
10964 if (t
< d
/2) return $.easing
.easeInBounce (x
, t
*2, 0, c
, d
) * .5 + b
;
10965 return $.easing
.easeOutBounce (x
, t
*2-d
, 0, c
, d
) * .5 + c
*.5 + b
;
10971 * TERMS OF USE - EASING EQUATIONS
10973 * Open source under the BSD License.
10975 * Copyright 2001 Robert Penner
10976 * All rights reserved.
10978 * Redistribution and use in source and binary forms, with or without modification,
10979 * are permitted provided that the following conditions are met:
10981 * Redistributions of source code must retain the above copyright notice, this list of
10982 * conditions and the following disclaimer.
10983 * Redistributions in binary form must reproduce the above copyright notice, this list
10984 * of conditions and the following disclaimer in the documentation and/or other materials
10985 * provided with the distribution.
10987 * Neither the name of the author nor the names of contributors may be used to endorse
10988 * or promote products derived from this software without specific prior written permission.
10990 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
10991 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
10992 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
10993 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
10994 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
10995 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
10996 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
10997 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10998 * OF THE POSSIBILITY OF SUCH DAMAGE.
11004 * jQuery UI Effects Blind 1.8.21
11006 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11007 * Dual licensed under the MIT or GPL Version 2 licenses.
11008 * http://jquery.org/license
11010 * http://docs.jquery.com/UI/Effects/Blind
11013 * jquery.effects.core.js
11015 (function( $, undefined ) {
11017 $.effects
.blind = function(o
) {
11019 return this.queue(function() {
11022 var el
= $(this), props
= ['position','top','bottom','left','right'];
11025 var mode
= $.effects
.setMode(el
, o
.options
.mode
|| 'hide'); // Set Mode
11026 var direction
= o
.options
.direction
|| 'vertical'; // Default direction
11029 $.effects
.save(el
, props
); el
.show(); // Save & Show
11030 var wrapper
= $.effects
.createWrapper(el
).css({overflow
:'hidden'}); // Create Wrapper
11031 var ref
= (direction
== 'vertical') ? 'height' : 'width';
11032 var distance
= (direction
== 'vertical') ? wrapper
.height() : wrapper
.width();
11033 if(mode
== 'show') wrapper
.css(ref
, 0); // Shift
11036 var animation
= {};
11037 animation
[ref
] = mode
== 'show' ? distance
: 0;
11040 wrapper
.animate(animation
, o
.duration
, o
.options
.easing
, function() {
11041 if(mode
== 'hide') el
.hide(); // Hide
11042 $.effects
.restore(el
, props
); $.effects
.removeWrapper(el
); // Restore
11043 if(o
.callback
) o
.callback
.apply(el
[0], arguments
); // Callback
11053 * jQuery UI Effects Bounce 1.8.21
11055 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11056 * Dual licensed under the MIT or GPL Version 2 licenses.
11057 * http://jquery.org/license
11059 * http://docs.jquery.com/UI/Effects/Bounce
11062 * jquery.effects.core.js
11064 (function( $, undefined ) {
11066 $.effects
.bounce = function(o
) {
11068 return this.queue(function() {
11071 var el
= $(this), props
= ['position','top','bottom','left','right'];
11074 var mode
= $.effects
.setMode(el
, o
.options
.mode
|| 'effect'); // Set Mode
11075 var direction
= o
.options
.direction
|| 'up'; // Default direction
11076 var distance
= o
.options
.distance
|| 20; // Default distance
11077 var times
= o
.options
.times
|| 5; // Default # of times
11078 var speed
= o
.duration
|| 250; // Default speed per bounce
11079 if (/show|hide/.test(mode
)) props
.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE
11082 $.effects
.save(el
, props
); el
.show(); // Save & Show
11083 $.effects
.createWrapper(el
); // Create Wrapper
11084 var ref
= (direction
== 'up' || direction
== 'down') ? 'top' : 'left';
11085 var motion
= (direction
== 'up' || direction
== 'left') ? 'pos' : 'neg';
11086 var distance
= o
.options
.distance
|| (ref
== 'top' ? el
.outerHeight({margin
:true}) / 3 : el
.outerWidth({margin
:true}) / 3);
11087 if (mode
== 'show') el
.css('opacity', 0).css(ref
, motion
== 'pos' ? -distance
: distance
); // Shift
11088 if (mode
== 'hide') distance
= distance
/ (times
* 2);
11089 if (mode
!= 'hide') times
--;
11092 if (mode
== 'show') { // Show Bounce
11093 var animation
= {opacity
: 1};
11094 animation
[ref
] = (motion
== 'pos' ? '+=' : '-=') + distance
;
11095 el
.animate(animation
, speed
/ 2, o
.options
.easing
);
11096 distance
= distance
/ 2;
11099 for (var i
= 0; i
< times
; i
++) { // Bounces
11100 var animation1
= {}, animation2
= {};
11101 animation1
[ref
] = (motion
== 'pos' ? '-=' : '+=') + distance
;
11102 animation2
[ref
] = (motion
== 'pos' ? '+=' : '-=') + distance
;
11103 el
.animate(animation1
, speed
/ 2, o
.options
.easing
).animate(animation2
, speed
/ 2, o
.options
.easing
);
11104 distance
= (mode
== 'hide') ? distance
* 2 : distance
/ 2;
11106 if (mode
== 'hide') { // Last Bounce
11107 var animation
= {opacity
: 0};
11108 animation
[ref
] = (motion
== 'pos' ? '-=' : '+=') + distance
;
11109 el
.animate(animation
, speed
/ 2, o
.options
.easing
, function(){
11111 $.effects
.restore(el
, props
); $.effects
.removeWrapper(el
); // Restore
11112 if(o
.callback
) o
.callback
.apply(this, arguments
); // Callback
11115 var animation1
= {}, animation2
= {};
11116 animation1
[ref
] = (motion
== 'pos' ? '-=' : '+=') + distance
;
11117 animation2
[ref
] = (motion
== 'pos' ? '+=' : '-=') + distance
;
11118 el
.animate(animation1
, speed
/ 2, o
.options
.easing
).animate(animation2
, speed
/ 2, o
.options
.easing
, function(){
11119 $.effects
.restore(el
, props
); $.effects
.removeWrapper(el
); // Restore
11120 if(o
.callback
) o
.callback
.apply(this, arguments
); // Callback
11123 el
.queue('fx', function() { el
.dequeue(); });
11131 * jQuery UI Effects Clip 1.8.21
11133 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11134 * Dual licensed under the MIT or GPL Version 2 licenses.
11135 * http://jquery.org/license
11137 * http://docs.jquery.com/UI/Effects/Clip
11140 * jquery.effects.core.js
11142 (function( $, undefined ) {
11144 $.effects
.clip = function(o
) {
11146 return this.queue(function() {
11149 var el
= $(this), props
= ['position','top','bottom','left','right','height','width'];
11152 var mode
= $.effects
.setMode(el
, o
.options
.mode
|| 'hide'); // Set Mode
11153 var direction
= o
.options
.direction
|| 'vertical'; // Default direction
11156 $.effects
.save(el
, props
); el
.show(); // Save & Show
11157 var wrapper
= $.effects
.createWrapper(el
).css({overflow
:'hidden'}); // Create Wrapper
11158 var animate
= el
[0].tagName
== 'IMG' ? wrapper
: el
;
11160 size
: (direction
== 'vertical') ? 'height' : 'width',
11161 position
: (direction
== 'vertical') ? 'top' : 'left'
11163 var distance
= (direction
== 'vertical') ? animate
.height() : animate
.width();
11164 if(mode
== 'show') { animate
.css(ref
.size
, 0); animate
.css(ref
.position
, distance
/ 2); } // Shift
11167 var animation
= {};
11168 animation
[ref
.size
] = mode
== 'show' ? distance
: 0;
11169 animation
[ref
.position
] = mode
== 'show' ? 0 : distance
/ 2;
11172 animate
.animate(animation
, { queue
: false, duration
: o
.duration
, easing
: o
.options
.easing
, complete: function() {
11173 if(mode
== 'hide') el
.hide(); // Hide
11174 $.effects
.restore(el
, props
); $.effects
.removeWrapper(el
); // Restore
11175 if(o
.callback
) o
.callback
.apply(el
[0], arguments
); // Callback
11185 * jQuery UI Effects Drop 1.8.21
11187 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11188 * Dual licensed under the MIT or GPL Version 2 licenses.
11189 * http://jquery.org/license
11191 * http://docs.jquery.com/UI/Effects/Drop
11194 * jquery.effects.core.js
11196 (function( $, undefined ) {
11198 $.effects
.drop = function(o
) {
11200 return this.queue(function() {
11203 var el
= $(this), props
= ['position','top','bottom','left','right','opacity'];
11206 var mode
= $.effects
.setMode(el
, o
.options
.mode
|| 'hide'); // Set Mode
11207 var direction
= o
.options
.direction
|| 'left'; // Default Direction
11210 $.effects
.save(el
, props
); el
.show(); // Save & Show
11211 $.effects
.createWrapper(el
); // Create Wrapper
11212 var ref
= (direction
== 'up' || direction
== 'down') ? 'top' : 'left';
11213 var motion
= (direction
== 'up' || direction
== 'left') ? 'pos' : 'neg';
11214 var distance
= o
.options
.distance
|| (ref
== 'top' ? el
.outerHeight({margin
:true}) / 2 : el
.outerWidth({margin
:true}) / 2);
11215 if (mode
== 'show') el
.css('opacity', 0).css(ref
, motion
== 'pos' ? -distance
: distance
); // Shift
11218 var animation
= {opacity
: mode
== 'show' ? 1 : 0};
11219 animation
[ref
] = (mode
== 'show' ? (motion
== 'pos' ? '+=' : '-=') : (motion
== 'pos' ? '-=' : '+=')) + distance
;
11222 el
.animate(animation
, { queue
: false, duration
: o
.duration
, easing
: o
.options
.easing
, complete: function() {
11223 if(mode
== 'hide') el
.hide(); // Hide
11224 $.effects
.restore(el
, props
); $.effects
.removeWrapper(el
); // Restore
11225 if(o
.callback
) o
.callback
.apply(this, arguments
); // Callback
11235 * jQuery UI Effects Explode 1.8.21
11237 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11238 * Dual licensed under the MIT or GPL Version 2 licenses.
11239 * http://jquery.org/license
11241 * http://docs.jquery.com/UI/Effects/Explode
11244 * jquery.effects.core.js
11246 (function( $, undefined ) {
11248 $.effects
.explode = function(o
) {
11250 return this.queue(function() {
11252 var rows
= o
.options
.pieces
? Math
.round(Math
.sqrt(o
.options
.pieces
)) : 3;
11253 var cells
= o
.options
.pieces
? Math
.round(Math
.sqrt(o
.options
.pieces
)) : 3;
11255 o
.options
.mode
= o
.options
.mode
== 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o
.options
.mode
;
11256 var el
= $(this).show().css('visibility', 'hidden');
11257 var offset
= el
.offset();
11259 //Substract the margins - not fixing the problem yet.
11260 offset
.top
-= parseInt(el
.css("marginTop"),10) || 0;
11261 offset
.left
-= parseInt(el
.css("marginLeft"),10) || 0;
11263 var width
= el
.outerWidth(true);
11264 var height
= el
.outerHeight(true);
11266 for(var i
=0;i
<rows
;i
++) { // =
11267 for(var j
=0;j
<cells
;j
++) { // ||
11271 .wrap('<div></div>')
11273 position
: 'absolute',
11274 visibility
: 'visible',
11275 left
: -j
*(width
/cells
),
11276 top
: -i
*(height
/rows
)
11279 .addClass('ui-effects-explode')
11281 position
: 'absolute',
11282 overflow
: 'hidden',
11283 width
: width
/cells
,
11284 height
: height
/rows
,
11285 left
: offset
.left
+ j
*(width
/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width
/cells
) : 0),
11286 top
: offset
.top
+ i
*(height
/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height
/rows
) : 0),
11287 opacity
: o
.options
.mode
== 'show' ? 0 : 1
11289 left
: offset
.left
+ j
*(width
/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width
/cells
)),
11290 top
: offset
.top
+ i
*(height
/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height
/rows
)),
11291 opacity
: o
.options
.mode
== 'show' ? 1 : 0
11292 }, o
.duration
|| 500);
11296 // Set a timeout, to call the callback approx. when the other animations have finished
11297 setTimeout(function() {
11299 o
.options
.mode
== 'show' ? el
.css({ visibility
: 'visible' }) : el
.css({ visibility
: 'visible' }).hide();
11300 if(o
.callback
) o
.callback
.apply(el
[0]); // Callback
11303 $('div.ui-effects-explode').remove();
11305 }, o
.duration
|| 500);
11314 * jQuery UI Effects Fade 1.8.21
11316 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11317 * Dual licensed under the MIT or GPL Version 2 licenses.
11318 * http://jquery.org/license
11320 * http://docs.jquery.com/UI/Effects/Fade
11323 * jquery.effects.core.js
11325 (function( $, undefined ) {
11327 $.effects
.fade = function(o
) {
11328 return this.queue(function() {
11329 var elem
= $(this),
11330 mode
= $.effects
.setMode(elem
, o
.options
.mode
|| 'hide');
11332 elem
.animate({ opacity
: mode
}, {
11334 duration
: o
.duration
,
11335 easing
: o
.options
.easing
,
11336 complete: function() {
11337 (o
.callback
&& o
.callback
.apply(this, arguments
));
11346 * jQuery UI Effects Fold 1.8.21
11348 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11349 * Dual licensed under the MIT or GPL Version 2 licenses.
11350 * http://jquery.org/license
11352 * http://docs.jquery.com/UI/Effects/Fold
11355 * jquery.effects.core.js
11357 (function( $, undefined ) {
11359 $.effects
.fold = function(o
) {
11361 return this.queue(function() {
11364 var el
= $(this), props
= ['position','top','bottom','left','right'];
11367 var mode
= $.effects
.setMode(el
, o
.options
.mode
|| 'hide'); // Set Mode
11368 var size
= o
.options
.size
|| 15; // Default fold size
11369 var horizFirst
= !(!o
.options
.horizFirst
); // Ensure a boolean value
11370 var duration
= o
.duration
? o
.duration
/ 2 : $.fx
.speeds
._default
/ 2;
11373 $.effects
.save(el
, props
); el
.show(); // Save & Show
11374 var wrapper
= $.effects
.createWrapper(el
).css({overflow
:'hidden'}); // Create Wrapper
11375 var widthFirst
= ((mode
== 'show') != horizFirst
);
11376 var ref
= widthFirst
? ['width', 'height'] : ['height', 'width'];
11377 var distance
= widthFirst
? [wrapper
.width(), wrapper
.height()] : [wrapper
.height(), wrapper
.width()];
11378 var percent
= /([0-9]+)%/.exec(size
);
11379 if(percent
) size
= parseInt(percent
[1],10) / 100 * distance
[mode
== 'hide' ? 0 : 1];
11380 if(mode
== 'show') wrapper
.css(horizFirst
? {height
: 0, width
: size
} : {height
: size
, width
: 0}); // Shift
11383 var animation1
= {}, animation2
= {};
11384 animation1
[ref
[0]] = mode
== 'show' ? distance
[0] : size
;
11385 animation2
[ref
[1]] = mode
== 'show' ? distance
[1] : 0;
11388 wrapper
.animate(animation1
, duration
, o
.options
.easing
)
11389 .animate(animation2
, duration
, o
.options
.easing
, function() {
11390 if(mode
== 'hide') el
.hide(); // Hide
11391 $.effects
.restore(el
, props
); $.effects
.removeWrapper(el
); // Restore
11392 if(o
.callback
) o
.callback
.apply(el
[0], arguments
); // Callback
11402 * jQuery UI Effects Highlight 1.8.21
11404 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11405 * Dual licensed under the MIT or GPL Version 2 licenses.
11406 * http://jquery.org/license
11408 * http://docs.jquery.com/UI/Effects/Highlight
11411 * jquery.effects.core.js
11413 (function( $, undefined ) {
11415 $.effects
.highlight = function(o
) {
11416 return this.queue(function() {
11417 var elem
= $(this),
11418 props
= ['backgroundImage', 'backgroundColor', 'opacity'],
11419 mode
= $.effects
.setMode(elem
, o
.options
.mode
|| 'show'),
11421 backgroundColor
: elem
.css('backgroundColor')
11424 if (mode
== 'hide') {
11425 animation
.opacity
= 0;
11428 $.effects
.save(elem
, props
);
11432 backgroundImage
: 'none',
11433 backgroundColor
: o
.options
.color
|| '#ffff99'
11435 .animate(animation
, {
11437 duration
: o
.duration
,
11438 easing
: o
.options
.easing
,
11439 complete: function() {
11440 (mode
== 'hide' && elem
.hide());
11441 $.effects
.restore(elem
, props
);
11442 (mode
== 'show' && !$.support
.opacity
&& this.style
.removeAttribute('filter'));
11443 (o
.callback
&& o
.callback
.apply(this, arguments
));
11452 * jQuery UI Effects Pulsate 1.8.21
11454 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11455 * Dual licensed under the MIT or GPL Version 2 licenses.
11456 * http://jquery.org/license
11458 * http://docs.jquery.com/UI/Effects/Pulsate
11461 * jquery.effects.core.js
11463 (function( $, undefined ) {
11465 $.effects
.pulsate = function(o
) {
11466 return this.queue(function() {
11467 var elem
= $(this),
11468 mode
= $.effects
.setMode(elem
, o
.options
.mode
|| 'show'),
11469 times
= ((o
.options
.times
|| 5) * 2) - 1,
11470 duration
= o
.duration
? o
.duration
/ 2 : $.fx
.speeds
._default
/ 2,
11471 isVisible
= elem
.is(':visible'),
11475 elem
.css('opacity', 0).show();
11479 if ((mode
== 'hide' && isVisible
) || (mode
== 'show' && !isVisible
)) {
11483 for (var i
= 0; i
< times
; i
++) {
11484 elem
.animate({ opacity
: animateTo
}, duration
, o
.options
.easing
);
11485 animateTo
= (animateTo
+ 1) % 2;
11488 elem
.animate({ opacity
: animateTo
}, duration
, o
.options
.easing
, function() {
11489 if (animateTo
== 0) {
11492 (o
.callback
&& o
.callback
.apply(this, arguments
));
11496 .queue('fx', function() { elem
.dequeue(); })
11503 * jQuery UI Effects Scale 1.8.21
11505 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11506 * Dual licensed under the MIT or GPL Version 2 licenses.
11507 * http://jquery.org/license
11509 * http://docs.jquery.com/UI/Effects/Scale
11512 * jquery.effects.core.js
11514 (function( $, undefined ) {
11516 $.effects
.puff = function(o
) {
11517 return this.queue(function() {
11518 var elem
= $(this),
11519 mode
= $.effects
.setMode(elem
, o
.options
.mode
|| 'hide'),
11520 percent
= parseInt(o
.options
.percent
, 10) || 150,
11521 factor
= percent
/ 100,
11522 original
= { height
: elem
.height(), width
: elem
.width() };
11524 $.extend(o
.options
, {
11527 percent
: mode
== 'hide' ? percent
: 100,
11528 from: mode
== 'hide'
11531 height
: original
.height
* factor
,
11532 width
: original
.width
* factor
11536 elem
.effect('scale', o
.options
, o
.duration
, o
.callback
);
11541 $.effects
.scale = function(o
) {
11543 return this.queue(function() {
11549 var options
= $.extend(true, {}, o
.options
);
11550 var mode
= $.effects
.setMode(el
, o
.options
.mode
|| 'effect'); // Set Mode
11551 var percent
= parseInt(o
.options
.percent
,10) || (parseInt(o
.options
.percent
,10) == 0 ? 0 : (mode
== 'hide' ? 0 : 100)); // Set default scaling percent
11552 var direction
= o
.options
.direction
|| 'both'; // Set default axis
11553 var origin
= o
.options
.origin
; // The origin of the scaling
11554 if (mode
!= 'effect') { // Set default origin and restore for show/hide
11555 options
.origin
= origin
|| ['middle','center'];
11556 options
.restore
= true;
11558 var original
= {height
: el
.height(), width
: el
.width()}; // Save original
11559 el
.from = o
.options
.from || (mode
== 'show' ? {height
: 0, width
: 0} : original
); // Default from state
11562 var factor
= { // Set scaling factor
11563 y
: direction
!= 'horizontal' ? (percent
/ 100) : 1,
11564 x
: direction
!= 'vertical' ? (percent
/ 100) : 1
11566 el
.to
= {height
: original
.height
* factor
.y
, width
: original
.width
* factor
.x
}; // Set to state
11568 if (o
.options
.fade
) { // Fade option to support puff
11569 if (mode
== 'show') {el
.from.opacity
= 0; el
.to
.opacity
= 1;};
11570 if (mode
== 'hide') {el
.from.opacity
= 1; el
.to
.opacity
= 0;};
11574 options
.from = el
.from; options
.to
= el
.to
; options
.mode
= mode
;
11577 el
.effect('size', options
, o
.duration
, o
.callback
);
11583 $.effects
.size = function(o
) {
11585 return this.queue(function() {
11588 var el
= $(this), props
= ['position','top','bottom','left','right','width','height','overflow','opacity'];
11589 var props1
= ['position','top','bottom','left','right','overflow','opacity']; // Always restore
11590 var props2
= ['width','height','overflow']; // Copy for children
11591 var cProps
= ['fontSize'];
11592 var vProps
= ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom'];
11593 var hProps
= ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight'];
11596 var mode
= $.effects
.setMode(el
, o
.options
.mode
|| 'effect'); // Set Mode
11597 var restore
= o
.options
.restore
|| false; // Default restore
11598 var scale
= o
.options
.scale
|| 'both'; // Default scale mode
11599 var origin
= o
.options
.origin
; // The origin of the sizing
11600 var original
= {height
: el
.height(), width
: el
.width()}; // Save original
11601 el
.from = o
.options
.from || original
; // Default from state
11602 el
.to
= o
.options
.to
|| original
; // Default to state
11604 if (origin
) { // Calculate baseline shifts
11605 var baseline
= $.effects
.getBaseline(origin
, original
);
11606 el
.from.top
= (original
.height
- el
.from.height
) * baseline
.y
;
11607 el
.from.left
= (original
.width
- el
.from.width
) * baseline
.x
;
11608 el
.to
.top
= (original
.height
- el
.to
.height
) * baseline
.y
;
11609 el
.to
.left
= (original
.width
- el
.to
.width
) * baseline
.x
;
11611 var factor
= { // Set scaling factor
11612 from: {y
: el
.from.height
/ original
.height
, x
: el
.from.width
/ original
.width
},
11613 to
: {y
: el
.to
.height
/ original
.height
, x
: el
.to
.width
/ original
.width
}
11615 if (scale
== 'box' || scale
== 'both') { // Scale the css box
11616 if (factor
.from.y
!= factor
.to
.y
) { // Vertical props scaling
11617 props
= props
.concat(vProps
);
11618 el
.from = $.effects
.setTransition(el
, vProps
, factor
.from.y
, el
.from);
11619 el
.to
= $.effects
.setTransition(el
, vProps
, factor
.to
.y
, el
.to
);
11621 if (factor
.from.x
!= factor
.to
.x
) { // Horizontal props scaling
11622 props
= props
.concat(hProps
);
11623 el
.from = $.effects
.setTransition(el
, hProps
, factor
.from.x
, el
.from);
11624 el
.to
= $.effects
.setTransition(el
, hProps
, factor
.to
.x
, el
.to
);
11627 if (scale
== 'content' || scale
== 'both') { // Scale the content
11628 if (factor
.from.y
!= factor
.to
.y
) { // Vertical props scaling
11629 props
= props
.concat(cProps
);
11630 el
.from = $.effects
.setTransition(el
, cProps
, factor
.from.y
, el
.from);
11631 el
.to
= $.effects
.setTransition(el
, cProps
, factor
.to
.y
, el
.to
);
11634 $.effects
.save(el
, restore
? props
: props1
); el
.show(); // Save & Show
11635 $.effects
.createWrapper(el
); // Create Wrapper
11636 el
.css('overflow','hidden').css(el
.from); // Shift
11639 if (scale
== 'content' || scale
== 'both') { // Scale the children
11640 vProps
= vProps
.concat(['marginTop','marginBottom']).concat(cProps
); // Add margins/font-size
11641 hProps
= hProps
.concat(['marginLeft','marginRight']); // Add margins
11642 props2
= props
.concat(vProps
).concat(hProps
); // Concat
11643 el
.find("*[width]").each(function(){
11644 var child
= $(this);
11645 if (restore
) $.effects
.save(child
, props2
);
11646 var c_original
= {height
: child
.height(), width
: child
.width()}; // Save original
11647 child
.from = {height
: c_original
.height
* factor
.from.y
, width
: c_original
.width
* factor
.from.x
};
11648 child
.to
= {height
: c_original
.height
* factor
.to
.y
, width
: c_original
.width
* factor
.to
.x
};
11649 if (factor
.from.y
!= factor
.to
.y
) { // Vertical props scaling
11650 child
.from = $.effects
.setTransition(child
, vProps
, factor
.from.y
, child
.from);
11651 child
.to
= $.effects
.setTransition(child
, vProps
, factor
.to
.y
, child
.to
);
11653 if (factor
.from.x
!= factor
.to
.x
) { // Horizontal props scaling
11654 child
.from = $.effects
.setTransition(child
, hProps
, factor
.from.x
, child
.from);
11655 child
.to
= $.effects
.setTransition(child
, hProps
, factor
.to
.x
, child
.to
);
11657 child
.css(child
.from); // Shift children
11658 child
.animate(child
.to
, o
.duration
, o
.options
.easing
, function(){
11659 if (restore
) $.effects
.restore(child
, props2
); // Restore children
11660 }); // Animate children
11665 el
.animate(el
.to
, { queue
: false, duration
: o
.duration
, easing
: o
.options
.easing
, complete: function() {
11666 if (el
.to
.opacity
=== 0) {
11667 el
.css('opacity', el
.from.opacity
);
11669 if(mode
== 'hide') el
.hide(); // Hide
11670 $.effects
.restore(el
, restore
? props
: props1
); $.effects
.removeWrapper(el
); // Restore
11671 if(o
.callback
) o
.callback
.apply(this, arguments
); // Callback
11681 * jQuery UI Effects Shake 1.8.21
11683 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11684 * Dual licensed under the MIT or GPL Version 2 licenses.
11685 * http://jquery.org/license
11687 * http://docs.jquery.com/UI/Effects/Shake
11690 * jquery.effects.core.js
11692 (function( $, undefined ) {
11694 $.effects
.shake = function(o
) {
11696 return this.queue(function() {
11699 var el
= $(this), props
= ['position','top','bottom','left','right'];
11702 var mode
= $.effects
.setMode(el
, o
.options
.mode
|| 'effect'); // Set Mode
11703 var direction
= o
.options
.direction
|| 'left'; // Default direction
11704 var distance
= o
.options
.distance
|| 20; // Default distance
11705 var times
= o
.options
.times
|| 3; // Default # of times
11706 var speed
= o
.duration
|| o
.options
.duration
|| 140; // Default speed per shake
11709 $.effects
.save(el
, props
); el
.show(); // Save & Show
11710 $.effects
.createWrapper(el
); // Create Wrapper
11711 var ref
= (direction
== 'up' || direction
== 'down') ? 'top' : 'left';
11712 var motion
= (direction
== 'up' || direction
== 'left') ? 'pos' : 'neg';
11715 var animation
= {}, animation1
= {}, animation2
= {};
11716 animation
[ref
] = (motion
== 'pos' ? '-=' : '+=') + distance
;
11717 animation1
[ref
] = (motion
== 'pos' ? '+=' : '-=') + distance
* 2;
11718 animation2
[ref
] = (motion
== 'pos' ? '-=' : '+=') + distance
* 2;
11721 el
.animate(animation
, speed
, o
.options
.easing
);
11722 for (var i
= 1; i
< times
; i
++) { // Shakes
11723 el
.animate(animation1
, speed
, o
.options
.easing
).animate(animation2
, speed
, o
.options
.easing
);
11725 el
.animate(animation1
, speed
, o
.options
.easing
).
11726 animate(animation
, speed
/ 2, o
.options
.easing
, function(){ // Last shake
11727 $.effects
.restore(el
, props
); $.effects
.removeWrapper(el
); // Restore
11728 if(o
.callback
) o
.callback
.apply(this, arguments
); // Callback
11730 el
.queue('fx', function() { el
.dequeue(); });
11738 * jQuery UI Effects Slide 1.8.21
11740 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11741 * Dual licensed under the MIT or GPL Version 2 licenses.
11742 * http://jquery.org/license
11744 * http://docs.jquery.com/UI/Effects/Slide
11747 * jquery.effects.core.js
11749 (function( $, undefined ) {
11751 $.effects
.slide = function(o
) {
11753 return this.queue(function() {
11756 var el
= $(this), props
= ['position','top','bottom','left','right'];
11759 var mode
= $.effects
.setMode(el
, o
.options
.mode
|| 'show'); // Set Mode
11760 var direction
= o
.options
.direction
|| 'left'; // Default Direction
11763 $.effects
.save(el
, props
); el
.show(); // Save & Show
11764 $.effects
.createWrapper(el
).css({overflow
:'hidden'}); // Create Wrapper
11765 var ref
= (direction
== 'up' || direction
== 'down') ? 'top' : 'left';
11766 var motion
= (direction
== 'up' || direction
== 'left') ? 'pos' : 'neg';
11767 var distance
= o
.options
.distance
|| (ref
== 'top' ? el
.outerHeight({margin
:true}) : el
.outerWidth({margin
:true}));
11768 if (mode
== 'show') el
.css(ref
, motion
== 'pos' ? (isNaN(distance
) ? "-" + distance
: -distance
) : distance
); // Shift
11771 var animation
= {};
11772 animation
[ref
] = (mode
== 'show' ? (motion
== 'pos' ? '+=' : '-=') : (motion
== 'pos' ? '-=' : '+=')) + distance
;
11775 el
.animate(animation
, { queue
: false, duration
: o
.duration
, easing
: o
.options
.easing
, complete: function() {
11776 if(mode
== 'hide') el
.hide(); // Hide
11777 $.effects
.restore(el
, props
); $.effects
.removeWrapper(el
); // Restore
11778 if(o
.callback
) o
.callback
.apply(this, arguments
); // Callback
11788 * jQuery UI Effects Transfer 1.8.21
11790 * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
11791 * Dual licensed under the MIT or GPL Version 2 licenses.
11792 * http://jquery.org/license
11794 * http://docs.jquery.com/UI/Effects/Transfer
11797 * jquery.effects.core.js
11799 (function( $, undefined ) {
11801 $.effects
.transfer = function(o
) {
11802 return this.queue(function() {
11803 var elem
= $(this),
11804 target
= $(o
.options
.to
),
11805 endPosition
= target
.offset(),
11807 top
: endPosition
.top
,
11808 left
: endPosition
.left
,
11809 height
: target
.innerHeight(),
11810 width
: target
.innerWidth()
11812 startPosition
= elem
.offset(),
11813 transfer
= $('<div class="ui-effects-transfer"></div>')
11814 .appendTo(document
.body
)
11815 .addClass(o
.options
.className
)
11817 top
: startPosition
.top
,
11818 left
: startPosition
.left
,
11819 height
: elem
.innerHeight(),
11820 width
: elem
.innerWidth(),
11821 position
: 'absolute'
11823 .animate(animation
, o
.duration
, o
.options
.easing
, function() {
11825 (o
.callback
&& o
.callback
.apply(elem
[0], arguments
));