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