Browse Source

Merge pull request #157 from RubaXa/fix-156

Determine the correct target before onFilter
pull/168/head
Lebedev Konstantin 10 years ago
parent
commit
6c41dcd380
  1. 40
      README.md
  2. 45
      Sortable.js
  3. 17
      index.html

40
README.md

@ -86,6 +86,7 @@ var sortable = new Sortable(el, {
// same properties as onUpdate // same properties as onUpdate
}, },
// Attempt to drag a filtered element
onFilter: function (/**Event*/evt) { onFilter: function (/**Event*/evt) {
var itemEl = evt.item; // HTMLElement receiving the `mousedown|tapstart` event. var itemEl = evt.item; // HTMLElement receiving the `mousedown|tapstart` event.
} }
@ -135,6 +136,29 @@ You can also define whether lists can give away, give and keep a copy (`clone`),
--- ---
#### `filter` option
```js
Sortable.create(list, {
filter: ".js-remove, .js-edit",
onFilter: function (evt) {
var item = el.item;
if (Sortable.utils.is(evt.target, ".js-remove")) { // Click on remove button
el.parentNode.removeChild(el); // remove sortable item
}
else if (Sortable.utils.is(evt.target, ".js-edit")) { // Click on edit link
// ...
}
}
})
```
---
<a name="ng"></a> <a name="ng"></a>
### Support AngularJS ### Support AngularJS
Include [ng-sortable.js](ng-sortable.js) Include [ng-sortable.js](ng-sortable.js)
@ -183,22 +207,6 @@ Get or set the option.
##### closest(el:`String`[, selector:`HTMLElement`]):`HTMLElement|null` ##### closest(el:`String`[, selector:`HTMLElement`]):`HTMLElement|null`
For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
```js
var editableList = new Sortable(list, {
filter: ".js-remove, .js-edit",
onFilter: function (evt) {
var el = editableList.closest(evt.item); // list item
if (editableList.closest(evt.item, ".js-remove")) { // Click on remove button
el.parentNode.removeChild(el); // remove sortable item
}
else if (editableList.closest(evt.item, ".js-edit")) { // Click on edit link
// ...
}
}
})
```
##### toArray():`String[]` ##### toArray():`String[]`
Serializes the sortable's item `data-id`'s into an array of string. Serializes the sortable's item `data-id`'s into an array of string.

45
Sortable.js

