From 609754fbad221d75f362f04ecf470207d4dca2e3 Mon Sep 17 00:00:00 2001 From: rlx <0x0073@0x2620.org> Date: Mon, 19 Dec 2011 17:19:54 +0000 Subject: [PATCH] fix select all --- source/Ox.UI/js/List/Ox.List.js | 202 ++++++++++++++++++-------------- 1 file changed, 117 insertions(+), 85 deletions(-) diff --git a/source/Ox.UI/js/List/Ox.List.js b/source/Ox.UI/js/List/Ox.List.js index a7cbb1bb..7153ec98 100644 --- a/source/Ox.UI/js/List/Ox.List.js +++ b/source/Ox.UI/js/List/Ox.List.js @@ -220,36 +220,29 @@ Ox.List = function(options, self) { } function addAllToSelection(pos) { - var arr, - len = self.$items.length; + var arr, i, len = self.$items.length; if (!isSelected(pos)) { if (self.selected.length == 0) { addToSelection(pos); } else { + arr = [pos]; if (Ox.min(self.selected) < pos) { - var arr = [pos]; - for (var i = pos - 1; i >= 0; i--) { + for (i = pos - 1; i >= 0; i--) { if (isSelected(i)) { - arr.forEach(function(v) { - addToSelection(v); - }); break; } arr.push(i); } } if (Ox.max(self.selected) > pos) { - var arr = [pos]; - for (var i = pos + 1; i < len; i++) { + for (i = pos + 1; i < len; i++) { if (isSelected(i)) { - arr.forEach(function(v) { - addToSelection(v); - }); break; } arr.push(i); } } + addToSelection(arr); } } } @@ -285,16 +278,20 @@ Ox.List = function(options, self) { } function addToSelection(pos) { - if (!isSelected(pos)) { - self.selected.push(pos); - !Ox.isUndefined(self.$items[pos]) && - self.$items[pos].addClass('OxSelected'); - triggerSelectEvent(); - } else { - // allow for 'cursor navigation' if orientation == 'both' - self.selected.splice(self.selected.indexOf(pos), 1); - self.selected.push(pos); - } + var triggerEvent = false; + Ox.toArray(pos).forEach(function(pos) { + if (!isSelected(pos)) { + self.selected.push(pos); + !Ox.isUndefined(self.$items[pos]) + && self.$items[pos].addClass('OxSelected'); + triggerEvent = true; + } else { + // allow for 'cursor navigation' if orientation == 'both' + self.selected.splice(self.selected.indexOf(pos), 1); + self.selected.push(pos); + } + }); + triggerEvent && triggerSelectEvent(); } function clear() { @@ -348,12 +345,16 @@ Ox.List = function(options, self) { } function deselect(pos) { - if (isSelected(pos)) { - self.selected.splice(self.selected.indexOf(pos), 1); - !Ox.isUndefined(self.$items[pos]) && - self.$items[pos].removeClass('OxSelected'); - triggerSelectEvent(); - } + var triggerEvent = false; + Ox.toArray(pos).forEach(function(pos) { + if (isSelected(pos)) { + self.selected.splice(self.selected.indexOf(pos), 1); + !Ox.isUndefined(self.$items[pos]) + && self.$items[pos].removeClass('OxSelected'); + triggerEvent = true; + } + }); + triggerEvent && triggerSelectEvent(); } function dragstart(data) { @@ -671,13 +672,40 @@ Ox.List = function(options, self) { ) * self.rowLength; } - function getSelectedIds() { + function getSelectedIds(callback) { + var ids = [], notFound = false; if (self.$items.length == 0) { - return self.options.selected; + callback(self.options.selected); } else { - return self.selected.map(function(pos) { - return self.$items[pos].options('data')[self.options.unique]; + Ox.forEach(self.selected, function(pos) { + if (self.$items[pos]) { + ids.push(self.$items[pos].options('data')[self.options.unique]); + } else { + notFound = true; + return false; + } }); + if (notFound) { + // selection across items that are not in the DOM + self.options.items({ + keys: [self.options.unique], + range: [0, self.listLength], + sort: self.options.sort + }, function(result) { + var ids = [], rest = [], + useRest = self.selected.length > self.listLength / 2; + result.data.items.forEach(function(item, i) { + if (self.selected.indexOf(i) > -1) { + ids.push(item[self.options.unique]); + } else if (useRest) { + rest.push(item[self.options.unique]); + } + }); + useRest ? callback(ids, rest) : callback(ids); + }); + } else { + callback(ids); + } } } @@ -687,9 +715,11 @@ Ox.List = function(options, self) { } function invertSelection() { - Ox.range(self.listLength).forEach(function(v) { - toggleSelection(v); + var arr = Ox.range(self.listLength).filter(function(pos) { + return !isSelected(pos); }); + selectNone(); + addToSelection(arr); } function isSelected(pos) { @@ -1155,9 +1185,7 @@ Ox.List = function(options, self) { } function selectAll() { - Ox.range(self.listLength).forEach(function(pos) { - addToSelection(pos); - }); + addToSelection(Ox.range(self.listLength)); } function selectBelow() { @@ -1177,9 +1205,7 @@ Ox.List = function(options, self) { } function selectNone() { - self.$items.forEach(function(v, i) { - deselect(i); - }); + deselect(Ox.range(self.listLength)); } function selectPrevious() { @@ -1238,6 +1264,7 @@ Ox.List = function(options, self) { } function toggleSelection(pos) { + // FIXME: unused if (!isSelected(pos)) { addToSelection(pos); } else { @@ -1255,21 +1282,24 @@ Ox.List = function(options, self) { } function triggerSelectEvent() { - var ids = self.options.selected = getSelectedIds(); - setTimeout(function() { - var ids_ = self.options.selected = getSelectedIds(); - // Ox.Log('List', 'ids', ids, 'ids after 100 msec', ids_, Ox.isEqual(ids, ids_)) - if (Ox.isEqual(ids, ids_)) { - that.triggerEvent('select', { - ids: ids + getSelectedIds(function(ids) { + self.options.selected = ids; + setTimeout(function() { + getSelectedIds(function(ids_, rest) { + self.options.selected = ids_; + if (Ox.isEqual(ids, ids_)) { + that.triggerEvent('select', Ox.extend({ + ids: ids + }, rest ? { + rest: rest + } : {})); + self.preview && that.triggerEvent('openpreview', { + ids: ids + }); + } }); - self.preview && that.triggerEvent('openpreview', { - ids: ids - }); - } else { - // Ox.Log('List', 'select event not triggered after timeout'); - } - }, 100); + }, 100); + }) } function triggerToggleEvent(expanded) { @@ -1360,15 +1390,16 @@ Ox.List = function(options, self) { function updateSelected() { //Ox.Log('List', 'updateSelected') - var oldSelectedIds = getSelectedIds(), - newSelectedIds = []; - Ox.forEach(self.options.items, function(item) { - if (oldSelectedIds.indexOf(item.id) > -1) { - newSelectedIds.push(item.id); - } - return newSelectedIds.length < oldSelectedIds.length; + getSelectedIds(function(oldIds) { + var newIds = []; + Ox.forEach(self.options.items, function(item) { + if (oldIds.indexOf(item.id) > -1) { + newIds.push(item.id); + } + return newIds.length < oldIds.length; + }); + setSelected(newIds); }); - setSelected(newSelectedIds); } function updateSort() { @@ -1379,30 +1410,31 @@ Ox.List = function(options, self) { sort = {}; //if (self.listLength > 1) { if (!self.isAsync) { - selectedIds = getSelectedIds(); - self.options.items.forEach(function(item) { - sort[item.id] = map ? map(item[key], item) : item[key]; - }); - self.options.items.sort(function(a, b) { - var aValue = sort[a.id], - bValue = sort[b.id], - ret = 0; - if (aValue < bValue) { - ret = operator == '+' ? -1 : 1; - } else if (aValue > bValue) { - ret = operator == '+' ? 1 : -1; - } - return ret; - }); - if (selectedIds.length) { - self.selected = []; - self.options.items.forEach(function(item, i) { - if (selectedIds.indexOf(item.id) > -1) { - self.selected.push(i); - } + getSelectedIds(function(selectedIds) { + self.options.items.forEach(function(item) { + sort[item.id] = map ? map(item[key], item) : item[key]; }); - } - loadItems(); + self.options.items.sort(function(a, b) { + var aValue = sort[a.id], + bValue = sort[b.id], + ret = 0; + if (aValue < bValue) { + ret = operator == '+' ? -1 : 1; + } else if (aValue > bValue) { + ret = operator == '+' ? 1 : -1; + } + return ret; + }); + if (selectedIds.length) { + self.selected = []; + self.options.items.forEach(function(item, i) { + if (selectedIds.indexOf(item.id) > -1) { + self.selected.push(i); + } + }); + } + loadItems(); + }); } else { clear(); // fixme: bad function name getPositions();