//------------------------------------------------------------------------------ // IPS JS: Drag Move // (c) 2005 Invision Power Services, Inc. // http://www.invisionpower.com // Matt Mecham (27/07/05) //------------------------------------------------------------------------------ var drag_move = new dragmove(); /*-------------------------------------------------------------------------*/ // Initiate object /*-------------------------------------------------------------------------*/ function dragmove() { /* * Portion of ID name without "-{id}" for * drag handles (object which initiates drag) * * @var string */ this.var_drag_handle_id_text = null; /* * URL to redirect to after change * * @var string */ this.var_bounce_url = null; /* * Portion of ID name without "-{id}" for * hidden drag elements. These are HTML * blobs which actually get made visible * and are dragged. * * @var string */ this.var_drag_draggable_id_text = null; /* * Portion of ID name without "-{id}" for * drag objects (the actual drag container) * * @var string */ this.var_drag_object_id_text = null; /* * Portion of ID name for the * row which is altered when the drag is * started AND a TARGET copy is created * over it when dragging started * * @var string */ this.var_original_row_text = null; /* * Current dragged ID * * @var integer */ this.current_id = null; /* * Drag in progress * * @var integer */ this._drag_in_progress = null; /** * Target IDs (Populated in DHTML) * Must be in the format as follows: * * * @var array */ this.var_target_ids = new Array(); /** * Parent IDs (Populated in DHTML) * Must be in the format as follows: * * * @var array */ this.var_parent_ids = new Array(); /** * Process parent IDs? * Turn off to not restrict actions * based on parents * * @var boolean */ this.var_parent_process = 1; /* * CSS classname of layer that is * drawn above the row when a move * is started * * @var string */ this.var_hide_row_classname = 'dragmove-hide'; /* * CSS classname of target mouseover * * @var string */ this.var_target_over_classname = 'tablerow3'; /* * CSS classname of target mouseout * * @var string */ this.var_target_out_classname = 'tablerow2'; /* * ID of target over * set by mouseover. cleared by mouseout * * @var string */ this.var_target_over_id = null; /* * URL of Ajax request * * @var string */ this.var_ajax_url = null; /* * Array of FAKE TARGETS * * @var array */ this._TARGETS = new Array(); /* * Array of FAKE TARGETS DImensions * * @var array */ this.dims = new Array(); /* * Array of unmoveable objects * * @var array */ this.UNMOVEABLES = new Array(); /* * ID of "Unmoveable" alert object * * @var array */ this.UNMOVEABLES_id = 'dragmove-unmoveable'; /* * Array of ALL parent ids for a certain ID * Traversing up the parent tree * * var @array */ this.parent_id_tree = new Array(); /* * Array of ALL children ids for a certain ID * Traversing up the parent tree * * var @array */ this.child_id_tree = new Array(); /* * Array of ALL children ids / parent * structure * * var @array */ this.child_id_array = new Array(); }; /*-------------------------------------------------------------------------*/ // Initiate draggable objects /*-------------------------------------------------------------------------*/ dragmove.prototype.drag_init = function() { //---------------------------------- // Get page links... // Gah.. another safari bug //---------------------------------- var draghandles = document.getElementsByTagName('*'); //---------------------------------- // Sort through and grab topic links //---------------------------------- for ( var i = 0 ; i <= draghandles.length ; i++ ) { try { if ( ! draghandles[i].id ) { continue; } } catch(e) { continue; } var linkid = draghandles[i].id; var linkname = linkid.replace( /^(.*)-(\d+)$/, "$1" ); var thisid = this.get_id_from_text( draghandles[i].id ); //---------------------------------- // SET UP DRAG HANDLES //---------------------------------- if ( linkname == this.var_drag_handle_id_text ) { var drag_main_obj = document.getElementById( this.var_drag_draggable_id_text + '-' + thisid ); var drag_handle_obj = document.getElementById( this.var_drag_handle_id_text + '-' + thisid ); draghandles[i].style.cursor = "move"; Drag.init( drag_handle_obj, drag_main_obj ); drag_main_obj.onDrag = function(x, y, e) { dragmove_events.prototype.event_drag_ging( x, y, e ); }; drag_main_obj.onDragStart = function(x, y, e) { dragmove_events.prototype.event_drag_start( x, y, e ); }; drag_main_obj.onDragEnd = function(x, y, e) { dragmove_events.prototype.event_drag_end( x, y, e ); }; //---------------------------------- // This has to be after Drag.init // to replace mouseover handler //---------------------------------- drag_handle_obj.onmouseover = dragmove_events.prototype.event_mouseover; drag_handle_obj.onmouseout = dragmove_events.prototype.event_mouseout; } } //---------------------------------- // Create child / parent structure //---------------------------------- if ( this.var_parent_ids.length ) { for( var i in this.var_parent_ids ) { if ( ! this.child_id_array[ this.var_parent_ids[i] ] ) { this.child_id_array[ this.var_parent_ids[i] ] = new Array(); } this.child_id_array[ this.var_parent_ids[i] ][ this.child_id_array[ this.var_parent_ids[i] ].length ] = i; } } }; /*-------------------------------------------------------------------------*/ // Add ID to UNMOVEABLES array /*-------------------------------------------------------------------------*/ dragmove.prototype.get_parents_array = function( root_tid ) { if ( this.var_parent_ids[ root_tid ] ) { this.parent_id_tree[ this.parent_id_tree.length ] = this.var_parent_ids[ root_tid ]; this.get_parents_array( this.var_parent_ids[ root_tid ] ); } }; /*-------------------------------------------------------------------------*/ // Add ID to UNMOVEABLES array /*-------------------------------------------------------------------------*/ dragmove.prototype.get_children_array = function( root_tid ) { if ( this.child_id_array[ root_tid ] ) { for( var i in this.child_id_array[ root_tid ] ) { this.child_id_tree[ this.child_id_tree.length ] = this.child_id_array[ root_tid ][i]; this.get_children_array( this.child_id_array[ root_tid ][i] ); } } }; /*-------------------------------------------------------------------------*/ // Add ID to UNMOVEABLES array /*-------------------------------------------------------------------------*/ dragmove.prototype.add_id_to_unmoveables = function( tid ) { this.UNMOVEABLES[ tid ] = tid; }; /*-------------------------------------------------------------------------*/ // Add ID to target array /*-------------------------------------------------------------------------*/ dragmove.prototype.add_id_to_targets = function( tid ) { this.var_target_ids[ tid ] = 1; }; /*-------------------------------------------------------------------------*/ // Add ID to target array /*-------------------------------------------------------------------------*/ dragmove.prototype.add_id_to_parents = function( tid, parent_id ) { this.var_parent_ids[ tid ] = parent_id == 'root' ? 0 : parseInt(parent_id); }; /*--------------------------------------------*/ // Get TID from ID /*--------------------------------------------*/ dragmove.prototype.get_id_from_text = function( id ) { return id.replace( /.*\-(\d+)/, "$1" ); }; /*-------------------------------------------------------------------------*/ // Initiate events object /*-------------------------------------------------------------------------*/ function dragmove_events() { }; /*-------------------------------------------------------------------------*/ // TARGET EVENT: Mouseover /*-------------------------------------------------------------------------*/ dragmove_events.prototype.event_TARGET_mouseover = function(e) { //------------------------------- // Already over a target //------------------------------- if ( drag_move.var_target_over_id ) { return false; } //------------------------------- // Not dragging? //------------------------------- if ( ! drag_move._drag_in_progress ) { return false; } //------------------------------- // No? Get one then //------------------------------- drag_move.var_target_over_id = drag_move.get_id_from_text( this.id ); //------------------------------- // Can we actually mouse over this? // Check parents to make sure we're not // trying to move a child into its existing // parent. Also don't allow to drop over // oneself //------------------------------- if ( drag_move.var_parent_process && drag_move.current_id ) { //------------------------------- // Move into self //------------------------------- if ( drag_move.var_target_over_id == drag_move.current_id ) { //------------------------------- // Yeah.. so don't do anything //------------------------------- drag_move.var_target_over_id = null; return false; } //------------------------------- // Move into current parent //------------------------------- if ( drag_move.var_target_over_id == drag_move.var_parent_ids[ drag_move.current_id ] ) { //------------------------------- // Yeah.. so don't do anything //------------------------------- drag_move.var_target_over_id = null; return false; } //------------------------------- // Make sure we're not moving into // own parents //------------------------------- drag_move.child_id_tree = new Array(); drag_move.get_children_array( drag_move.current_id ); // Add in current ID drag_move.child_id_tree[ drag_move.child_id_tree.length ] = drag_move.current_id; for( var i in drag_move.child_id_tree ) { if ( drag_move.var_target_over_id == drag_move.child_id_tree[i] ) { //------------------------------- // Yeah.. so don't do anything //------------------------------- drag_move.var_target_over_id = null; return false; } } } var target_obj = document.getElementById( drag_move.var_original_row_text + '-' + drag_move.var_target_over_id ); //------------------------------- // Store old classname... //------------------------------- drag_move.var_target_out_classname = target_obj.className; //------------------------------- // Change classname... //------------------------------- target_obj.className = drag_move.var_target_over_classname; }; /*-------------------------------------------------------------------------*/ // TARGET EVENT: Mouseout /*-------------------------------------------------------------------------*/ dragmove_events.prototype.event_TARGET_mouseout = function(e) { //------------------------------- // Not touched a target? //------------------------------- if ( ! drag_move.var_target_over_id ) { return false; } //------------------------------- // Not dragging? //------------------------------- if ( ! drag_move._drag_in_progress ) { return false; } //------------------------------- // Get obj //------------------------------- var target_obj = document.getElementById( drag_move.var_original_row_text + '-' + drag_move.var_target_over_id ); //------------------------------- // Store old classname... //------------------------------- target_obj.className = drag_move.var_target_out_classname; //------------------------------- // Clear target ID //------------------------------- drag_move.var_target_over_id = null; }; /*-------------------------------------------------------------------------*/ // MAIN EVENT: Mouseover /*-------------------------------------------------------------------------*/ dragmove_events.prototype.event_mouseover = function(e) { //------------------------------- // Already dragging? //------------------------------- if ( drag_move.current_id ) { return false; } //------------------------------- // Unmoveable? //------------------------------- var check_for_id = drag_move.UNMOVEABLES[ drag_move.get_id_from_text( this.id ) ]; if ( check_for_id ) { var alert_object = null; //------------------------------- // Attempt to get DIV //------------------------------- try { alert_object = document.getElementById( drag_move.UNMOVEABLES_id ); } catch(error) { drag_move.UNMOVEABLES_id = null; } //------------------------------- // Yeah, so draw alert and return //------------------------------- if ( alert_object ) { var drag_root_obj = document.getElementById( drag_move.var_drag_handle_id_text + '-' + check_for_id ); alert_object.style.top = ipsclass.get_obj_toppos( drag_root_obj ) - 4 + 'px'; alert_object.style.left = ipsclass.get_obj_leftpos( drag_root_obj ) + 22 + 'px'; alert_object.style.position = 'absolute'; alert_object.style.display = ''; } return false; } //------------------------------- // No? Get one then //------------------------------- drag_move.current_id = drag_move.get_id_from_text( this.id ); }; /*-------------------------------------------------------------------------*/ // MAIN EVENT: Mouseout /*-------------------------------------------------------------------------*/ dragmove_events.prototype.event_mouseout = function(e) { //------------------------------- // Unmoveable? //------------------------------- var check_for_id = drag_move.UNMOVEABLES[ drag_move.get_id_from_text( this.id ) ]; if ( check_for_id ) { var alert_object = null; //------------------------------- // Attempt to get DIV //------------------------------- try { alert_object = document.getElementById( drag_move.UNMOVEABLES_id ); } catch(error) { drag_move.UNMOVEABLES_id = null; } //------------------------------- // Yeah, so draw alert and return //------------------------------- if ( alert_object ) { alert_object.style.display = 'none'; } return false; } //------------------------------- // Release current drag ID // only if a drag is not in // progress //------------------------------- if ( ! drag_move._drag_in_progress ) { drag_move.current_id = null; } }; /*-------------------------------------------------------------------------*/ // DRAG EVENT: DRAG IN PROGRESS (No, not men in dresses) /*-------------------------------------------------------------------------*/ dragmove_events.prototype.event_drag_ging = function( x, y ) { if ( is_ie ) { var bingo = 0; if ( drag_move.var_target_ids.length ) { for ( var i in drag_move.var_target_ids ) { if ( x >= drag_move.dims[ i ]['x1'] && x <= drag_move.dims[ i ]['x2'] && y >= drag_move.dims[ i ]['y1'] && y <= drag_move.dims[ i ]['y2'] ) { bingo = 1; this.id = i; dragmove_events.prototype.event_TARGET_mouseover(); break; } } } if ( ! bingo ) { dragmove_events.prototype.event_TARGET_mouseout(); } } }; /*-------------------------------------------------------------------------*/ // DRAG START: Gentlemen, start your dresses! /*-------------------------------------------------------------------------*/ dragmove_events.prototype.event_drag_start = function( x, y ) { //------------------------------- // Time for hidden div to make // a showing... //------------------------------- if ( drag_move.current_id ) { var drag_main_obj = document.getElementById( drag_move.var_drag_draggable_id_text + '-' + drag_move.current_id ); var drag_root_obj = document.getElementById( drag_move.var_drag_object_id_text + '-' + drag_move.current_id ); var drag_orig_obj = document.getElementById( drag_move.var_original_row_text + '-' + drag_move.current_id ); //------------------------------- // For some reason, Safari wants // to be relative.. //------------------------------- if ( is_safari ) { drag_root_obj.style.position = 'relative'; } drag_main_obj.style.top = ipsclass.get_obj_toppos( drag_root_obj ) + 'px'; drag_main_obj.style.left = ipsclass.get_obj_leftpos( drag_root_obj ) + 'px'; drag_main_obj.style.position = 'absolute'; drag_main_obj.style.display = 'block'; drag_main_obj.style.zIndex = 1000; //------------------------------- // Set up TARGETS //------------------------------- if ( drag_move.var_target_ids.length ) { for ( var i in drag_move.var_target_ids ) { var main_obj = document.getElementById( drag_move.var_original_row_text + '-' + i ); //------------------------------- // For some reason, Safari wants // to be relative.. //------------------------------- if ( is_safari ) { main_obj.style.position = 'relative'; } if ( is_ie ) { //------------------------------- // IE has problems with onmouseover // and zIndex.. couldn't resolve it // so cheated. slower, hence IE only // Gen co-ord maps of targets //------------------------------- drag_move.dims[ i ] = new Array(); drag_move.dims[ i ]['x1'] = ipsclass.get_obj_leftpos(main_obj); drag_move.dims[ i ]['x2'] = drag_move.dims[i]['x1'] + main_obj.offsetWidth; drag_move.dims[ i ]['y1'] = ipsclass.get_obj_toppos(main_obj) - 20; // We need to leave a gutter at the bottom / top of each target area to allow // the mouse out event to fire otherwise two targets together will show as one // big target drag_move.dims[ i ]['y2'] = drag_move.dims[i]['y1'] + main_obj.offsetHeight - 5; } else { var targetobj = document.createElement('div'); targetobj.id = drag_move.var_original_row_text + '-TARGET-' + i; targetobj.style.background = 'transparent'; targetobj.style.position = 'absolute'; targetobj.style.left = ipsclass.get_obj_leftpos(main_obj) + 'px'; targetobj.style.top = ipsclass.get_obj_toppos(main_obj) + 'px'; targetobj.style.width = main_obj.offsetWidth + 'px'; targetobj.style.height = main_obj.offsetHeight + 'px'; targetobj.style.zIndex = 1000; document.body.appendChild(targetobj); drag_move._TARGETS[ drag_move._TARGETS.length ] = targetobj; targetobj.onmouseover = dragmove_events.prototype.event_TARGET_mouseover; targetobj.onmouseout = dragmove_events.prototype.event_TARGET_mouseout; } } } //------------------------------- // Alter original row //------------------------------- if ( ! document.getElementById( drag_move.var_original_row_text + '-HIDDEN-' + drag_move.current_id ) ) { var newdiv = document.createElement('DIV'); newdiv.id = drag_move.var_original_row_text + '-HIDDEN-' + drag_move.current_id; newdiv.className = (is_ie ) ? drag_move.var_hide_row_classname+'-ie' : drag_move.var_hide_row_classname+'-moz'; newdiv.style.position = 'absolute'; newdiv.style.top = ipsclass.get_obj_toppos( drag_root_obj ) + 'px'; newdiv.style.left = ipsclass.get_obj_leftpos( drag_root_obj ) + 'px'; newdiv.style.width = drag_orig_obj.offsetWidth + 'px'; newdiv.style.height = drag_orig_obj.offsetHeight + 'px'; document.body.appendChild(newdiv); } else { var newdiv = document.getElementById( drag_move.var_original_row_text + '-HIDDEN-' + drag_move.current_id ); newdiv.style.display = ''; } //------------------------------- // Set drag flag //------------------------------- drag_move._drag_in_progress = 1; } }; /*-------------------------------------------------------------------------*/ // DRAG START: Time to remove the makeup /*-------------------------------------------------------------------------*/ dragmove_events.prototype.event_drag_end = function( x, y ) { //------------------------------- // Hide DIV //------------------------------- if ( drag_move.current_id ) { var drag_main_obj = document.getElementById( drag_move.var_drag_draggable_id_text + '-' + drag_move.current_id ); var drag_root_obj = document.getElementById( drag_move.var_drag_object_id_text + '-' + drag_move.current_id ); var drag_orig_obj = document.getElementById( drag_move.var_original_row_text + '-' + drag_move.current_id ); //------------------------------- // Hide draggable thing //------------------------------- drag_main_obj.style.display = 'none'; //------------------------------- // Hide row cover //------------------------------- if ( document.getElementById( drag_move.var_original_row_text + '-HIDDEN-' + drag_move.current_id ) ) { document.getElementById( drag_move.var_original_row_text + '-HIDDEN-' + drag_move.current_id ).style.display = 'none'; } } //------------------------------- // CLEAR TARGETS //------------------------------- if ( drag_move._TARGETS ) { for ( var i in drag_move._TARGETS ) { document.body.removeChild( drag_move._TARGETS[i] ); } drag_move._TARGETS = new Array(); } //------------------------------- // Did we drop on a target? //------------------------------- if ( drag_move.var_target_over_id ) { var new_parent_id = drag_move.var_target_over_id; var page_id = drag_move.current_id; /*--------------------------------------------*/ // Main function to do on request // Must be defined first!! /*--------------------------------------------*/ do_request_function = function() { //---------------------------------- // Ignore unless we're ready to go //---------------------------------- if ( ! xmlobj.readystate_ready_and_ok() ) { xmlobj.show_loading( "Move in progress..." ); return; } xmlobj.hide_loading(); //---------------------------------- // INIT //---------------------------------- var returned = xmlobj.xmlhandler.responseText; if ( returned.match( /(0|-|\=)<\/null>/ ) ) { alert( "Error occured, move not completed " + returned ); } else { window.location = drag_move.var_bounce_url; } }; //---------------------------------- // LOAD XML //---------------------------------- xmlobj = new ajax_request(); xmlobj.onreadystatechange( do_request_function ); xmlobj.process( drag_move.var_ajax_url +'&pid='+page_id+'&new_parent_id='+new_parent_id ); } //------------------------------- // Release current drag ID //------------------------------- drag_move.current_id = null; //------------------------------- // Set drag flag //------------------------------- drag_move._drag_in_progress = null; //------------------------------- // Change colour back... //------------------------------- if ( drag_move.var_target_over_id ) { //------------------------------- // Get obj //------------------------------- var target_obj = document.getElementById( drag_move.var_original_row_text + '-' + drag_move.var_target_over_id ); //------------------------------- // Store old classname... //------------------------------- target_obj.className = drag_move.var_target_out_classname; } //------------------------------- // Clear target ID //------------------------------- drag_move.var_target_over_id = null; };