@ -164,41 +164,46 @@
_onTapStart: function (/**Event|TouchEvent*/evt) { _onTapStart: function (/**Event|TouchEvent*/evt) {
var touch = evt.touches && evt.touches[0], var touch = evt.touches && evt.touches[0],
target = (touch || evt).target, target = (touch || evt).target,
originalTarget = target,
options = this.options, options = this.options,
el = this.el, el = this.el,
filter = options.filter; filter = options.filter;
// get the index of the dragged element within its parent
startIndex = _index(target);
if (evt.type === 'mousedown' && evt.button !== 0 || options.disabled) { if (evt.type === 'mousedown' && evt.button !== 0 || options.disabled) {
return; // only left button or enabled return; // only left button or enabled
} }
if (options.handle) {
target = _closest(target, options.handle, el);
}
target = _closest(target, options.draggable, el);
// get the index of the dragged element within its parent
startIndex = _index(target);
// Check filter // Check filter
if (typeof filter === 'function') { if (typeof filter === 'function') {
if (filter.call(this, target, this)) { if (filter.call(this, evt, target, this)) {
_dispatchEvent(el, 'filter', target); _dispatchEvent(originalTarget, 'filter', target, el, startIndex);
return; // cancel dnd return; // cancel dnd
} }
} }
else if (filter) { else if (filter) {
filter = filter.split(',').filter(function (criteria) { filter = filter.split(',').some(function (criteria) {
return _closest(target, criteria.trim(), el); criteria = _closest(originalTarget, criteria.trim(), el);
if (criteria) {
_dispatchEvent(criteria, 'filter', target, el, startIndex);
return true;
}
}); });
if (filter.length) { if (filter.length) {
_dispatchEvent(el, 'filter', target);
return; // cancel dnd return; // cancel dnd
} }
} }
if (options.handle) {
target = _closest(target, options.handle, el);
}
target = _closest(target, options.draggable, el);
// IE 9 Support // IE 9 Support
if (target && evt.type == 'selectstart') { if (target && evt.type == 'selectstart') {
if (target.tagName != 'A' && target.tagName != 'IMG') { if (target.tagName != 'A' && target.tagName != 'IMG') {
@ -673,7 +678,7 @@
} }
function _closest(el, selector, ctx) { function _closest(/**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx) {
if (selector === '*') { if (selector === '*') {
return el; return el;
} }
@ -699,7 +704,7 @@
} }
function _globalDragOver(evt) { function _globalDragOver(/**Event*/evt) {
evt.dataTransfer.dropEffect = 'move'; evt.dataTransfer.dropEffect = 'move';
evt.preventDefault(); evt.preventDefault();
} }
@ -808,11 +813,12 @@
/** /**
* Returns the index of an element within its parent * Returns the index of an element within its parent
* @param el * @param el
* @returns {HTMLElement} * @returns {number}
* @private
*/ */
function _index(/**HTMLElement*/el) { function _index(/**HTMLElement*/el) {
var index = 0; var index = 0;
while ((el = el.previousElementSibling)) { while (el && (el = el.previousElementSibling)) {
index++; index++;
} }
return index; return index;
@ -825,6 +831,9 @@
css: _css, css: _css,
find: _find, find: _find,
bind: _bind, bind: _bind,
is: function (el, selector) {
return !!_closest(el, selector, el);
},
closest: _closest, closest: _closest,
toggleClass: _toggleClass, toggleClass: _toggleClass,
dispatchEvent: _dispatchEvent, dispatchEvent: _dispatchEvent,

17
index.html

@ -276,7 +276,7 @@ var editableList = new Sortable(editable, {
} }
new Sortable(foo, { Sortable.create(foo, {
group: "words", group: "words",
animation: 150, animation: 150,
store: { store: {
@ -298,7 +298,7 @@ var editableList = new Sortable(editable, {
}); });
new Sortable(bar, { Sortable.create(bar, {
group: "words", group: "words",
animation: 150, animation: 150,
onAdd: function (evt){ console.log('onAdd.bar:', evt.item); }, onAdd: function (evt){ console.log('onAdd.bar:', evt.item); },
@ -309,19 +309,18 @@ var editableList = new Sortable(editable, {
}); });
new Sortable(multi, { Sortable.create(multi, {
animation: 150, animation: 150,
draggable: '.tile', draggable: '.tile',
handle: '.tile__name' handle: '.tile__name'
}); });
var editableList = new Sortable(editable, { var editableList = Sortable.create(editable, {
animation: 150, animation: 150,
filter: '.js-remove', filter: '.js-remove',
onFilter: function (evt) { onFilter: function (evt) {
var el = editableList.closest(evt.item); evt.item.parentNode.removeChild(evt.item);
el && el.parentNode.removeChild(el);
} }
}); });
@ -339,7 +338,7 @@ var editableList = new Sortable(editable, {
[].forEach.call(multi.getElementsByClassName('tile__list'), function (el){ [].forEach.call(multi.getElementsByClassName('tile__list'), function (el){
new Sortable(el, { Sortable.create(el, {
group: 'photo', group: 'photo',
animation: 150 animation: 150
}); });
@ -360,14 +359,14 @@ var editableList = new Sortable(editable, {
pull: false, pull: false,
put: true put: true
}].forEach(function (groupOpts, i) { }].forEach(function (groupOpts, i) {
new Sortable(document.getElementById('advanced-' + (i + 1)), { Sortable.create(document.getElementById('advanced-' + (i + 1)), {
sort: (i != 1), sort: (i != 1),
group: groupOpts, group: groupOpts,
animation: 150 animation: 150
}); });
}); });
new Sortable(document.getElementById('handle-1'), { Sortable.create(document.getElementById('handle-1'), {
handle: '.drag-handle', handle: '.drag-handle',
animation: 150 animation: 150
}); });

Loading…
Cancel
Save