Skip to content
This repository has been archived by the owner on Mar 10, 2024. It is now read-only.

New option to don't add placeholder element #497

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Use the dnd-list attribute to make your list element a dropzone. Usually you wil
* `dnd-disable-if` Optional boolean expression. When it evaluates to true, no dropping into the list is possible. Note that this also disables rearranging items inside the list. [Demo](http://marceljuenemann.github.io/angular-drag-and-drop-lists/demo/#/types)
* `dnd-horizontal-list` Optional boolean expression. When it evaluates to true, the positioning algorithm will use the left and right halfs of the list items instead of the upper and lower halfs. [Demo](http://marceljuenemann.github.io/angular-drag-and-drop-lists/demo/#/advanced)
* `dnd-external-sources` Optional boolean expression. When it evaluates to true, the list accepts drops from sources outside of the current browser tab, which allows to drag and drop accross different browser tabs. The only major browser for which this is currently not working is Microsoft Edge. [Demo](http://marceljuenemann.github.io/angular-drag-and-drop-lists/demo/#/advanced)
* `dnd-no-placeholder` Optional attribute. When it is defined the list will not add child element with class dndPlaceholder and the index in callbacks will always be undefined.

**Callbacks**
* `dnd-dragover` Optional expression that is invoked when an element is dragged over the list. If the expression is set, but does not return true, the element is not allowed to be dropped. The following variables will be available:
Expand Down
23 changes: 15 additions & 8 deletions angular-drag-and-drop-lists.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@
* drops from sources outside of the current browser tab. This allows to
* drag and drop accross different browser tabs. The only major browser
* that does not support this is currently Microsoft Edge.
* - dnd-no-placeholder Optional attribute. When it is defined the list will
* not add child element with class dndPlaceholder and the index in
* callbacks will always be undefined.
*
* Callbacks:
* - dnd-dragover Optional expression that is invoked when an element is dragged over the
Expand Down Expand Up @@ -271,12 +274,14 @@
*/
dndLists.directive('dndList', ['$parse', function($parse) {
return function(scope, element, attr) {
var doNotUsePlaceholder = 'dndNoPlaceholder' in attr;
// While an element is dragged over the list, this placeholder element is inserted
// at the location where the element would be inserted after dropping.
var placeholder = getPlaceholderElement();
placeholder.remove();

var placeholderNode = placeholder[0];
if (!doNotUsePlaceholder) {
var placeholder = getPlaceholderElement();
placeholder.remove();
var placeholderNode = placeholder[0];
}
var listNode = element[0];
var listSettings = {};

Expand Down Expand Up @@ -316,7 +321,7 @@
if (!mimeType || !isDropAllowed(itemType)) return true;

// Make sure the placeholder is shown, which is especially important if the list is empty.
if (placeholderNode.parentNode != listNode) {
if (!doNotUsePlaceholder && placeholderNode.parentNode != listNode) {
element.append(placeholder);
}

Expand All @@ -327,7 +332,7 @@
listItemNode = listItemNode.parentNode;
}

if (listItemNode.parentNode == listNode && listItemNode != placeholderNode) {
if (!doNotUsePlaceholder && listItemNode.parentNode == listNode && listItemNode != placeholderNode) {
// If the mouse pointer is in the upper half of the list item element,
// we position the placeholder before the list item, otherwise after it.
var rect = listItemNode.getBoundingClientRect();
Expand Down Expand Up @@ -518,7 +523,8 @@
* Small helper function that cleans up if we aborted a drop.
*/
function stopDragover() {
placeholder.remove();
if (!doNotUsePlaceholder)
placeholder.remove();
element.removeClass("dndDragover");
return true;
}
Expand All @@ -543,7 +549,8 @@
* object needs to be inserted
*/
function getPlaceholderIndex() {
return Array.prototype.indexOf.call(listNode.children, placeholderNode);
if (!doNotUsePlaceholder)
return Array.prototype.indexOf.call(listNode.children, placeholderNode);
}

/**
Expand Down
38 changes: 20 additions & 18 deletions angular-drag-and-drop-lists.min.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,39 +11,41 @@
e.directive("dndDraggable",["$parse","$timeout",function(e,i){return function(l,f,c){f.attr("draggable","true"),c.dndDisableIf&&l.$watch(c.dndDisableIf,function(e){f.attr("draggable",!e)}),f.on("dragstart",function(s){if(s=s.originalEvent||s,"false"==f.attr("draggable"))return!0
o.isDragging=!0,o.itemType=c.dndType&&l.$eval(c.dndType).toLowerCase(),o.dropEffect="none",o.effectAllowed=c.dndEffectAllowed||d[0],s.dataTransfer.effectAllowed=o.effectAllowed
var g=l.$eval(c.dndDraggable),u=a+(o.itemType?"-"+o.itemType:"")
try{s.dataTransfer.setData(u,angular.toJson(g))}catch(p){var v=angular.toJson({item:g,type:o.itemType})
try{s.dataTransfer.setData(r,v)}catch(p){var D=n(d,o.effectAllowed)
s.dataTransfer.effectAllowed=D[0],s.dataTransfer.setData(t,v)}}if(f.addClass("dndDragging"),i(function(){f.addClass("dndDraggingSource")},0),s._dndHandle&&s.dataTransfer.setDragImage&&s.dataTransfer.setDragImage(f[0],0,0),e(c.dndDragstart)(l,{event:s}),c.dndCallback){var y=e(c.dndCallback)
o.callback=function(e){return y(l,e||{})}}s.stopPropagation()}),f.on("dragend",function(n){n=n.originalEvent||n,l.$apply(function(){var a=o.dropEffect,r={copy:"dndCopied",link:"dndLinked",move:"dndMoved",none:"dndCanceled"}
e(c[r[a]])(l,{event:n}),e(c.dndDragend)(l,{event:n,dropEffect:a})}),o.isDragging=!1,o.callback=void 0,f.removeClass("dndDragging"),f.removeClass("dndDraggingSource"),n.stopPropagation(),i(function(){f.removeClass("dndDraggingSource")},0)}),f.on("click",function(n){c.dndSelected&&(n=n.originalEvent||n,l.$apply(function(){e(c.dndSelected)(l,{event:n})}),n.stopPropagation())}),f.on("selectstart",function(){this.dragDrop&&this.dragDrop()})}}]),e.directive("dndList",["$parse",function(e){return function(i,l,f){function c(e){if(!e)return t
try{s.dataTransfer.setData(u,angular.toJson(g))}catch(e){var p=angular.toJson({item:g,type:o.itemType})
try{s.dataTransfer.setData(r,p)}catch(e){var v=n(d,o.effectAllowed)
s.dataTransfer.effectAllowed=v[0],s.dataTransfer.setData(t,p)}}if(f.addClass("dndDragging"),i(function(){f.addClass("dndDraggingSource")},0),s._dndHandle&&s.dataTransfer.setDragImage&&s.dataTransfer.setDragImage(f[0],0,0),e(c.dndDragstart)(l,{event:s}),c.dndCallback){var D=e(c.dndCallback)
o.callback=function(e){return D(l,e||{})}}s.stopPropagation()}),f.on("dragend",function(n){n=n.originalEvent||n,l.$apply(function(){var a=o.dropEffect
e(c[{copy:"dndCopied",link:"dndLinked",move:"dndMoved",none:"dndCanceled"}[a]])(l,{event:n}),e(c.dndDragend)(l,{event:n,dropEffect:a})}),o.isDragging=!1,o.callback=void 0,f.removeClass("dndDragging"),f.removeClass("dndDraggingSource"),n.stopPropagation(),i(function(){f.removeClass("dndDraggingSource")},0)}),f.on("click",function(n){c.dndSelected&&(n=n.originalEvent||n,l.$apply(function(){e(c.dndSelected)(l,{event:n})}),n.stopPropagation())}),f.on("selectstart",function(){this.dragDrop&&this.dragDrop()})}}]),e.directive("dndList",["$parse",function(e){return function(i,l,f){function c(e){if(!e)return t
for(var n=0;n<e.length;n++)if(e[n]==t||e[n]==r||e[n].substr(0,a.length)==a)return e[n]
return null}function s(e){return o.isDragging?o.itemType||void 0:e==t||e==r?null:e&&e.substr(a.length+1)||void 0}function g(e){return E.disabled?!1:E.externalSources||o.isDragging?E.allowedTypes&&null!==e?e&&-1!=E.allowedTypes.indexOf(e):!0:!1}function u(e,a){var r=d
return a||(r=n(r,e.dataTransfer.effectAllowed)),o.isDragging&&(r=n(r,o.effectAllowed)),f.dndEffectAllowed&&(r=n(r,f.dndEffectAllowed)),r.length?e.ctrlKey&&-1!=r.indexOf("copy")?"copy":e.altKey&&-1!=r.indexOf("link")?"link":r[0]:"none"}function p(){return T.remove(),l.removeClass("dndDragover"),!0}function v(n,a,r,t,d,l){return e(n)(i,{callback:o.callback,dropEffect:r,event:a,external:!o.isDragging,index:void 0!==d?d:D(),item:l||void 0,type:t})}function D(){return Array.prototype.indexOf.call(m.children,h)}function y(){var e
return null}function s(e){return o.isDragging?o.itemType||void 0:e==t||e==r?null:e&&e.substr(a.length+1)||void 0}function g(e){return!E.disabled&&(!(!E.externalSources&&!o.isDragging)&&(!E.allowedTypes||null===e||e&&-1!=E.allowedTypes.indexOf(e)))}function u(e,a){var r=d
return a||(r=n(r,e.dataTransfer.effectAllowed)),o.isDragging&&(r=n(r,o.effectAllowed)),f.dndEffectAllowed&&(r=n(r,f.dndEffectAllowed)),r.length?e.ctrlKey&&-1!=r.indexOf("copy")?"copy":e.altKey&&-1!=r.indexOf("link")?"link":r[0]:"none"}function p(){return y||T.remove(),l.removeClass("dndDragover"),!0}function v(n,a,r,t,d,l){return e(n)(i,{callback:o.callback,dropEffect:r,event:a,external:!o.isDragging,index:void 0!==d?d:D(),item:l||void 0,type:t})}function D(){if(!y)return Array.prototype.indexOf.call(m.children,h)}var y="dndNoPlaceholder"in f
if(!y){var T=function(){var e
return angular.forEach(l.children(),function(n){var a=angular.element(n)
a.hasClass("dndPlaceholder")&&(e=a)}),e||angular.element("<li class='dndPlaceholder'></li>")}var T=y()
a.hasClass("dndPlaceholder")&&(e=a)}),e||angular.element("<li class='dndPlaceholder'></li>")}()
T.remove()
var h=T[0],m=l[0],E={}
var h=T[0]}var m=l[0],E={}
l.on("dragenter",function(e){e=e.originalEvent||e
var n=f.dndAllowedTypes&&i.$eval(f.dndAllowedTypes)
E={allowedTypes:angular.isArray(n)&&n.join("|").toLowerCase().split("|"),disabled:f.dndDisableIf&&i.$eval(f.dndDisableIf),externalSources:f.dndExternalSources&&i.$eval(f.dndExternalSources),horizontal:f.dndHorizontalList&&i.$eval(f.dndHorizontalList)}
var a=c(e.dataTransfer.types)
return a&&g(s(a))?void e.preventDefault():!0}),l.on("dragover",function(e){e=e.originalEvent||e
if(!a||!g(s(a)))return!0
e.preventDefault()}),l.on("dragover",function(e){e=e.originalEvent||e
var n=c(e.dataTransfer.types),a=s(n)
if(!n||!g(a))return!0
if(h.parentNode!=m&&l.append(T),e.target!=m){for(var r=e.target;r.parentNode!=m&&r.parentNode;)r=r.parentNode
if(r.parentNode==m&&r!=h){var d=r.getBoundingClientRect()
if(y||h.parentNode==m||l.append(T),e.target!=m){for(var r=e.target;r.parentNode!=m&&r.parentNode;)r=r.parentNode
if(!y&&r.parentNode==m&&r!=h){var d=r.getBoundingClientRect()
if(E.horizontal)var o=e.clientX<d.left+d.width/2
else var o=e.clientY<d.top+d.height/2
m.insertBefore(h,o?r:r.nextSibling)}}var i=n==t,D=u(e,i)
return"none"==D?p():f.dndDragover&&!v(f.dndDragover,e,D,a)?p():(e.preventDefault(),i||(e.dataTransfer.dropEffect=D),l.addClass("dndDragover"),e.stopPropagation(),!1)}),l.on("drop",function(e){e=e.originalEvent||e
var n=c(e.dataTransfer.types),a=s(n)
if(!n||!g(a))return!0
e.preventDefault()
try{var d=JSON.parse(e.dataTransfer.getData(n))}catch(l){return p()}if((n==t||n==r)&&(a=d.type||void 0,d=d.item,!g(a)))return p()
var y=n==t,T=u(e,y)
if("none"==T)return p()
var h=D()
return f.dndDrop&&(d=v(f.dndDrop,e,T,a,h,d),!d)?p():(o.dropEffect=T,y||(e.dataTransfer.dropEffect=T),d!==!0&&i.$apply(function(){i.$eval(f.dndList).splice(h,0,d)}),v(f.dndInserted,e,T,a,h,d),p(),e.stopPropagation(),!1)}),l.on("dragleave",function(e){e=e.originalEvent||e
try{var d=JSON.parse(e.dataTransfer.getData(n))}catch(e){return p()}if((n==t||n==r)&&(a=d.type||void 0,d=d.item,!g(a)))return p()
var l=n==t,y=u(e,l)
if("none"==y)return p()
var T=D()
return f.dndDrop&&!(d=v(f.dndDrop,e,y,a,T,d))?p():(o.dropEffect=y,l||(e.dataTransfer.dropEffect=y),!0!==d&&i.$apply(function(){i.$eval(f.dndList).splice(T,0,d)}),v(f.dndInserted,e,y,a,T,d),p(),e.stopPropagation(),!1)}),l.on("dragleave",function(e){e=e.originalEvent||e
var n=document.elementFromPoint(e.clientX,e.clientY)
m.contains(n)&&!e._dndPhShown?e._dndPhShown=!0:p()})}}]),e.directive("dndNodrag",function(){return function(e,n,a){n.attr("draggable","true"),n.on("dragstart",function(e){e=e.originalEvent||e,e._dndHandle||(e.dataTransfer.types&&e.dataTransfer.types.length||e.preventDefault(),e.stopPropagation())}),n.on("dragend",function(e){e=e.originalEvent||e,e._dndHandle||e.stopPropagation()})}}),e.directive("dndHandle",function(){return function(e,n,a){n.attr("draggable","true"),n.on("dragstart dragend",function(e){e=e.originalEvent||e,e._dndHandle=!0})}})
var o={}}(angular.module("dndLists",[]));
var o={}}(angular.module("dndLists",[]))
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "angular-drag-and-drop-lists",
"main": "angular-drag-and-drop-lists.js",
"version": "2.1.0",
"version": "2.1.1",
"description": "Angular directives for sorting nested lists using the HTML5 Drag and Drop API",
"repository": "https://github.com/marceljuenemann/angular-drag-and-drop-lists",
"license": "MIT",
Expand Down