/** * workspace-draggable.js - what a drag * Applied to odkControl and toolButton; basic dragging functionality * onto the workspace and interactions with existing controls. */ var workspace_init =function($) { // private methods var scrollTimer; var scrolling = false; var checkScroll = function(position, config) { var $workspaceScrollArea = $('.workspaceScrollArea:visible'); var workspaceOffset = $workspaceScrollArea.offset(); if (position.top < (workspaceOffset.top + config.scrollMargin)) { if (!scrolling) { scrolling = true; clearInterval(scrollTimer); scrollTimer = setInterval(function() { $workspaceScrollArea.scrollTop($workspaceScrollArea.scrollTop() - config.scrollSpeed); }, config.scrollSpeed); } } else if (position.top > (workspaceOffset.top + $workspaceScrollArea.outerHeight(false) - config.scrollMargin)) { if (!scrolling) { scrolling = true; clearInterval(scrollTimer); scrollTimer = setInterval(function() { $workspaceScrollArea.scrollTop($workspaceScrollArea.scrollTop() + config.scrollSpeed); }, config.scrollSpeed); } } else { scrolling = false; clearInterval(scrollTimer); } }; var checkElemHover = function($elem, position, config, $container, thisControl, targetUI) { // Process for Invoice Table if (checkCanDropIntoGroup(thisControl, $elem) == false) { return false; } if(thisControl.is('.multi-selected') && multiSelectedControls){ for (var key in multiSelectedControls) { if(key == '__CTRLS__' || key == '__LAST_SEL__'){ continue; } if (checkCanDropIntoGroup(multiSelectedControls['__CTRLS__'][key], $elem) == false) { return false; } } } var properties = thisControl.data('odkControl-properties'); if(!isVersion(VERSION_STRICT_FORM_BUILDER) && isFormOpenSpecial && !isVersion(VERSION_ADD_DEL_CTRL_OSP) && (!isVersion(VERSION_ADD_CTRL_OSP) || (properties && properties.name.isOldCtrl))){ if(!properties){ return false; }else if(properties.ctrlDesc){ if(!isVersion(VERSION_FORM_BUILDER_EDIT_STOP_MOVETO_CONTAINER)){ if(properties.ctrlDesc.isInsideTheRepeat || properties.ctrlDesc.isInsideTheTable){ return false; } }else{ if(properties.ctrlDesc.isInsideTheRepeat || properties.ctrlDesc.isInsideTheTable || properties.ctrlDesc.isInsideTheGrid || properties.ctrlDesc.isInsideTheButtonGrid || properties.ctrlDesc.isInsideThePOD){ return false; } } } } // if element is clearly beyond our scope, clear placeholders and abort if (position.top > $elem.innerHeight()) { $elem.find('.placeholder') .addClass('closing') .slideUp('normal', function() { $(this).remove(); }); return false; } // set $container to self if not defined if (($container === undefined) || ($container === null)) $container = $elem; // otherwise, if there are no controls in the container, add a // placeholder and return as found if ($container.children(':not(.placeholder)').length === 0) { if ($container.find('.placeholder').length === 0){ config.dragCallback($container, 0); } return true; } var stackHeight = $container.offset().top - $elem.offset().top; var found = false; $container.children().each(function() { var $control = $(this); // Skip the placeholder; special case for groups/branches if ($control.is('.placeholder')) { stackHeight += $control.outerHeight(true); return; } else if ($control.is('.group')) { if (position.top > (stackHeight + 30)){ var $groupContainer = $control.children('.workspaceInnerWrapper').children('.workspaceInner'); found = checkElemHover($control, { top: position.top - stackHeight, left: position.left }, config, $groupContainer, thisControl, $control); if (found) return false; } } else if ($control.is('.ctrlTable')) { if (position.top > (stackHeight + 30)){ var $groupContainer = $control.children('.workspaceInnerWrapper').children('.workspaceInner'); found = checkElemHover($control, { top: position.top - stackHeight, left: position.left }, config, $groupContainer, thisControl, $control); if (found) return false; } } else if ($control.is('.ctrlSchedule')) { if (position.top > (stackHeight + 30)){ var $groupContainer = $control.children('.workspaceInnerWrapper').children('.workspaceInner'); found = checkElemHover($control, { top: position.top - stackHeight, left: position.left }, config, $groupContainer, thisControl, $control); if (found) return false; } } else if ($control.is('.ctrlPOD')) { if (position.top > (stackHeight + 30)){ var $groupContainer = $control.children('.workspaceInnerWrapper').children('.workspaceInner'); found = checkElemHover($control, { top: position.top - stackHeight, left: position.left }, config, $groupContainer, thisControl, $control); if (found) return false; } } else if ($control.is('.ctrlScoreTable')) { if (position.top > (stackHeight + 30)){ var $groupContainer = $control.children('.workspaceInnerWrapper').children('.workspaceInner'); found = checkElemHover($control, { top: position.top - stackHeight, left: position.left }, config, $groupContainer, thisControl, $control); if (found) return false; } } else if ($control.is('.ctrlButtonGrid')) { if (position.top > (stackHeight + 30)){ var $groupContainer = $control.children('.workspaceInnerWrapper').children('.workspaceInner'); found = checkElemHover($control, { top: position.top - stackHeight, left: position.left }, config, $groupContainer, thisControl, $control); if (found) return false; } } else if ($control.is('.ctrlGrid')) { if (position.top > (stackHeight + 30)){ var $groupContainer = $control.children('.workspaceInnerWrapper').children('.workspaceInner'); found = checkElemHover($control, { top: position.top - stackHeight, left: position.left }, config, $groupContainer, thisControl, $control); if (found) return false; } } else if ($control.is('.ctrlBreakPointData')) { if (position.top > (stackHeight + 30)){ var $groupContainer = $control.children('.workspaceInnerWrapper').children('.workspaceInner'); found = checkElemHover($control, { top: position.top - stackHeight, left: position.left }, config, $groupContainer, thisControl, $control); if (found) return false; } } var threshold = $control.innerHeight() / 3; // Check the top of the current block if (position.top < (stackHeight + threshold)) { if (! $control.prev().is('.placeholder')) { config.dragCallback($control, -1); } found = true; return false; } // Add the height stackHeight += $control.outerHeight(true); // Check the bottom of the current block if ((position.top > (stackHeight - threshold)) && (position.top < stackHeight)) { if (! $control.next().is('.placeholder')){ config.dragCallback($control, 1); } found = true; return false; } }); return found; }; var checkHover = function($this, position, config) { var properties = $this.data('odkControl-properties'); if(!isVersion(VERSION_STRICT_FORM_BUILDER) && isFormOpenSpecial && !isVersion(VERSION_ADD_DEL_CTRL_OSP) && (!isVersion(VERSION_ADD_CTRL_OSP) || (properties && properties.name.isOldCtrl))){ if(!properties){ return false; }else if(properties.ctrlDesc){ if(!isVersion(VERSION_FORM_BUILDER_EDIT_STOP_MOVETO_CONTAINER)){ if(properties.ctrlDesc.isInsideTheRepeat || properties.ctrlDesc.isInsideTheTable){ return false; } }else{ if(properties.ctrlDesc.isInsideTheRepeat || properties.ctrlDesc.isInsideTheTable || properties.ctrlDesc.isInsideTheGrid || properties.ctrlDesc.isInsideTheButtonGrid || properties.ctrlDesc.isInsideThePOD){ return false; } } } } // Check bounds var $workspaceScrollArea = $('.workspaceScrollArea:visible'); var workspaceOffset = $workspaceScrollArea.offset(); if ((position.left < workspaceOffset.left) || (position.left > (workspaceOffset.left + $workspaceScrollArea.outerWidth(false))) || (position.top < workspaceOffset.top) || (position.top > (workspaceOffset.top + $workspaceScrollArea.outerHeight(false)))) return; // Append as necessary var $workspace = $('.workspace:visible'); var stackHeight = workspaceOffset.top - $workspaceScrollArea.scrollTop() + $workspaceScrollArea.spacingTop() + $workspace.spacingTop(); position.top -= stackHeight; // Fallback: if we haven't matched any of the above cases // we're at the end of the line, so just add it after here. if((!checkElemHover($workspace, position, config, null, $this)) && ($workspace.children(':last-child').is(':not(.placeholder)'))){ config.dragCallback($workspace.children(':last-child'), 1); } }; $.fn.workspaceDraggable = function(options) { if(isVersion(VERSION_STRICT_FORM_BUILDER) && isFormOpenSpecial && !isVersion(VERSION_ADD_DEL_CTRL_OSP) && !isVersion(VERSION_ADD_CTRL_OSP)){ return false; } var options = $.extend({}, $.fn.workspaceDraggable.defaults, options); return this.each(function() { if(!isVersion(VERSION_STRICT_FORM_BUILDER) && isFormOpenSpecial && !isVersion(VERSION_ADD_DEL_CTRL_OSP) && !isVersion(VERSION_ADD_CTRL_OSP)){ return false; } var $this = $(this); // Support the metadata plugin var config = $.meta ? $.extend({}, options, $this.data()) : options; $(this).draggable($.extend({}, { addClass: false, appendTo: 'body', distance: 5, helper: 'clone', opacity: 0.8, scroll: false, drag: function(event, ui) { if($this.hasClass('inputDiable')){ return; } if($this.hasClass('inputDiableForDsp')){ return; } if($this.hasClass('scheduleSpecialCtrl')){ //return; } if($this.hasClass('podSpecialCtrl')){ //return; } if($this.hasClass('invSpecialCtrl')){ //return; } if($this.hasClass('ctrlDataSource')){ return; } if($this.hasClass('ctrlHeaderGrid')){ return; } if($this.hasClass('ctrlDataFilter')){ return; } if($this.hasClass('ctrlReportBreakPoint')){ return; } if($this.hasClass('ctrlBreakPointData')){ return; } if($this.hasClass('ctrlFooterGrid')){ return; } if($this.hasClass('ctrlEmailSchedule')){ return; } if($(this).is('.multi-selected')){ $('.workspaceScrollArea:visible .multi-selected').addClass('hideSessionForMoveImp'); } checkScroll({ left: ui.position.left, top: ui.position.top }, config); checkHover($this, { left: ui.position.left, top: ui.position.top }, config); }, stop: function(event, ui) { if($(this).is('.multi-selected')){ $('.workspaceScrollArea:visible .multi-selected').removeClass('hideSessionForMoveImp'); } if($this.hasClass('scheduleSpecialCtrl')){ //return; } if($this.hasClass('podSpecialCtrl')){ //return; } if($this.hasClass('invSpecialCtrl')){ //return; } if($this.hasClass('ctrlDataSource')){ return; } if($this.hasClass('ctrlHeaderGrid')){ return; } if($this.hasClass('ctrlDataFilter')){ return; } if($this.hasClass('ctrlReportBreakPoint')){ return; } if($this.hasClass('ctrlBreakPointData')){ return; } if($this.hasClass('ctrlFooterGrid')){ return; } if($this.hasClass('ctrlEmailSchedule')){ return; } clearInterval(scrollTimer); var currentPlaceHolder = $('.placeholder:first'); // If the control is inside an Invoice Table, we will confirm with user if ( (isInsideTheInvoiceTable(currentPlaceHolder) || isInsideTheGrid($this)) && ($this.is('.inputText') || $this.is('.inputNumeric') || $this.is('.inputTrends')) ) { config.dropCallback(ui.helper); } else if ( isInsideThePOD(currentPlaceHolder) && ($this.is('.inputLabel')) ) { config.dropCallback(ui.helper); } else if($this.is('.ctrlBreakPointDataElement')){ if(isInsideTheBreakPointData(currentPlaceHolder)){ config.dropCallback(ui.helper); }else{ currentPlaceHolder .addClass('closing') .slideUp('normal', function() { $(this).remove(); }); config.dropCallback(ui.helper); } } else { // Normal processing config.dropCallback(ui.helper); } } }, options.draggableOptions)); }); }; $.fn.workspaceDraggable.defaults = { dragCallback: function($control, direction) {}, draggableOptions: {}, dropCallback: function() {}, insertCallback: function() {}, scrollInterval: 10, scrollMargin: 40, scrollSpeed: 10 }; }; ;(function($){ workspace_init($); })(jQuery);