Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dragleave #540

Merged
merged 11 commits into from
Aug 15, 2020
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,15 @@ sortable('.sortable')[0].addEventListener('sortupdate', function(e) {
});
```

### sortenter

Fired when a dragitem enters a sortable container.

### sortleave

Fired when a dragitem leaves a sortable container.


## Options

### items
Expand Down Expand Up @@ -253,6 +262,15 @@ sortable('.sortable', {
});
```

### dropTargetContainerClass
Use `dropTargetContainerClass` option to apply a css Class to the container. The class is added when dragged item enters the container and removed when it leaves it (or is dropped).

``` javascript
sortable('.sortable', {
dropTargetContainerClass: 'is-drop-target' // Defaults to false
});
```

### maxItems
Use the `maxItems` option to restrict the number of items that can be added to a sortable from a [connected](#connectwith) sortable. `maxItems` should always be combined with the `items` option. Make sure `items` does not match placeholder and other options, so that they are not counted.

Expand Down
37 changes: 37 additions & 0 deletions docs/html5sortable.js
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,7 @@ var sortable = (function () {
placeholderClass: 'sortable-placeholder',
draggingClass: 'sortable-dragging',
hoverClass: false,
dropTargetContainerClass: false,
debounce: 0,
throttleTime: 100,
maxItems: 0,
Expand Down Expand Up @@ -719,6 +720,15 @@ var sortable = (function () {
removeEventListener(items, 'mouseenter');
removeEventListener(items, 'mouseleave');
};
// Remove container events
var _removeContainerEvents = function () {
if (originContainer) {
removeEventListener(originContainer, 'dragleave');
}
if (previousContainer && (previousContainer !== originContainer)) {
removeEventListener(previousContainer, 'dragleave');
}
};
/**
* _getDragging returns the current element to drag or
* a copy of the element.
Expand Down Expand Up @@ -804,6 +814,7 @@ var sortable = (function () {
removeEventListener(handles, 'mousedown');
_removeItemEvents(items);
_removeItemData(items);
_removeContainerEvents();
// clear sortable flag
sortableElement.isSortable = false;
};
Expand Down Expand Up @@ -865,6 +876,7 @@ var sortable = (function () {
addData(sortableElement, '_disabled', 'false');
// remove event handlers from items
_removeItemEvents(items);
_removeContainerEvents();
removeEventListener(handles, 'mousedown');
// remove event handlers from sortable
removeEventListener(sortableElement, 'dragover');
Expand Down Expand Up @@ -995,6 +1007,9 @@ var sortable = (function () {
if (sortableContainer && sortableContainer !== previousContainer) {
destinationItemsBeforeUpdate = _filter(sortableContainer.children, addData(sortableContainer, 'items'))
.filter(function (item) { return item !== store(sortableElement).placeholder; });
if (options.dropTargetContainerClass) {
sortableContainer.classList.add(options.dropTargetContainerClass);
}
sortableContainer.dispatchEvent(new CustomEvent('sortenter', {
detail: {
origin: {
Expand All @@ -1010,6 +1025,25 @@ var sortable = (function () {
originalTarget: target
}
}));
addEventListener(sortableContainer, 'dragleave', function (e) {
var outTarget = e.releatedTarget || e.fromElement;
if (!e.currentTarget.contains(outTarget)) {
if (options.dropTargetContainerClass) {
sortableContainer.classList.remove(options.dropTargetContainerClass);
}
sortableContainer.dispatchEvent(new CustomEvent('sortleave', {
detail: {
origin: {
elementIndex: originElementIndex,
index: originIndex,
container: sortableContainer
},
item: dragging,
originalTarget: target
}
}));
}
});
}
previousContainer = sortableContainer;
});
Expand Down Expand Up @@ -1096,6 +1130,9 @@ var sortable = (function () {
var destinationElementIndex = _index(dragging, Array.from(dragging.parentElement.children)
.filter(function (item) { return item !== placeholder; }));
var destinationIndex = _index(dragging, destinationItems);
if (options.dropTargetContainerClass) {
destinationContainer.classList.remove(options.dropTargetContainerClass);
}
/*
* When a list item changed container lists or index within a list
* Fires Custom Event - 'sortupdate'
Expand Down
1 change: 1 addition & 0 deletions src/defaultConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export default {
placeholderClass: 'sortable-placeholder',
draggingClass: 'sortable-dragging',
hoverClass: false,
dropTargetContainerClass: false,
debounce: 0,
throttleTime: 100,
maxItems: 0,
Expand Down
43 changes: 42 additions & 1 deletion src/html5sortable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,17 @@ const _removeItemEvents = function (items) {
_off(items, 'mouseenter')
_off(items, 'mouseleave')
}

// Remove container events
const _removeContainerEvents = function () {
if (originContainer) {
_off(originContainer, 'dragleave')
}
if (previousContainer && (previousContainer !== originContainer)) {
_off(previousContainer, 'dragleave')
}
}

/**
* _getDragging returns the current element to drag or
* a copy of the element.
Expand Down Expand Up @@ -146,6 +157,7 @@ const _destroySortable = function (sortableElement) {
_off(handles, 'mousedown')
_removeItemEvents(items)
_removeItemData(items)
_removeContainerEvents()
// clear sortable flag
sortableElement.isSortable = false
}
Expand Down Expand Up @@ -206,6 +218,7 @@ const _reloadSortable = function (sortableElement) {
_data(sortableElement, '_disabled', 'false')
// remove event handlers from items
_removeItemEvents(items)
_removeContainerEvents()
_off(handles, 'mousedown')
// remove event handlers from sortable
_off(sortableElement, 'dragover')
Expand Down Expand Up @@ -349,6 +362,9 @@ export default function sortable (sortableElements, options: configuration|objec
destinationItemsBeforeUpdate = _filter(sortableContainer.children, _data(sortableContainer, 'items'))
.filter(item => item !== store(sortableElement).placeholder)

if (options.dropTargetContainerClass) {
sortableContainer.classList.add(options.dropTargetContainerClass)
}
sortableContainer.dispatchEvent(new CustomEvent('sortenter', {
detail: {
origin: {
Expand All @@ -364,8 +380,29 @@ export default function sortable (sortableElements, options: configuration|objec
originalTarget: target
}
}))
}

_on(sortableContainer, 'dragleave', e => {
// TODO: rename outTarget to be more self-explanatory
// e.fromElement for very old browsers, similar to relatedTarget
const outTarget = e.relatedTarget || e.fromElement
if (!e.currentTarget.contains(outTarget)) {
if (options.dropTargetContainerClass) {
sortableContainer.classList.remove(options.dropTargetContainerClass)
}
sortableContainer.dispatchEvent(new CustomEvent('sortleave', {
detail: {
origin: {
elementIndex: originElementIndex,
index: originIndex,
container: sortableContainer
},
item: dragging,
originalTarget: target
}
}))
}
})
}
previousContainer = sortableContainer
})

Expand Down Expand Up @@ -464,6 +501,10 @@ export default function sortable (sortableElements, options: configuration|objec
.filter(item => item !== placeholder))
const destinationIndex = _index(dragging, destinationItems)

if (options.dropTargetContainerClass) {
destinationContainer.classList.remove(options.dropTargetContainerClass)
}

/*
* When a list item changed container lists or index within a list
* Fires Custom Event - 'sortupdate'
Expand Down