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: { jquery: {
files: { files: {}
'jquery.fn.sortable.min.js': 'jquery.fn.sortable.js'
}
} }
}, },
@ -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'), var fs = require('fs'),
filename = 'jquery.fn.sortable.js'; filename = 'jquery.fn.' + exportName + '.js';
grunt.log.oklns(filename); grunt.log.oklns(filename);
fs.writeFileSync( fs.writeFileSync(
filename, filename,
(fs.readFileSync('jquery.binding.js') + '') (fs.readFileSync('jquery.binding.js') + '')
.replace('$.fn.sortable', '$.fn.' + exportName)
.replace('/* CODE */', .replace('/* CODE */',
(fs.readFileSync('Sortable.js') + '') (fs.readFileSync('Sortable.js') + '')
.replace(/^[\s\S]*?function[\s\S]*?(var[\s\S]+)\/\/\s+Export[\s\S]+/, '$1') .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'); 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, { var sortable = new Sortable(el, {
group: "name", // or { name: "...", pull: [true, false, clone], put: [true, false, array] } group: "name", // or { name: "...", pull: [true, false, clone], put: [true, false, array] }
sort: true, // sorting inside list 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. disabled: false, // Disables the sortable if set to true.
store: null, // @see Store store: null, // @see Store
animation: 150, // ms, animation speed moving items when sorting, `0` — without animation 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 // 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.
},
// 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 #### `sort` option
Sorting inside list Sorting inside list.
Demo: http://jsbin.com/xizeh/2/edit?html,js,output 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 #### `disabled` options
Disables the sortable if set to `true`. 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 $("#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, _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, abs = Math.abs,
slice = [].slice, slice = [].slice,
@ -537,13 +516,13 @@
if (activeGroup && !options.disabled && if (activeGroup && !options.disabled &&
(isOwner (isOwner
? canSort || (revert = !rootEl.contains(dragEl)) ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list
: activeGroup.pull && groupPut && ( : activeGroup.pull && groupPut && (
(activeGroup.name === group.name) || // by Name (activeGroup.name === group.name) || // by Name
(groupPut.indexOf && ~groupPut.indexOf(activeGroup.name)) // by Array (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 // Smart auto-scrolling
_autoScroll(evt, options, this.el); _autoScroll(evt, options, this.el);
@ -582,9 +561,11 @@
_cloneHide(isOwner); _cloneHide(isOwner);
el.appendChild(dragEl); if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect) !== false) {
this._animate(dragRect, dragEl); el.appendChild(dragEl);
target && this._animate(targetRect, target); this._animate(dragRect, dragEl);
target && this._animate(targetRect, target);
}
} }
else if (target && !target.animated && target !== dragEl && (target.parentNode[expando] !== void 0)) { else if (target && !target.animated && target !== dragEl && (target.parentNode[expando] !== void 0)) {
if (lastEl !== target) { if (lastEl !== target) {
@ -601,28 +582,34 @@
isLong = (target.offsetHeight > dragEl.offsetHeight), isLong = (target.offsetHeight > dragEl.offsetHeight),
halfway = (floating ? (evt.clientX - targetRect.left) / width : (evt.clientY - targetRect.top) / height) > 0.5, halfway = (floating ? (evt.clientX - targetRect.left) / width : (evt.clientY - targetRect.top) / height) > 0.5,
nextSibling = target.nextElementSibling, nextSibling = target.nextElementSibling,
moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect),
after after
; ;
_silent = true; if (moveVector !== false) {
setTimeout(_unsilent, 30); _silent = true;
setTimeout(_unsilent, 30);
_cloneHide(isOwner); _cloneHide(isOwner);
if (floating) { if (moveVector === 1 || moveVector === -1) {
after = (target.previousElementSibling === dragEl) && !isWide || halfway && isWide; after = (moveVector === 1);
} else { }
after = (nextSibling !== dragEl) && !isLong || halfway && isLong; else if (floating) {
} after = (target.previousElementSibling === dragEl) && !isWide || halfway && isWide;
} else {
after = (nextSibling !== dragEl) && !isLong || halfway && isLong;
}
if (after && !nextSibling) { if (after && !nextSibling) {
el.appendChild(dragEl); el.appendChild(dragEl);
} else { } else {
target.parentNode.insertBefore(dragEl, after ? nextSibling : target); target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
} }
this._animate(dragRect, dragEl); this._animate(dragRect, dragEl);
this._animate(targetRect, target); this._animate(targetRect, target);
}
} }
} }
}, },
@ -717,8 +704,13 @@
} }
} }
// Drag end event if (Sortable.active) {
Sortable.active && _dispatchEvent(this, rootEl, 'end', dragEl, rootEl, oldIndex, newIndex); // Drag end event
_dispatchEvent(this, rootEl, 'end', dragEl, rootEl, oldIndex, newIndex);
// Save sorting
this.save();
}
} }
// Nulling // Nulling
@ -739,9 +731,6 @@
activeGroup = activeGroup =
Sortable.active = null; 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) { function _disableDraggable(el) {
el.draggable = false; el.draggable = false;
} }
@ -998,7 +1035,9 @@
/** @returns {HTMLElement|false} */ /** @returns {HTMLElement|false} */
function _ghostInBottom(el, evt) { 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 return (evt.clientY - (rect.top + rect.height) > 5) && lastEl; // min delta
} }

37
ng-sortable.js

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

Loading…
Cancel
Save