angular .module('fasit') .directive('fbGridDragColumns', [function () { 'use strict'; return { restrict: 'A', replace: true, link: function (scope: fb.IFbGridScope, el: JQuery, attrs: ng.IAttributes) { var draggedEl; var isMousePointerOnFirstHalf = function (e: MouseEvent) : boolean { var el = e.target; var pos = (e.offsetX || e.layerX) / el.offsetWidth; return pos < 0.5; } scope.$on('$destroy', function () { el.unbind(); }); el.bind('dragstart', function (e: JQueryEventObject) { draggedEl = angular.element(e.target); var x = e.originalEvent['clientX'], y = e.originalEvent['clientY'], elementMouseIsOver = document.elementFromPoint(x, y); if (elementMouseIsOver.tagName === 'INPUT' || !draggedEl.hasClass('draggable')) { e.preventDefault(); e.stopPropagation(); return; } $('.drag-overlay').css('display', 'block'); $('.rc-handle').css('display', 'none'); // Göm rc-handles (de som ändrar kolumnstorlek) för att inte störa med drop e.originalEvent['dataTransfer'].effectAllowed = 'move'; e.originalEvent['dataTransfer'].setData('text', 'column'); // För att FF ska visa ghost-bild }); el.bind('dragend', function (e: JQueryEventObject) { $('.rc-handle').css('display', 'block'); // Visa rc-handles igen $('.drag-overlay').css('display', 'none'); $('.drag-overlay').removeClass('draggingLeft draggingRight'); scope.syncHandles(); }); el.bind('dragover', function (e: JQueryEventObject) { e.preventDefault(); e.stopPropagation(); var elOver = angular.element(e.target); if (!elOver.hasClass('drag-overlay')) { return; } var isOnFirstHalf = isMousePointerOnFirstHalf( e.originalEvent); if (isOnFirstHalf) { if (!elOver.hasClass('draggingLeft')) { // Minimerar flicker i IE genom att endast ändra klass vid behov elOver.addClass('draggingLeft'); } if (elOver.hasClass('draggingRight')) { elOver.removeClass('draggingRight'); } } else { if (!elOver.hasClass('draggingRight')) { elOver.addClass('draggingRight'); } if (elOver.hasClass('draggingLeft')) { elOver.removeClass('draggingLeft'); } } }); el.bind('dragenter', function (e: JQueryEventObject) { e.preventDefault(); e.stopPropagation(); e.originalEvent['dataTransfer'].dropEffect = 'move'; }); el.bind('dragleave', function (e: JQueryEventObject) { e.preventDefault(); e.stopPropagation(); var elLeave = angular.element(e.target); if (!elLeave.hasClass('drag-overlay')) { return; } elLeave.removeClass('draggingLeft draggingRight'); }); el.bind('drop', function (e: JQueryEventObject) { e.preventDefault(); var sortedVisibleColumns = scope.orderedColumns.slice(); var draggedColumn:fb.IGridColumn = draggedEl.scope()['column']; var draggedIndex = _.indexOf(sortedVisibleColumns, draggedColumn); var droppedOnEl = angular.element(e.target); var droppedIndex = -1; if (droppedOnEl.hasClass('checkbox-column')) { droppedIndex = 0; } else if (droppedOnEl.hasClass('fill-column')) { droppedIndex = sortedVisibleColumns.length - 1; } else { droppedIndex = _.indexOf(sortedVisibleColumns, droppedOnEl.scope()['column']); var isOnFirstHalf = isMousePointerOnFirstHalf( e.originalEvent); if (isOnFirstHalf && draggedIndex < droppedIndex) { --droppedIndex; } else if (!isOnFirstHalf && draggedIndex > droppedIndex) { ++droppedIndex; } } if (droppedIndex < 0 || draggedIndex === droppedIndex) { return; } sortedVisibleColumns.splice(draggedIndex, 1); sortedVisibleColumns.splice(droppedIndex, 0, draggedColumn); _.each(sortedVisibleColumns, function (col : fb.IGridColumn, i) { col.Order = i; }); scope.$apply(); }); } }; }]);