_RowMapLayer.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
  3. Available via Academic Free License >= 2.1 OR the modified BSD license.
  4. see: http://dojotoolkit.org/license for details
  5. */
  6. if(!dojo._hasResource["dojox.grid.enhanced.plugins._RowMapLayer"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
  7. dojo._hasResource["dojox.grid.enhanced.plugins._RowMapLayer"] = true;
  8. dojo.provide("dojox.grid.enhanced.plugins._RowMapLayer");
  9. dojo.require("dojox.grid.enhanced.plugins._StoreLayer");
  10. (function(){
  11. var _devideToArrays = function(a){
  12. a.sort(function(v1, v2){
  13. return v1 - v2;
  14. });
  15. var arr = [[a[0]]];
  16. for(var i = 1, j = 0; i < a.length; ++i){
  17. if(a[i] == a[i-1] + 1){
  18. arr[j].push(a[i]);
  19. }else{
  20. arr[++j] = [a[i]];
  21. }
  22. }
  23. return arr;
  24. },
  25. hitchIfCan = function(scope, func){
  26. return func ? dojo.hitch(scope || dojo.global, func) : function(){};
  27. };
  28. dojo.declare("dojox.grid.enhanced.plugins._RowMapLayer", dojox.grid.enhanced.plugins._StoreLayer, {
  29. tags: ["reorder"],
  30. constructor: function(grid){
  31. this._map = {};
  32. this._revMap = {};
  33. this.grid = grid;
  34. this._oldOnDelete = grid._onDelete;
  35. var _this = this;
  36. grid._onDelete = function(item){
  37. _this._onDelete(item);
  38. _this._oldOnDelete.call(grid, item);
  39. };
  40. this._oldSort = grid.sort;
  41. grid.sort = function(){
  42. _this.clearMapping();
  43. _this._oldSort.apply(grid, arguments);
  44. };
  45. },
  46. uninitialize: function(){
  47. this.grid._onDelete = this._oldOnDelete;
  48. this.grid.sort = this._oldSort;
  49. },
  50. setMapping: function(mapping){
  51. // summary:
  52. // Remember the row mapping.
  53. // mapping: Object
  54. // keys are original rowIndexes, values are new rowIndexes.
  55. this._store.forEachLayer(function(layer){
  56. if(layer.name() === "rowmap"){
  57. return false;
  58. }else if(layer.onRowMappingChange){
  59. layer.onRowMappingChange(mapping);
  60. }
  61. return true;
  62. }, false);
  63. var from, to, origin, revmap = {};
  64. for(from in mapping){
  65. from = parseInt(from, 10);
  66. to = mapping[from];
  67. if(typeof to == "number"){
  68. if(from in this._revMap){
  69. origin = this._revMap[from];
  70. delete this._revMap[from];
  71. }else{
  72. origin = from;
  73. }
  74. if(origin == to){
  75. delete this._map[origin];
  76. revmap[to] = "eq";
  77. }else{
  78. this._map[origin] = to;
  79. revmap[to] = origin;
  80. }
  81. }
  82. }
  83. for(to in revmap){
  84. if(revmap[to] === "eq"){
  85. delete this._revMap[parseInt(to, 10)];
  86. }else{
  87. this._revMap[parseInt(to, 10)] = revmap[to];
  88. }
  89. }
  90. },
  91. clearMapping: function(){
  92. this._map = {};
  93. this._revMap = {};
  94. },
  95. _onDelete: function(item){
  96. var idx = this.grid._getItemIndex(item, true);
  97. if(idx in this._revMap){
  98. var rowIdxArr = [], r, i, origin = this._revMap[idx];
  99. delete this._map[origin];
  100. delete this._revMap[idx];
  101. for(r in this._revMap){
  102. r = parseInt(r, 10);
  103. if(this._revMap[r] > origin){
  104. --this._revMap[r];
  105. }
  106. }
  107. for(r in this._revMap){
  108. r = parseInt(r, 10);
  109. if(r > idx){
  110. rowIdxArr.push(r);
  111. }
  112. }
  113. rowIdxArr.sort(function(a, b){
  114. return b - a;
  115. });
  116. for(i = rowIdxArr.length - 1; i >= 0; --i){
  117. r = rowIdxArr[i];
  118. this._revMap[r - 1] = this._revMap[r];
  119. delete this._revMap[r];
  120. }
  121. this._map = {};
  122. for(r in this._revMap){
  123. this._map[this._revMap[r]] = r;
  124. }
  125. }
  126. },
  127. _fetch: function(userRequest){
  128. var mapCount = 0, r;
  129. var start = userRequest.start || 0;
  130. for(r in this._revMap){
  131. r = parseInt(r, 10);
  132. if(r >= start){
  133. ++mapCount;
  134. }
  135. }
  136. if(mapCount > 0){
  137. //Row mapping is in use.
  138. var rows = [], i, map = {},
  139. count = userRequest.count > 0 ? userRequest.count : -1;
  140. if(count > 0){
  141. for(i = 0; i < count; ++i){
  142. r = start + i;
  143. r = r in this._revMap ? this._revMap[r] : r;
  144. map[r] = i;
  145. rows.push(r);
  146. }
  147. }else{
  148. //We don't have a count, must create our own.
  149. for(i = 0;; ++i){
  150. r = start + i;
  151. if(r in this._revMap){
  152. --mapCount;
  153. r = this._revMap[r];
  154. }
  155. map[r] = i;
  156. rows.push(r);
  157. if(mapCount <= 0){
  158. break;
  159. }
  160. }
  161. }
  162. this._subFetch(userRequest, this._getRowArrays(rows), 0, [], map, userRequest.onComplete, start, count);
  163. return userRequest;
  164. }else{
  165. //No row mapping at all.
  166. return dojo.hitch(this._store, this._originFetch)(userRequest);
  167. }
  168. },
  169. _getRowArrays: function(rows){
  170. return _devideToArrays(rows);
  171. },
  172. _subFetch: function(userRequest, rowArrays, index, result, map, oldOnComplete, start, count){
  173. var arr = rowArrays[index], _this = this;
  174. var urstart = userRequest.start = arr[0];
  175. userRequest.count = arr[arr.length - 1] - arr[0] + 1;
  176. userRequest.onComplete = function(items){
  177. dojo.forEach(items, function(item, i){
  178. var r = urstart + i;
  179. if(r in map){
  180. result[map[r]] = item;
  181. }
  182. });
  183. if(++index == rowArrays.length){
  184. //mapped rows are all fetched.
  185. if(count > 0){
  186. userRequest.start = start;
  187. userRequest.count = count;
  188. userRequest.onComplete = oldOnComplete;
  189. hitchIfCan(userRequest.scope, oldOnComplete)(result, userRequest);
  190. }else{
  191. userRequest.start = userRequest.start + items.length;
  192. delete userRequest.count;
  193. userRequest.onComplete = function(items){
  194. result = result.concat(items);
  195. userRequest.start = start;
  196. userRequest.onComplete = oldOnComplete;
  197. hitchIfCan(userRequest.scope, oldOnComplete)(result, userRequest);
  198. };
  199. _this.originFetch(userRequest);
  200. }
  201. }else{
  202. _this._subFetch(userRequest, rowArrays, index, result, map, oldOnComplete, start, count);
  203. }
  204. };
  205. _this.originFetch(userRequest);
  206. }
  207. });
  208. })();
  209. }