salix/front/core/directives/droppable.js

94 lines
2.7 KiB
JavaScript

import ngModule from '../module';
export function directive($parse) {
return {
restrict: 'A',
link: function($scope, $element, $attrs) {
const element = $element[0];
const onDropEvent = $parse($attrs.onDrop);
const isDroppable = $attrs.vnDroppable === 'true';
if (!isDroppable) return;
/**
* Captures current dragging element
*/
element.addEventListener('dragstart', () => {
this.dragged = element;
});
/**
* Enter droppable area event
*/
element.addEventListener('dragenter', event => {
element.style.backgroundColor = 'yellow';
event.stopImmediatePropagation();
event.preventDefault();
}, false);
/**
* Exit droppable area event
*/
element.addEventListener('dragleave', event => {
element.style.backgroundColor = 'transparent';
event.stopImmediatePropagation();
event.preventDefault();
});
/**
* Prevent dragover for allowing
* dispatch drop event
*/
element.addEventListener('dragover', event => {
event.stopPropagation();
event.preventDefault();
});
/**
* Fires when a drop events
*/
element.addEventListener('drop', event => {
const draggedParent = this.dragged.parentNode;
const targetChild = element.querySelector('ul');
element.style.transition = 'background 2s';
element.style.backgroundColor = 'transparent';
if (this.dragged === element)
return event.preventDefault();
if (targetChild) {
const targetNodes = targetChild.querySelectorAll('li');
const before = targetNodes[targetNodes.length - 1];
targetChild.insertBefore(this.dragged, before);
} else
draggedParent.removeChild(this.dragged);
onDropEvent($scope, {
dragged: {
element: this.dragged,
scope: angular.element(this.dragged).scope()
},
dropped: {
element: element,
scope: angular.element(element).scope()
}
});
event.stopImmediatePropagation();
});
}
};
}
directive.$inject = ['$parse'];
ngModule.directive('vnDroppable', directive);