Ox.List: add support for moving a (potentially discontinuous) selection of multiple items

This commit is contained in:
rlx 2013-07-17 10:20:24 +00:00
parent 654850f0b9
commit 60bf786a3a

View file

@ -649,7 +649,6 @@ Ox.List = function(options, self) {
} }
function getPositionById(id) { function getPositionById(id) {
// fixme: is this really needed?
var pos = -1; var pos = -1;
Ox.forEach(self.$items, function($item, i) { Ox.forEach(self.$items, function($item, i) {
if ($item.options('data')[self.options.unique] == id) { if ($item.options('data')[self.options.unique] == id) {
@ -934,62 +933,89 @@ Ox.List = function(options, self) {
} }
function movestart(data) { function movestart(data) {
self.drag = { var pos = findItemPosition(data),
pos: findItemPosition(data) $items = self.$items.filter(function($item, i) {
}; if ($item.is('.OxSelected')) {
Ox.extend(self.drag, { $item.addClass('OxDrag');
id: self.$items[self.drag.pos].options('data')[self.options.unique], return true;
startPos: self.drag.pos, }
startY: data.clientY, return false;
stopPos: self.drag.pos
});
self.$items[self.drag.pos]
.addClass('OxDrag')
.css({
cursor: 'move'
}); });
self.drag = {
$items: $items,
index: Ox.indexOf($items, function($item) {
return $item.options('position') == pos;
}),
length: $items.length,
startPos: pos,
startY: data.clientY,
stopPos: pos
};
} }
function move(data) { function move(data) {
var clientY = data.clientY - that.offset()['top'], var clientY = data.clientY - that.offset().top,
offset = clientY % 16, offset = clientY % 16,
position = Ox.limit(Math.floor(clientY / 16), 0, self.$items.length - 1); position = Ox.limit(
if (position < self.drag.pos) { Math.floor(clientY / 16),
0, self.$items.length - 1
);
if (position < self.drag.startPos) {
self.drag.stopPos = position + (offset > 8 ? 1 : 0); self.drag.stopPos = position + (offset > 8 ? 1 : 0);
} else if (position > self.drag.pos) { } else if (position > self.drag.startPos) {
self.drag.stopPos = position - (offset <= 8 ? 1 : 0); self.drag.stopPos = position - (offset <= 8 ? 1 : 0);
} }
if (self.drag.stopPos != self.drag.pos) { if (self.drag.stopPos != self.drag.startPos) {
moveItem(self.drag.pos, self.drag.stopPos); moveItems(self.drag.startPos, self.drag.stopPos);
self.drag.pos = self.drag.stopPos; self.drag.startPos = self.drag.stopPos;
} }
} }
function moveend(data) { function moveend(data) {
self.$items[self.drag.pos] var ids = [];
.removeClass('OxDrag') self.$items.forEach(function($item) {
.css({ $item.removeClass('OxDrag');
cursor: 'default' ids.push($item.options('data')[self.options.unique]);
});
that.triggerEvent('move', {
ids: self.$items.map(function($item) {
return $item.options('data')[self.options.unique];
})
}); });
that.triggerEvent('move', {ids: ids});
delete self.drag; delete self.drag;
} }
function moveItem(startPos, stopPos) { function moveItems(startPos, stopPos) {
var $item = self.$items[startPos], var pos = stopPos;
insert = startPos < stopPos ? 'insertAfter' : 'insertBefore'; while (self.$items[pos].is('.OxSelected')) {
$item.detach()[insert](self.$items[stopPos].$element); // fixme: why do we need .$element here? pos = pos + (pos < startPos ? -1 : 1);
//Ox.Log('List', 'moveItem', startPos, stopPos, insert, self.ids); if (pos < 0 || pos > self.$items.length - 1) {
var $item = self.$items.splice(startPos, 1)[0]; // handle item can still be moved, but group cannot
self.$items.splice(stopPos, 0, $item); return;
}
}
self.drag.$items.forEach(function($item) {
$item.detach();
});
self.drag.$items.forEach(function($item, i) {
if (i == 0) {
$item[
pos < startPos ? 'insertBefore' : 'insertAfter'
](self.$items[pos].$element); // fixme: shouldn't require $element
} else {
$item.insertAfter(self.drag.$items[i - 1]);
}
});
self.drag.$items.forEach(function($item, i) {
self.$items.splice($item.options('position') - i, 1);
});
self.$items.splice.apply(
self.$items,
[stopPos - self.drag.index, 0].concat(self.drag.$items)
);
self.$items.forEach(function($item, pos) { self.$items.forEach(function($item, pos) {
$item.options({position: pos}); $item.options({position: pos});
}); });
self.selected = [stopPos]; self.selected = [];
self.drag.$items.forEach(function($item) {
self.selected.push($item.options('position'));
});
} }
function open(isSpecialTarget) { function open(isSpecialTarget) {