2009-11-26 04:02:39 +01:00
/ *
2010-03-11 03:29:07 +01:00
* jQuery UI Droppable 1.8 rc3
2009-11-26 04:02:39 +01:00
*
2010-03-11 03:29:07 +01:00
* Copyright ( c ) 2010 AUTHORS . txt ( http : //jqueryui.com/about)
2009-11-26 04:02:39 +01:00
* Dual licensed under the MIT ( MIT - LICENSE . txt )
* and GPL ( GPL - LICENSE . txt ) licenses .
2010-03-11 03:29:07 +01:00
*
2009-11-26 04:02:39 +01:00
* http : //docs.jquery.com/UI/Droppables
*
* Depends :
2010-03-11 03:29:07 +01:00
* jquery . ui . core . js
* jquery . ui . widget . js
* jquery . ui . mouse . js
* jquery . ui . draggable . js
2009-11-26 04:02:39 +01:00
* /
( function ( $ ) {
$ . widget ( "ui.droppable" , {
2010-03-11 03:29:07 +01:00
widgetEventPrefix : "drop" ,
options : {
accept : '*' ,
activeClass : false ,
addClasses : true ,
greedy : false ,
hoverClass : false ,
scope : 'default' ,
tolerance : 'intersect'
2009-11-26 04:02:39 +01:00
} ,
2010-03-11 03:29:07 +01:00
_create : function ( ) {
2009-11-26 04:02:39 +01:00
var o = this . options , accept = o . accept ;
this . isover = 0 ; this . isout = 1 ;
2010-03-11 03:29:07 +01:00
this . accept = $ . isFunction ( accept ) ? accept : function ( d ) {
2009-11-26 04:02:39 +01:00
return d . is ( accept ) ;
} ;
//Store the droppable's proportions
this . proportions = { width : this . element [ 0 ] . offsetWidth , height : this . element [ 0 ] . offsetHeight } ;
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
// Add the reference and positions to the manager
2010-03-11 03:29:07 +01:00
$ . ui . ddmanager . droppables [ o . scope ] = $ . ui . ddmanager . droppables [ o . scope ] || [ ] ;
$ . ui . ddmanager . droppables [ o . scope ] . push ( this ) ;
( o . addClasses && this . element . addClass ( "ui-droppable" ) ) ;
2009-11-26 04:02:39 +01:00
} ,
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
destroy : function ( ) {
var drop = $ . ui . ddmanager . droppables [ this . options . scope ] ;
for ( var i = 0 ; i < drop . length ; i ++ )
if ( drop [ i ] == this )
drop . splice ( i , 1 ) ;
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
this . element
2010-03-11 03:29:07 +01:00
. removeClass ( "ui-droppable ui-droppable-disabled" )
2009-11-26 04:02:39 +01:00
. removeData ( "droppable" )
. unbind ( ".droppable" ) ;
2010-03-11 03:29:07 +01:00
return this ;
2009-11-26 04:02:39 +01:00
} ,
2010-03-11 03:29:07 +01:00
_setOption : function ( key , value ) {
if ( key == 'accept' ) {
this . accept = $ . isFunction ( value ) ? value : function ( d ) {
return d . is ( value ) ;
} ;
}
$ . Widget . prototype . _setOption . apply ( this , arguments ) ;
} ,
_activate : function ( event ) {
var draggable = $ . ui . ddmanager . current ;
if ( this . options . activeClass ) this . element . addClass ( this . options . activeClass ) ;
( draggable && this . _trigger ( 'activate' , event , this . ui ( draggable ) ) ) ;
} ,
_deactivate : function ( event ) {
var draggable = $ . ui . ddmanager . current ;
if ( this . options . activeClass ) this . element . removeClass ( this . options . activeClass ) ;
( draggable && this . _trigger ( 'deactivate' , event , this . ui ( draggable ) ) ) ;
} ,
_over : function ( event ) {
2009-11-26 04:02:39 +01: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
2010-03-11 03:29:07 +01:00
if ( this . accept . call ( this . element [ 0 ] , ( draggable . currentItem || draggable . element ) ) ) {
if ( this . options . hoverClass ) this . element . addClass ( this . options . hoverClass ) ;
this . _trigger ( 'over' , event , this . ui ( draggable ) ) ;
2009-11-26 04:02:39 +01:00
}
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
} ,
2010-03-11 03:29:07 +01:00
_out : function ( event ) {
2009-11-26 04:02:39 +01: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
2010-03-11 03:29:07 +01:00
if ( this . accept . call ( this . element [ 0 ] , ( draggable . currentItem || draggable . element ) ) ) {
if ( this . options . hoverClass ) this . element . removeClass ( this . options . hoverClass ) ;
this . _trigger ( 'out' , event , this . ui ( draggable ) ) ;
2009-11-26 04:02:39 +01:00
}
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
} ,
2010-03-11 03:29:07 +01:00
_drop : function ( event , custom ) {
2009-11-26 04:02:39 +01: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
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
var childrenIntersection = false ;
this . element . find ( ":data(droppable)" ) . not ( ".ui-draggable-dragging" ) . each ( function ( ) {
var inst = $ . data ( this , 'droppable' ) ;
2010-03-11 03:29:07 +01:00
if (
inst . options . greedy
&& ! inst . options . disabled
&& inst . options . scope == draggable . options . scope
&& inst . accept . call ( inst . element [ 0 ] , ( draggable . currentItem || draggable . element ) )
&& $ . ui . intersect ( draggable , $ . extend ( inst , { offset : inst . element . offset ( ) } ) , inst . options . tolerance )
) { childrenIntersection = true ; return false ; }
2009-11-26 04:02:39 +01:00
} ) ;
if ( childrenIntersection ) return false ;
2010-03-11 03:29:07 +01:00
if ( this . accept . call ( this . element [ 0 ] , ( draggable . currentItem || draggable . element ) ) ) {
if ( this . options . activeClass ) this . element . removeClass ( this . options . activeClass ) ;
if ( this . options . hoverClass ) this . element . removeClass ( this . options . hoverClass ) ;
this . _trigger ( 'drop' , event , this . ui ( draggable ) ) ;
return this . element ;
2009-11-26 04:02:39 +01:00
}
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
return false ;
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
} ,
2010-03-11 03:29:07 +01:00
ui : function ( c ) {
return {
draggable : ( c . currentItem || c . element ) ,
helper : c . helper ,
position : c . position ,
offset : c . positionAbs
} ;
2009-11-26 04:02:39 +01:00
}
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
} ) ;
$ . extend ( $ . ui . droppable , {
2010-03-11 03:29:07 +01:00
version : "1.8rc3"
2009-11-26 04:02:39 +01:00
} ) ;
$ . ui . intersect = function ( draggable , droppable , toleranceMode ) {
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
if ( ! droppable . offset ) return false ;
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01: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 ;
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01: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' :
2010-03-11 03:29:07 +01: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 ;
2009-11-26 04:02:39 +01: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 ;
}
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
} ;
/ *
This manager tracks offsets of draggables and droppables
* /
$ . ui . ddmanager = {
current : null ,
droppables : { 'default' : [ ] } ,
2010-03-11 03:29:07 +01:00
prepareOffsets : function ( t , event ) {
var m = $ . ui . ddmanager . droppables [ t . options . scope ] || [ ] ;
var type = event ? event . type : null ; // workaround for #2317
var list = ( t . currentItem || t . element ) . find ( ":data(droppable)" ) . andSelf ( ) ;
2009-11-26 04:02:39 +01:00
droppablesLoop : for ( var i = 0 ; i < m . length ; i ++ ) {
2010-03-11 03:29:07 +01:00
if ( m [ i ] . options . disabled || ( t && ! m [ i ] . accept . call ( m [ i ] . element [ 0 ] , ( t . currentItem || t . element ) ) ) ) continue ; //No disabled and non-accepted
2009-11-26 04:02:39 +01: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
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
m [ i ] . offset = m [ i ] . element . offset ( ) ;
m [ i ] . proportions = { width : m [ i ] . element [ 0 ] . offsetWidth , height : m [ i ] . element [ 0 ] . offsetHeight } ;
2010-03-11 03:29:07 +01:00
if ( type == "mousedown" ) m [ i ] . _activate . call ( m [ i ] , event ) ; //Activate the droppable if used directly from draggables
2009-11-26 04:02:39 +01:00
}
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
} ,
2010-03-11 03:29:07 +01:00
drop : function ( draggable , event ) {
2009-11-26 04:02:39 +01:00
var dropped = false ;
2010-03-11 03:29:07 +01:00
$ . each ( $ . ui . ddmanager . droppables [ draggable . options . scope ] || [ ] , function ( ) {
2009-11-26 04:02:39 +01:00
if ( ! this . options ) return ;
if ( ! this . options . disabled && this . visible && $ . ui . intersect ( draggable , this , this . options . tolerance ) )
2010-03-11 03:29:07 +01:00
dropped = dropped || this . _drop . call ( this , event ) ;
if ( ! this . options . disabled && this . visible && this . accept . call ( this . element [ 0 ] , ( draggable . currentItem || draggable . element ) ) ) {
2009-11-26 04:02:39 +01:00
this . isout = 1 ; this . isover = 0 ;
2010-03-11 03:29:07 +01:00
this . _deactivate . call ( this , event ) ;
2009-11-26 04:02:39 +01:00
}
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
} ) ;
return dropped ;
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
} ,
2010-03-11 03:29:07 +01:00
drag : function ( draggable , event ) {
2009-11-26 04:02:39 +01:00
//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2010-03-11 03:29:07 +01:00
if ( draggable . options . refreshPositions ) $ . ui . ddmanager . prepareOffsets ( draggable , event ) ;
2009-11-26 04:02:39 +01:00
//Run through all droppables and check their positions based on specific tolerance options
2010-03-11 03:29:07 +01:00
$ . each ( $ . ui . ddmanager . droppables [ draggable . options . scope ] || [ ] , function ( ) {
2009-11-26 04:02:39 +01:00
if ( this . options . disabled || this . greedyChild || ! this . visible ) return ;
var intersects = $ . ui . intersect ( draggable , this , this . options . tolerance ) ;
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
var c = ! intersects && this . isover == 1 ? 'isout' : ( intersects && this . isover == 0 ? 'isover' : null ) ;
if ( ! c ) return ;
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
var parentInstance ;
if ( this . options . greedy ) {
var parent = this . element . parents ( ':data(droppable):eq(0)' ) ;
if ( parent . length ) {
parentInstance = $ . data ( parent [ 0 ] , 'droppable' ) ;
parentInstance . greedyChild = ( c == 'isover' ? 1 : 0 ) ;
}
}
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
// we just moved into a greedy child
if ( parentInstance && c == 'isover' ) {
parentInstance [ 'isover' ] = 0 ;
parentInstance [ 'isout' ] = 1 ;
2010-03-11 03:29:07 +01:00
parentInstance . _out . call ( parentInstance , event ) ;
2009-11-26 04:02:39 +01:00
}
2010-03-11 03:29:07 +01:00
2009-11-26 04:02:39 +01:00
this [ c ] = 1 ; this [ c == 'isout' ? 'isover' : 'isout' ] = 0 ;
2010-03-11 03:29:07 +01:00
this [ c == "isover" ? "_over" : "_out" ] . call ( this , event ) ;
2009-11-26 04:02:39 +01:00
// we just moved out of a greedy child
if ( parentInstance && c == 'isout' ) {
parentInstance [ 'isout' ] = 0 ;
parentInstance [ 'isover' ] = 1 ;
2010-03-11 03:29:07 +01:00
parentInstance . _over . call ( parentInstance , event ) ;
2009-11-26 04:02:39 +01:00
}
} ) ;
}
2010-03-11 03:29:07 +01:00
} ;
2009-11-26 04:02:39 +01:00
} ) ( jQuery ) ;