2008-06-04 02:34:33 +00:00
/ *
2008-09-04 22:03:30 +00:00
* jQuery UI Droppable @ VERSION
2008-06-04 02:34:33 +00:00
*
2009-01-03 21:55:13 +00:00
* Copyright ( c ) 2009 AUTHORS . txt ( http : //ui.jquery.com/about)
2008-06-04 02:34:33 +00:00
* Dual licensed under the MIT ( MIT - LICENSE . txt )
* and GPL ( GPL - LICENSE . txt ) licenses .
2008-11-20 04:10:34 +00:00
*
2008-06-04 02:34:33 +00:00
* http : //docs.jquery.com/UI/Droppables
*
* Depends :
* ui . core . js
* ui . draggable . js
* /
2008-06-05 12:14:12 +00:00
( function ( $ ) {
2008-06-04 02:34:33 +00:00
$ . widget ( "ui.droppable" , {
2008-11-18 02:55:25 +00:00
2008-08-17 02:15:55 +00:00
_init : function ( ) {
2008-11-18 02:55:25 +00:00
2008-07-14 15:55:33 +00:00
var o = this . options , accept = o . accept ;
2008-06-04 02:34:33 +00:00
this . isover = 0 ; this . isout = 1 ;
2008-11-18 02:55:25 +00:00
2008-09-16 09:03:28 +00:00
this . options . accept = this . options . accept && $ . isFunction ( this . options . accept ) ? this . options . accept : function ( d ) {
2008-07-14 14:21:07 +00:00
return d . is ( accept ) ;
} ;
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
//Store the droppable's proportions
2008-07-02 17:38:34 +00:00
this . proportions = { width : this . element [ 0 ] . offsetWidth , height : this . element [ 0 ] . offsetHeight } ;
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
// Add the reference and positions to the manager
2008-07-28 18:34:01 +00:00
$ . ui . ddmanager . droppables [ this . options . scope ] = $ . ui . ddmanager . droppables [ this . options . scope ] || [ ] ;
$ . ui . ddmanager . droppables [ this . options . scope ] . push ( this ) ;
2008-11-18 02:55:25 +00:00
2008-07-28 21:06:04 +00:00
( this . options . cssNamespace && this . element . addClass ( this . options . cssNamespace + "-droppable" ) ) ;
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
} ,
2008-11-21 04:01:33 +00:00
2008-06-04 02:34:33 +00:00
destroy : function ( ) {
2008-07-28 18:34:01 +00:00
var drop = $ . ui . ddmanager . droppables [ this . options . scope ] ;
2008-06-04 02:34:33 +00:00
for ( var i = 0 ; i < drop . length ; i ++ )
if ( drop [ i ] == this )
drop . splice ( i , 1 ) ;
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
this . element
2009-01-07 17:43:15 +00:00
. removeClass ( this . options . cssNamespace + "-droppable " + this . options . cssNamespace + "-droppable-disabled" )
2009-01-16 02:09:45 +00:00
. removeData ( "droppable" )
. unbind ( ".droppable" ) ;
2008-06-04 02:34:33 +00:00
} ,
2008-11-21 04:01:33 +00:00
_setData : function ( key , value ) {
if ( key == 'accept' ) {
this . options . accept = value && $ . isFunction ( value ) ? value : function ( d ) {
return d . is ( accept ) ;
} ;
} else {
$ . widget . prototype . _setData . apply ( this , arguments ) ;
}
} ,
_activate : function ( event ) {
var draggable = $ . ui . ddmanager . current ;
2009-01-16 18:35:04 +00:00
if ( this . options . activeClass ) this . element . addClass ( this . options . activeClass ) ;
2009-01-03 15:30:23 +00:00
( draggable && this . _trigger ( 'activate' , event , this . ui ( draggable ) ) ) ;
2008-11-21 04:01:33 +00:00
} ,
_deactivate : function ( event ) {
var draggable = $ . ui . ddmanager . current ;
2009-01-16 18:35:04 +00:00
if ( this . options . activeClass ) this . element . removeClass ( this . options . activeClass ) ;
2009-01-03 15:30:23 +00:00
( draggable && this . _trigger ( 'deactivate' , event , this . ui ( draggable ) ) ) ;
2008-11-21 04:01:33 +00:00
} ,
2008-11-14 03:00:16 +00:00
_over : function ( event ) {
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
var draggable = $ . ui . ddmanager . current ;
if ( ! draggable || ( draggable . currentItem || draggable . element ) [ 0 ] == this . element [ 0 ] ) return ; // Bail if draggable and droppable are same element
2008-11-18 02:55:25 +00:00
2009-01-27 14:58:05 +00:00
if ( this . options . accept . call ( this . element [ 0 ] , ( draggable . currentItem || draggable . element ) ) ) {
2009-01-16 18:35:04 +00:00
if ( this . options . hoverClass ) this . element . addClass ( this . options . hoverClass ) ;
2009-01-03 15:30:23 +00:00
this . _trigger ( 'over' , event , this . ui ( draggable ) ) ;
2008-06-04 02:34:33 +00:00
}
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
} ,
2008-11-21 04:01:33 +00:00
2008-11-14 03:00:16 +00:00
_out : function ( event ) {
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
var draggable = $ . ui . ddmanager . current ;
if ( ! draggable || ( draggable . currentItem || draggable . element ) [ 0 ] == this . element [ 0 ] ) return ; // Bail if draggable and droppable are same element
2008-11-18 02:55:25 +00:00
2009-01-27 14:58:05 +00:00
if ( this . options . accept . call ( this . element [ 0 ] , ( draggable . currentItem || draggable . element ) ) ) {
2009-01-16 18:35:04 +00:00
if ( this . options . hoverClass ) this . element . removeClass ( this . options . hoverClass ) ;
2009-01-03 15:30:23 +00:00
this . _trigger ( 'out' , event , this . ui ( draggable ) ) ;
2008-06-04 02:34:33 +00:00
}
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
} ,
2008-11-21 04:01:33 +00:00
2008-11-14 03:00:16 +00:00
_drop : function ( event , custom ) {
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
var draggable = custom || $ . ui . ddmanager . current ;
if ( ! draggable || ( draggable . currentItem || draggable . element ) [ 0 ] == this . element [ 0 ] ) return false ; // Bail if draggable and droppable are same element
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
var childrenIntersection = false ;
2009-01-16 02:09:45 +00:00
this . element . find ( ":data(droppable)" ) . not ( "." + draggable . options . cssNamespace + "-draggable-dragging" ) . each ( function ( ) {
var inst = $ . data ( this , 'droppable' ) ;
2008-06-04 02:34:33 +00:00
if ( inst . options . greedy && $ . ui . intersect ( draggable , $ . extend ( inst , { offset : inst . element . offset ( ) } ) , inst . options . tolerance ) ) {
childrenIntersection = true ; return false ;
}
} ) ;
if ( childrenIntersection ) return false ;
2008-11-18 02:55:25 +00:00
2009-01-27 14:58:05 +00:00
if ( this . options . accept . call ( this . element [ 0 ] , ( draggable . currentItem || draggable . element ) ) ) {
2009-01-16 18:35:04 +00:00
if ( this . options . activeClass ) this . element . removeClass ( this . options . activeClass ) ;
if ( this . options . hoverClass ) this . element . removeClass ( this . options . hoverClass ) ;
2009-01-03 15:30:23 +00:00
this . _trigger ( 'drop' , event , this . ui ( draggable ) ) ;
2008-09-18 09:51:50 +00:00
return this . element ;
2008-06-04 02:34:33 +00:00
}
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
return false ;
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
} ,
2008-11-18 02:55:25 +00:00
2008-11-21 04:01:33 +00:00
ui : function ( c ) {
return {
draggable : ( c . currentItem || c . element ) ,
helper : c . helper ,
position : c . position ,
2009-01-29 12:35:38 +00:00
absolutePosition : c . positionAbs , //deprecated
offset : c . positionAbs
2008-11-21 04:01:33 +00:00
} ;
2008-06-04 02:34:33 +00:00
}
2008-11-21 04:01:33 +00:00
2008-06-04 02:34:33 +00:00
} ) ;
$ . extend ( $ . ui . droppable , {
2008-10-05 16:29:21 +00:00
version : "@VERSION" ,
2009-01-03 15:30:23 +00:00
eventPrefix : 'drop' ,
2008-06-04 02:34:33 +00:00
defaults : {
2008-12-30 13:14:29 +00:00
accept : '*' ,
2009-01-20 13:10:11 +00:00
activeClass : false ,
2008-11-08 21:56:57 +00:00
cssNamespace : 'ui' ,
greedy : false ,
2009-01-20 13:10:11 +00:00
hoverClass : false ,
2008-07-28 21:06:04 +00:00
scope : 'default' ,
2008-11-08 21:56:57 +00:00
tolerance : 'intersect'
2008-06-04 02:34:33 +00:00
}
} ) ;
$ . ui . intersect = function ( draggable , droppable , toleranceMode ) {
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
if ( ! droppable . offset ) return false ;
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
var x1 = ( draggable . positionAbs || draggable . position . absolute ) . left , x2 = x1 + draggable . helperProportions . width ,
y1 = ( draggable . positionAbs || draggable . position . absolute ) . top , y2 = y1 + draggable . helperProportions . height ;
var l = droppable . offset . left , r = l + droppable . proportions . width ,
t = droppable . offset . top , b = t + droppable . proportions . height ;
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
switch ( toleranceMode ) {
case 'fit' :
return ( l < x1 && x2 < r
&& t < y1 && y2 < b ) ;
break ;
case 'intersect' :
return ( l < x1 + ( draggable . helperProportions . width / 2 ) // Right Half
&& x2 - ( draggable . helperProportions . width / 2 ) < r // Left Half
&& t < y1 + ( draggable . helperProportions . height / 2 ) // Bottom Half
&& y2 - ( draggable . helperProportions . height / 2 ) < b ) ; // Top Half
break ;
case 'pointer' :
2008-11-10 06:39:52 +00:00
var draggableLeft = ( ( draggable . positionAbs || draggable . position . absolute ) . left + ( draggable . clickOffset || draggable . offset . click ) . left ) ,
draggableTop = ( ( draggable . positionAbs || draggable . position . absolute ) . top + ( draggable . clickOffset || draggable . offset . click ) . top ) ,
isOver = $ . ui . isOver ( draggableTop , draggableLeft , t , l , droppable . proportions . height , droppable . proportions . width ) ;
return isOver ;
2008-06-04 02:34:33 +00:00
break ;
case 'touch' :
return (
( y1 >= t && y1 <= b ) || // Top edge touching
( y2 >= t && y2 <= b ) || // Bottom edge touching
( y1 < t && y2 > b ) // Surrounded vertically
) && (
( x1 >= l && x1 <= r ) || // Left edge touching
( x2 >= l && x2 <= r ) || // Right edge touching
( x1 < l && x2 > r ) // Surrounded horizontally
) ;
break ;
default :
return false ;
break ;
}
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
} ;
/ *
This manager tracks offsets of draggables and droppables
* /
$ . ui . ddmanager = {
current : null ,
2008-07-28 21:06:04 +00:00
droppables : { 'default' : [ ] } ,
2008-11-14 03:00:16 +00:00
prepareOffsets : function ( t , event ) {
2009-01-16 02:09:45 +00:00
2008-07-28 18:34:01 +00:00
var m = $ . ui . ddmanager . droppables [ t . options . scope ] ;
2008-11-14 03:00:16 +00:00
var type = event ? event . type : null ; // workaround for #2317
2009-01-16 02:09:45 +00:00
var list = ( t . currentItem || t . element ) . find ( ":data(droppable)" ) . andSelf ( ) ;
2008-11-18 02:55:25 +00:00
2008-07-28 18:34:01 +00:00
droppablesLoop : for ( var i = 0 ; i < m . length ; i ++ ) {
2008-11-18 02:55:25 +00:00
2009-01-27 14:58:05 +00:00
if ( m [ i ] . options . disabled || ( t && ! m [ i ] . options . accept . call ( m [ i ] . element [ 0 ] , ( t . currentItem || t . element ) ) ) ) continue ; //No disabled and non-accepted
2008-07-28 18:34:01 +00:00
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
m [ i ] . visible = m [ i ] . element . css ( "display" ) != "none" ; if ( ! m [ i ] . visible ) continue ; //If the element is not visible, continue
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
m [ i ] . offset = m [ i ] . element . offset ( ) ;
2008-07-02 17:38:34 +00:00
m [ i ] . proportions = { width : m [ i ] . element [ 0 ] . offsetWidth , height : m [ i ] . element [ 0 ] . offsetHeight } ;
2008-11-18 02:55:25 +00:00
2009-01-16 20:41:03 +00:00
if ( type == "mousedown" ) m [ i ] . _activate . call ( m [ i ] , event ) ; //Activate the droppable if used directly from draggables
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
}
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
} ,
2008-11-14 03:00:16 +00:00
drop : function ( draggable , event ) {
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
var dropped = false ;
2008-07-28 18:34:01 +00:00
$ . each ( $ . ui . ddmanager . droppables [ draggable . options . scope ] , function ( ) {
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
if ( ! this . options ) return ;
if ( ! this . options . disabled && this . visible && $ . ui . intersect ( draggable , this , this . options . tolerance ) )
2008-11-14 03:00:16 +00:00
dropped = this . _drop . call ( this , event ) ;
2008-11-18 02:55:25 +00:00
2009-01-27 14:58:05 +00:00
if ( ! this . options . disabled && this . visible && this . options . accept . call ( this . element [ 0 ] , ( draggable . currentItem || draggable . element ) ) ) {
2008-06-04 02:34:33 +00:00
this . isout = 1 ; this . isover = 0 ;
2008-11-14 03:00:16 +00:00
this . _deactivate . call ( this , event ) ;
2008-06-04 02:34:33 +00:00
}
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
} ) ;
return dropped ;
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
} ,
2008-11-14 03:00:16 +00:00
drag : function ( draggable , event ) {
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2008-11-14 03:00:16 +00:00
if ( draggable . options . refreshPositions ) $ . ui . ddmanager . prepareOffsets ( draggable , event ) ;
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
//Run through all droppables and check their positions based on specific tolerance options
2008-11-18 02:55:25 +00:00
2008-07-28 18:34:01 +00:00
$ . each ( $ . ui . ddmanager . droppables [ draggable . options . scope ] , function ( ) {
2008-11-18 02:55:25 +00:00
2008-06-26 10:49:47 +00:00
if ( this . options . disabled || this . greedyChild || ! this . visible ) return ;
2008-06-04 02:34:33 +00:00
var intersects = $ . ui . intersect ( draggable , this , this . options . tolerance ) ;
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
var c = ! intersects && this . isover == 1 ? 'isout' : ( intersects && this . isover == 0 ? 'isover' : null ) ;
if ( ! c ) return ;
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
var parentInstance ;
if ( this . options . greedy ) {
2009-01-16 02:09:45 +00:00
var parent = this . element . parents ( ':data(droppable):eq(0)' ) ;
2008-06-04 02:34:33 +00:00
if ( parent . length ) {
2009-01-16 02:09:45 +00:00
parentInstance = $ . data ( parent [ 0 ] , 'droppable' ) ;
2008-06-04 02:34:33 +00:00
parentInstance . greedyChild = ( c == 'isover' ? 1 : 0 ) ;
}
}
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
// we just moved into a greedy child
if ( parentInstance && c == 'isover' ) {
parentInstance [ 'isover' ] = 0 ;
parentInstance [ 'isout' ] = 1 ;
2008-11-14 03:00:16 +00:00
parentInstance . _out . call ( parentInstance , event ) ;
2008-06-04 02:34:33 +00:00
}
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
this [ c ] = 1 ; this [ c == 'isout' ? 'isover' : 'isout' ] = 0 ;
2008-11-14 03:00:16 +00:00
this [ c == "isover" ? "_over" : "_out" ] . call ( this , event ) ;
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
// we just moved out of a greedy child
if ( parentInstance && c == 'isout' ) {
parentInstance [ 'isout' ] = 0 ;
parentInstance [ 'isover' ] = 1 ;
2008-11-14 03:00:16 +00:00
parentInstance . _over . call ( parentInstance , event ) ;
2008-06-04 02:34:33 +00:00
}
} ) ;
2008-11-18 02:55:25 +00:00
2008-06-04 02:34:33 +00:00
}
} ;
} ) ( jQuery ) ;