Browse Source

Merge branch 'dev'

pull/404/merge
RubaXa 10 years ago
parent
commit
3cb80fb6a6
  1. 25
      Gruntfile.js
  2. 23
      README.md
  3. 133
      Sortable.js
  4. 37
      ng-sortable.js

25
Gruntfile.js

@ -35,9 +35,7 @@ module.exports = function (grunt) {
}
},
jquery: {
files: {
'jquery.fn.sortable.min.js': 'jquery.fn.sortable.js'
}
files: {}
}
},
@ -54,22 +52,37 @@ module.exports = function (grunt) {
});
grunt.registerTask('jquery', function (arg) {
grunt.registerTask('jquery', function (exportName, uglify) {
if (exportName == 'min') {
exportName = null;
uglify = 'min';
}
if (!exportName) {
exportName = 'sortable';
}
var fs = require('fs'),
filename = 'jquery.fn.sortable.js';
filename = 'jquery.fn.' + exportName + '.js';
grunt.log.oklns(filename);
fs.writeFileSync(
filename,
(fs.readFileSync('jquery.binding.js') + '')
.replace('$.fn.sortable', '$.fn.' + exportName)
.replace('/* CODE */',
(fs.readFileSync('Sortable.js') + '')
.replace(/^[\s\S]*?function[\s\S]*?(var[\s\S]+)\/\/\s+Export[\s\S]+/, '$1')
)
);
if (arg === 'min') {
if (uglify) {
var opts = {};
opts['jquery.fn.' + exportName + '.min.js'] = filename;
grunt.config.set('uglify.jquery.files', opts);
grunt.task.run('uglify:jquery');
}
});

23
README.md

@ -55,6 +55,7 @@ You can use any element for the list and its elements, not just `ul`/`li`. Here
var sortable = new Sortable(el, {
group: "name", // or { name: "...", pull: [true, false, clone], put: [true, false, array] }
sort: true, // sorting inside list
delay: 0, // time in milliseconds to define when the sorting should start
disabled: false, // Disables the sortable if set to true.
store: null, // @see Store
animation: 150, // ms, animation speed moving items when sorting, `0` — without animation
@ -109,6 +110,16 @@ var sortable = new Sortable(el, {
// Attempt to drag a filtered element
onFilter: function (/**Event*/evt) {
var itemEl = evt.item; // HTMLElement receiving the `mousedown|tapstart` event.
},
// Event when you move an item in the list or between lists
onMove: function (/**Event*/evt) {
// Example: http://jsbin.com/tuyafe/1/edit?js,output
evt.dragged; // dragged HTMLElement
evt.draggedRect; // TextRectangle {left, top, right и bottom}
evt.related; // HTMLElement on which have guided
evt.relatedRect; // TextRectangle
// retrun false; — for cancel
}
});
```
@ -130,7 +141,7 @@ You can also define whether lists can give away, give and keep a copy (`clone`),
#### `sort` option
Sorting inside list
Sorting inside list.
Demo: http://jsbin.com/xizeh/2/edit?html,js,output
@ -138,6 +149,15 @@ Demo: http://jsbin.com/xizeh/2/edit?html,js,output
---
#### `delay` option
Time in milliseconds to define when the sorting should start.
Demo: http://jsbin.com/xizeh/4/edit?html,js,output
---
#### `disabled` options
Disables the sortable if set to `true`.
@ -603,6 +623,7 @@ Now you can use `jquery.fn.sortable.js`:<br/>
$("#list").sortable("{method-name}", "foo", "bar"); // call an instance method with parameters
```
And `grunt jquery:mySortableFunc` → `jquery.fn.mySortableFunc.js`
---

133
Sortable.js

@ -58,27 +58,6 @@
_silent = false,
_dispatchEvent = function (sortable, rootEl, name, targetEl, fromEl, startIndex, newIndex) {
var evt = document.createEvent('Event'),
options = (sortable || rootEl[expando]).options,
onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1);
evt.initEvent(name, true, true);
evt.item = targetEl || rootEl;
evt.from = fromEl || rootEl;
evt.clone = cloneEl;
evt.oldIndex = startIndex;
evt.newIndex = newIndex;
if (options[onName]) {
options[onName].call(sortable, evt);
}
rootEl.dispatchEvent(evt);
},
abs = Math.abs,
slice = [].slice,
@ -537,13 +516,13 @@
if (activeGroup && !options.disabled &&
(isOwner
? canSort || (revert = !rootEl.contains(dragEl))
? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list
: activeGroup.pull && groupPut && (
(activeGroup.name === group.name) || // by Name
(groupPut.indexOf && ~groupPut.indexOf(activeGroup.name)) // by Array
)
) &&
(evt.rootEl === void 0 || evt.rootEl === this.el)
(evt.rootEl === void 0 || evt.rootEl === this.el) // touch fallback
) {
// Smart auto-scrolling
_autoScroll(evt, options, this.el);
@ -582,9 +561,11 @@
_cloneHide(isOwner);
el.appendChild(dragEl);
this._animate(dragRect, dragEl);
target && this._animate(targetRect, target);
if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect) !== false) {
el.appendChild(dragEl);
this._animate(dragRect, dragEl);
target && this._animate(targetRect, target);
}
}
else if (target && !target.animated && target !== dragEl && (target.parentNode[expando] !== void 0)) {
if (lastEl !== target) {
@ -601,28 +582,34 @@
isLong = (target.offsetHeight > dragEl.offsetHeight),
halfway = (floating ? (evt.clientX - targetRect.left) / width : (evt.clientY - targetRect.top) / height) > 0.5,
nextSibling = target.nextElementSibling,
moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect),
after
;
_silent = true;
setTimeout(_unsilent, 30);
if (moveVector !== false) {
_silent = true;
setTimeout(_unsilent, 30);
_cloneHide(isOwner);
_cloneHide(isOwner);
if (floating) {
after = (target.previousElementSibling === dragEl) && !isWide || halfway && isWide;
} else {
after = (nextSibling !== dragEl) && !isLong || halfway && isLong;
}
if (moveVector === 1 || moveVector === -1) {
after = (moveVector === 1);
}
else if (floating) {
after = (target.previousElementSibling === dragEl) && !isWide || halfway && isWide;
} else {
after = (nextSibling !== dragEl) && !isLong || halfway && isLong;
}
if (after && !nextSibling) {
el.appendChild(dragEl);
} else {
target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
}
if (after && !nextSibling) {
el.appendChild(dragEl);
} else {
target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
}
this._animate(dragRect, dragEl);
this._animate(targetRect, target);
this._animate(dragRect, dragEl);
this._animate(targetRect, target);
}
}
}
},
@ -717,8 +704,13 @@
}
}
// Drag end event
Sortable.active && _dispatchEvent(this, rootEl, 'end', dragEl, rootEl, oldIndex, newIndex);
if (Sortable.active) {
// Drag end event
_dispatchEvent(this, rootEl, 'end', dragEl, rootEl, oldIndex, newIndex);
// Save sorting
this.save();
}
}
// Nulling
@ -739,9 +731,6 @@
activeGroup =
Sortable.active = null;
// Save sorting
this.save();
}
},
@ -986,6 +975,54 @@
}
function _dispatchEvent(sortable, rootEl, name, targetEl, fromEl, startIndex, newIndex) {
var evt = document.createEvent('Event'),
options = (sortable || rootEl[expando]).options,
onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1);
evt.initEvent(name, true, true);
evt.to = rootEl;
evt.from = fromEl || rootEl;
evt.item = targetEl || rootEl;
evt.clone = cloneEl;
evt.oldIndex = startIndex;
evt.newIndex = newIndex;
rootEl.dispatchEvent(evt);
if (options[onName]) {
options[onName].call(sortable, evt);
}
}
function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect) {
var evt,
sortable = fromEl[expando],
onMoveFn = sortable.options.onMove,
retVal;
if (onMoveFn) {
evt = document.createEvent('Event');
evt.initEvent('move', true, true);
evt.to = toEl;
evt.from = fromEl;
evt.dragged = dragEl;
evt.draggedRect = dragRect;
evt.related = targetEl || toEl;
evt.relatedRect = targetRect || toEl.getBoundingClientRect();
retVal = onMoveFn.call(sortable, evt);
}
return retVal;
}
function _disableDraggable(el) {
el.draggable = false;
}
@ -998,7 +1035,9 @@
/** @returns {HTMLElement|false} */
function _ghostInBottom(el, evt) {
var lastEl = el.lastElementChild, rect = lastEl.getBoundingClientRect();
var lastEl = el.lastElementChild,
rect = lastEl.getBoundingClientRect();
return (evt.clientY - (rect.top + rect.height) > 5) && lastEl; // min delta
}

