mirror of
https://github.com/TracksApp/tracks.git
synced 2025-09-22 05:50:47 +02:00
migrate context and context_list features. Drag and drop is still WIP
This commit is contained in:
parent
de309c8ee8
commit
4a8fdbabc2
12 changed files with 246 additions and 94 deletions
163
public/javascripts/jquery.simulate.drag-sortable.js
Normal file
163
public/javascripts/jquery.simulate.drag-sortable.js
Normal file
|
@ -0,0 +1,163 @@
|
|||
(function($) {
|
||||
/*
|
||||
* Simulate drag of a JQuery UI sortable list
|
||||
* Repository: https://github.com/mattheworiordan/jquery.simulate.drag-sortable.js
|
||||
* Author: http://mattheworiordan.com
|
||||
*
|
||||
* options are:
|
||||
* - move: move item up (positive) or down (negative) by Integer amount
|
||||
* - handle: selector for the draggable handle element (optional)
|
||||
* - listItem: selector to limit which sibling items can be used for reordering
|
||||
* - placeHolder: if a placeholder is used during dragging, we need to consider it's height
|
||||
*
|
||||
*/
|
||||
$.fn.simulateDragSortable = function(options) {
|
||||
// build main options before element iteration
|
||||
var opts = $.extend({}, $.fn.simulateDragSortable.defaults, options);
|
||||
|
||||
// iterate and move each matched element
|
||||
return this.each(function() {
|
||||
// allow for a drag handle if item is not draggable
|
||||
var that = this,
|
||||
handle = opts.handle ? $(this).find(opts.handle)[0] : $(this)[0],
|
||||
listItem = opts.listItem,
|
||||
placeHolder = opts.placeHolder,
|
||||
sibling = $(this),
|
||||
moveCounter = Math.floor(opts.move),
|
||||
direction = moveCounter > 0 ? 'down' : 'up',
|
||||
moveVerticalAmount = 0,
|
||||
dragPastBy = 0;
|
||||
|
||||
if (moveCounter === 0) { return; }
|
||||
|
||||
while (moveCounter !== 0) {
|
||||
if (direction === 'down') {
|
||||
if (sibling.next(listItem).length) {
|
||||
sibling = sibling.next(listItem);
|
||||
moveVerticalAmount += sibling.outerHeight();
|
||||
}
|
||||
moveCounter -= 1;
|
||||
} else {
|
||||
if (sibling.prev(listItem).length) {
|
||||
sibling = sibling.prev(listItem);
|
||||
moveVerticalAmount -= sibling.outerHeight();
|
||||
}
|
||||
moveCounter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
var center = findCenter(handle);
|
||||
var x = Math.floor(center.x), y = Math.floor(center.y);
|
||||
dispatchEvent(handle, 'mousedown', createEvent('mousedown', handle, { clientX: x, clientY: y }));
|
||||
// simulate drag start
|
||||
dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x+1, clientY: y+1 }));
|
||||
|
||||
// Sortable is using a fixed height placeholder meaning items jump up and down as you drag variable height items into fixed height placeholder
|
||||
placeHolder = placeHolder && $(this).parent().find(placeHolder);
|
||||
if (placeHolder && placeHolder.length) {
|
||||
// we're going to move past it, and back again
|
||||
moveVerticalAmount += (direction === 'down' ? -1 : 1) * Math.min($(this).outerHeight() / 2, 5);
|
||||
// Sortable UI bug when dragging down and place holder exists. You need to drag past by the total height of this
|
||||
// and then drag back to the right point
|
||||
dragPastBy = (direction === 'down' ? 1 : -1) * $(this).outerHeight() / 2;
|
||||
} else {
|
||||
// no place holder
|
||||
if (direction === 'down') {
|
||||
// need to move at least as far as this item and or the last sibling
|
||||
if ($(this).outerHeight() > $(sibling).outerHeight()) {
|
||||
moveVerticalAmount += $(this).outerHeight() - $(sibling).outerHeight();
|
||||
}
|
||||
moveVerticalAmount += $(sibling).outerHeight() / 2;
|
||||
} else {
|
||||
// move a little extra to ensure item clips into next position
|
||||
moveVerticalAmount -= Math.min($(this).outerHeight() / 2, 5);
|
||||
}
|
||||
}
|
||||
|
||||
if (sibling[0] !== $(this)[0]) {
|
||||
// step through so that the UI controller can determine when to show the placeHolder
|
||||
var targetOffset = moveVerticalAmount + dragPastBy;
|
||||
for (var offset = 0; Math.abs(offset) < Math.abs(targetOffset); offset += (direction === 'down' ? 10 : -10)) {
|
||||
// drag move
|
||||
dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + offset }));
|
||||
}
|
||||
dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + targetOffset }));
|
||||
} else {
|
||||
if (window.console) {
|
||||
console.log('Could not move as at top or bottom already');
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + moveVerticalAmount }));
|
||||
}, 5);
|
||||
setTimeout(function() {
|
||||
dispatchEvent(handle, 'mouseup', createEvent('mouseup', handle, { clientX: x, clientY: y + moveVerticalAmount }));
|
||||
}, 10);
|
||||
});
|
||||
};
|
||||
|
||||
function createEvent(type, target, options) {
|
||||
var evt;
|
||||
var e = $.extend({
|
||||
target: target,
|
||||
preventDefault: function() { },
|
||||
stopImmediatePropagation: function() { },
|
||||
stopPropagation: function() { },
|
||||
isPropagationStopped: function() { return true; },
|
||||
isImmediatePropagationStopped: function() { return true; },
|
||||
isDefaultPrevented: function() { return true; },
|
||||
bubbles: true,
|
||||
cancelable: (type != "mousemove"),
|
||||
view: window,
|
||||
detail: 0,
|
||||
screenX: 0,
|
||||
screenY: 0,
|
||||
clientX: 0,
|
||||
clientY: 0,
|
||||
ctrlKey: false,
|
||||
altKey: false,
|
||||
shiftKey: false,
|
||||
metaKey: false,
|
||||
button: 0,
|
||||
relatedTarget: undefined
|
||||
}, options || {});
|
||||
|
||||
if ($.isFunction(document.createEvent)) {
|
||||
evt = document.createEvent("MouseEvents");
|
||||
evt.initMouseEvent(type, e.bubbles, e.cancelable, e.view, e.detail,
|
||||
e.screenX, e.screenY, e.clientX, e.clientY,
|
||||
e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
|
||||
e.button, e.relatedTarget || document.body.parentNode);
|
||||
} else if (document.createEventObject) {
|
||||
evt = document.createEventObject();
|
||||
$.extend(evt, e);
|
||||
evt.button = { 0:1, 1:4, 2:2 }[evt.button] || evt.button;
|
||||
}
|
||||
return evt;
|
||||
}
|
||||
|
||||
function dispatchEvent(el, type, evt) {
|
||||
if (el.dispatchEvent) {
|
||||
el.dispatchEvent(evt);
|
||||
} else if (el.fireEvent) {
|
||||
el.fireEvent('on' + type, evt);
|
||||
}
|
||||
return evt;
|
||||
}
|
||||
|
||||
function findCenter(el) {
|
||||
var el = $(el), o = el.offset();
|
||||
return {
|
||||
x: o.left + el.outerWidth() / 2,
|
||||
y: o.top + el.outerHeight() / 2
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// plugin defaults
|
||||
//
|
||||
$.fn.simulateDragSortable.defaults = {
|
||||
move: 0
|
||||
};
|
||||
})(jQuery);
|
Loading…
Add table
Add a link
Reference in a new issue