37
ng-sortable.js

@ -64,11 +64,12 @@
// Export
return {
restrict: 'AC',
scope: { ngSortable: "=?" },
link: function (scope, $el, attrs) {
var el = $el[0],
ngSortable = attrs.ngSortable,
options = scope.$eval(ngSortable) || {},
options = scope.ngSortable || {},
source = getSource(el),
watchers = [],
sortable
;
@ -154,27 +155,29 @@
}));
$el.on('$destroy', function () {
angular.forEach(watchers, function (/** Function */unwatch) {
unwatch();
});
sortable.destroy();
watchers = null;
sortable = null;
nextSibling = null;
});
if (ngSortable && !/{|}/.test(ngSortable)) { // todo: ugly
angular.forEach([
'sort', 'disabled', 'draggable', 'handle', 'animation',
'onStart', 'onEnd', 'onAdd', 'onUpdate', 'onRemove', 'onSort'
], function (name) {
scope.$watch(ngSortable + '.' + name, function (value) {
if (value !== void 0) {
options[name] = value;
if (!/^on[A-Z]/.test(name)) {
sortable.option(name, value);
}
angular.forEach([
'sort', 'disabled', 'draggable', 'handle', 'animation',
'onStart', 'onEnd', 'onAdd', 'onUpdate', 'onRemove', 'onSort'
], function (name) {
watchers.push(scope.$watch('ngSortable.' + name, function (value) {
if (value !== void 0) {
options[name] = value;
if (!/^on[A-Z]/.test(name)) {
sortable.option(name, value);
}
});
});
}
}
}));
});
}
};
}]);

Loading…
Cancel
Save