summaryrefslogtreecommitdiff
path: root/js/dojo/dojox/grid/enhanced/plugins/Rearrange.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo/dojox/grid/enhanced/plugins/Rearrange.js')
-rw-r--r--js/dojo/dojox/grid/enhanced/plugins/Rearrange.js506
1 files changed, 506 insertions, 0 deletions
diff --git a/js/dojo/dojox/grid/enhanced/plugins/Rearrange.js b/js/dojo/dojox/grid/enhanced/plugins/Rearrange.js
new file mode 100644
index 0000000..1c3bac3
--- /dev/null
+++ b/js/dojo/dojox/grid/enhanced/plugins/Rearrange.js
@@ -0,0 +1,506 @@
+//>>built
+define("dojox/grid/enhanced/plugins/Rearrange", [
+ "dojo/_base/kernel",
+ "dojo/_base/lang",
+ "dojo/_base/declare",
+ "dojo/_base/array",
+ "dojo/_base/connect",
+ "../../EnhancedGrid",
+ "../_Plugin",
+ "./_RowMapLayer"
+], function(dojo, lang, declare, array, connect, EnhancedGrid, _Plugin, _RowMapLayer){
+
+var Rearrange = declare("dojox.grid.enhanced.plugins.Rearrange", _Plugin, {
+ // summary:
+ // Provides a set of method to re-arrange the structure of grid.
+
+ // name: String
+ // plugin name
+ name: "rearrange",
+
+ constructor: function(grid, args){
+ this.grid = grid;
+ this.setArgs(args);
+ var rowMapLayer = new _RowMapLayer(grid);
+ dojox.grid.enhanced.plugins.wrap(grid, "_storeLayerFetch", rowMapLayer);
+ },
+ setArgs: function(args){
+ this.args = lang.mixin(this.args || {}, args || {});
+ this.args.setIdentifierForNewItem = this.args.setIdentifierForNewItem || function(v){return v;};
+ },
+ destroy: function(){
+ this.inherited(arguments);
+ this.grid.unwrap("rowmap");
+ },
+ onSetStore: function(store){
+ this.grid.layer("rowmap").clearMapping();
+ },
+ _hasIdentity: function(points){
+ var g = this.grid, s = g.store, cells = g.layout.cells;
+ if(s.getFeatures()["dojo.data.api.Identity"]){
+ if(array.some(points, function(point){
+ return s.getIdentityAttributes(g._by_idx[point.r].item) == cells[point.c].field;
+ })){
+ return true;
+ }
+ }
+ return false;
+ },
+ moveColumns: function(colsToMove, targetPos){
+ // summary:
+ // Move a set of columns to a given position.
+ // tag:
+ // public
+ // colsToMove: Integer[]
+ // Array of column indexes.
+ // targetPos: Integer
+ // The target position
+ var g = this.grid,
+ layout = g.layout,
+ cells = layout.cells,
+ colIndex, i, delta = 0,
+ before = true, tmp = {}, mapping = {};
+ colsToMove.sort(function(a, b){
+ return a - b;
+ });
+ for(i = 0; i < colsToMove.length; ++i){
+ tmp[colsToMove[i]] = i;
+ if(colsToMove[i] < targetPos){
+ ++delta;
+ }
+ }
+ var leftCount = 0, rightCount = 0;
+ var maxCol = Math.max(colsToMove[colsToMove.length - 1], targetPos);
+ if(maxCol == cells.length){
+ --maxCol;
+ }
+ var minCol = Math.min(colsToMove[0], targetPos);
+ for(i = minCol; i <= maxCol; ++i){
+ var j = tmp[i];
+ if(j >= 0){
+ mapping[i] = targetPos - delta + j;
+ }else if(i < targetPos){
+ mapping[i] = minCol + leftCount;
+ ++leftCount;
+ }else if(i >= targetPos){
+ mapping[i] = targetPos + colsToMove.length - delta + rightCount;
+ ++rightCount;
+ }
+ }
+ //console.log("mapping:", mapping, ", colsToMove:", colsToMove,", target:", targetPos);
+ delta = 0;
+ if(targetPos == cells.length){
+ --targetPos;
+ before = false;
+ }
+ g._notRefreshSelection = true;
+ for(i = 0; i < colsToMove.length; ++i){
+ colIndex = colsToMove[i];
+ if(colIndex < targetPos){
+ colIndex -= delta;
+ }
+ ++delta;
+ if(colIndex != targetPos){
+ layout.moveColumn(cells[colIndex].view.idx, cells[targetPos].view.idx, colIndex, targetPos, before);
+ cells = layout.cells;
+ }
+ if(targetPos <= colIndex){
+ ++targetPos;
+ }
+ }
+ delete g._notRefreshSelection;
+ connect.publish("dojox/grid/rearrange/move/" + g.id, ["col", mapping, colsToMove]);
+ },
+ moveRows: function(rowsToMove, targetPos){
+ // summary:
+ // Move a set of rows to a given position
+ // tag:
+ // public
+ // rowsToMove: Integer[]
+ // Array of row indexes.
+ // targetPos: Integer
+ // The target position
+ var g = this.grid,
+ mapping = {},
+ preRowsToMove = [],
+ postRowsToMove = [],
+ len = rowsToMove.length,
+ i, r, k, arr, rowMap, lastPos;
+
+ for(i = 0; i < len; ++i){
+ r = rowsToMove[i];
+ if(r >= targetPos){
+ break;
+ }
+ preRowsToMove.push(r);
+ }
+ postRowsToMove = rowsToMove.slice(i);
+
+ arr = preRowsToMove;
+ len = arr.length;
+ if(len){
+ rowMap = {};
+ array.forEach(arr, function(r){
+ rowMap[r] = true;
+ });
+ mapping[arr[0]] = targetPos - len;
+ for(k = 0, i = arr[k] + 1, lastPos = i - 1; i < targetPos; ++i){
+ if(!rowMap[i]){
+ mapping[i] = lastPos;
+ ++lastPos;
+ }else{
+ ++k;
+ mapping[i] = targetPos - len + k;
+ }
+ }
+ }
+ arr = postRowsToMove;
+ len = arr.length;
+ if(len){
+ rowMap = {};
+ array.forEach(arr, function(r){
+ rowMap[r] = true;
+ });
+ mapping[arr[len - 1]] = targetPos + len - 1;
+ for(k = len - 1, i = arr[k] - 1, lastPos = i + 1; i >= targetPos; --i){
+ if(!rowMap[i]){
+ mapping[i] = lastPos;
+ --lastPos;
+ }else{
+ --k;
+ mapping[i] = targetPos + k;
+ }
+ }
+ }
+ var tmpMapping = lang.clone(mapping);
+ g.layer("rowmap").setMapping(mapping);
+ g.forEachLayer(function(layer){
+ if(layer.name() != "rowmap"){
+ layer.invalidate();
+ return true;
+ }else{
+ return false;
+ }
+ }, false);
+ g.selection.selected = [];
+ g._noInternalMapping = true;
+ g._refresh();
+ setTimeout(function(){
+ connect.publish("dojox/grid/rearrange/move/" + g.id, ["row", tmpMapping, rowsToMove]);
+ g._noInternalMapping = false;
+ }, 0);
+ },
+ moveCells: function(cellsToMove, target){
+ var g = this.grid,
+ s = g.store;
+ if(s.getFeatures()["dojo.data.api.Write"]){
+ if(cellsToMove.min.row == target.min.row && cellsToMove.min.col == target.min.col){
+ //Same position, no need to move
+ return;
+ }
+ var cells = g.layout.cells,
+ cnt = cellsToMove.max.row - cellsToMove.min.row + 1,
+ r, c, tr, tc,
+ sources = [], targets = [];
+ for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){
+ for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){
+ while(cells[c] && cells[c].hidden){
+ ++c;
+ }
+ while(cells[tc] && cells[tc].hidden){
+ ++tc;
+ }
+ sources.push({
+ "r": r,
+ "c": c
+ });
+ targets.push({
+ "r": tr,
+ "c": tc,
+ "v": cells[c].get(r, g._by_idx[r].item)
+ });
+ }
+ }
+ if(this._hasIdentity(sources.concat(targets))){
+ console.warn("Can not write to identity!");
+ return;
+ }
+ array.forEach(sources, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, "");
+ });
+ array.forEach(targets, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v);
+ });
+ s.save({
+ onComplete: function(){
+ connect.publish("dojox/grid/rearrange/move/" + g.id, ["cell", {
+ "from": cellsToMove,
+ "to": target
+ }]);
+ }
+ });
+ }
+ },
+ copyCells: function(cellsToMove, target){
+ var g = this.grid,
+ s = g.store;
+ if(s.getFeatures()["dojo.data.api.Write"]){
+ if(cellsToMove.min.row == target.min.row && cellsToMove.min.col == target.min.col){
+ return;
+ }
+ var cells = g.layout.cells,
+ cnt = cellsToMove.max.row - cellsToMove.min.row + 1,
+ r, c, tr, tc,
+ targets = [];
+ for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){
+ for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){
+ while(cells[c] && cells[c].hidden){
+ ++c;
+ }
+ while(cells[tc] && cells[tc].hidden){
+ ++tc;
+ }
+ targets.push({
+ "r": tr,
+ "c": tc,
+ "v": cells[c].get(r, g._by_idx[r].item)
+ });
+ }
+ }
+ if(this._hasIdentity(targets)){
+ console.warn("Can not write to identity!");
+ return;
+ }
+ array.forEach(targets, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v);
+ });
+ s.save({
+ onComplete: function(){
+ setTimeout(function(){
+ connect.publish("dojox/grid/rearrange/copy/" + g.id, ["cell", {
+ "from": cellsToMove,
+ "to": target
+ }]);
+ }, 0);
+ }
+ });
+ }
+ },
+ changeCells: function(sourceGrid, cellsToMove, target){
+ var g = this.grid,
+ s = g.store;
+ if(s.getFeatures()["dojo.data.api.Write"]){
+ var srcg = sourceGrid,
+ cells = g.layout.cells,
+ srccells = srcg.layout.cells,
+ cnt = cellsToMove.max.row - cellsToMove.min.row + 1,
+ r, c, tr, tc, targets = [];
+ for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){
+ for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){
+ while(srccells[c] && srccells[c].hidden){
+ ++c;
+ }
+ while(cells[tc] && cells[tc].hidden){
+ ++tc;
+ }
+ targets.push({
+ "r": tr,
+ "c": tc,
+ "v": srccells[c].get(r, srcg._by_idx[r].item)
+ });
+ }
+ }
+ if(this._hasIdentity(targets)){
+ console.warn("Can not write to identity!");
+ return;
+ }
+ array.forEach(targets, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, point.v);
+ });
+ s.save({
+ onComplete: function(){
+ connect.publish("dojox/grid/rearrange/change/" + g.id, ["cell", target]);
+ }
+ });
+ }
+ },
+ clearCells: function(cellsToClear){
+ var g = this.grid,
+ s = g.store;
+ if(s.getFeatures()["dojo.data.api.Write"]){
+ var cells = g.layout.cells,
+ cnt = cellsToClear.max.row - cellsToClear.min.row + 1,
+ r, c, targets = [];
+ for(r = cellsToClear.min.row; r <= cellsToClear.max.row; ++r){
+ for(c = cellsToClear.min.col; c <= cellsToClear.max.col; ++c){
+ while(cells[c] && cells[c].hidden){
+ ++c;
+ }
+ targets.push({
+ "r": r,
+ "c": c
+ });
+ }
+ }
+ if(this._hasIdentity(targets)){
+ console.warn("Can not write to identity!");
+ return;
+ }
+ array.forEach(targets, function(point){
+ s.setValue(g._by_idx[point.r].item, cells[point.c].field, "");
+ });
+ s.save({
+ onComplete: function(){
+ connect.publish("dojox/grid/rearrange/change/" + g.id, ["cell", cellsToClear]);
+ }
+ });
+ }
+ },
+ insertRows: function(sourceGrid, rowsToMove, targetPos){
+ try{
+ var g = this.grid,
+ s = g.store,
+ rowCnt = g.rowCount,
+ mapping = {},
+ obj = {idx: 0},
+ newRows = [], i,
+ emptyTarget = targetPos < 0;
+ _this = this;
+ var len = rowsToMove.length;
+ if(emptyTarget){
+ targetPos = 0;
+ }else{
+ for(i = targetPos; i < g.rowCount; ++i){
+ mapping[i] = i + len;
+ }
+ }
+ if(s.getFeatures()['dojo.data.api.Write']){
+ if(sourceGrid){
+ var srcg = sourceGrid,
+ srcs = srcg.store,
+ thisItem, attrs;
+ if(!emptyTarget){
+ for(i = 0; !thisItem; ++i){
+ thisItem = g._by_idx[i];
+ }
+ attrs = s.getAttributes(thisItem.item);
+ }else{
+ //If the target grid is empty, there is no way to retrieve attributes.
+ //So try to get attrs from grid.layout.cells[], but this might not be right
+ //since some fields may be missed(e.g ID fields), please use "setIdentifierForNewItem()"
+ //to add those missed fields
+ attrs = array.map(g.layout.cells, function(cell){
+ return cell.field;
+ });
+ }
+ var rowsToFetch = [];
+ array.forEach(rowsToMove, function(rowIndex, i){
+ var item = {};
+ var srcItem = srcg._by_idx[rowIndex];
+ if(srcItem){
+ array.forEach(attrs, function(attr){
+ item[attr] = srcs.getValue(srcItem.item, attr);
+ });
+ item = _this.args.setIdentifierForNewItem(item, s, rowCnt + obj.idx) || item;
+ try{
+ s.newItem(item);
+ newRows.push(targetPos + i);
+ mapping[rowCnt + obj.idx] = targetPos + i;
+ ++obj.idx;
+ }catch(e){
+ console.log("insertRows newItem:",e,item);
+ }
+ }else{
+ rowsToFetch.push(rowIndex);
+ }
+ });
+ }else if(rowsToMove.length && lang.isObject(rowsToMove[0])){
+ array.forEach(rowsToMove, function(rowData, i){
+ var item = _this.args.setIdentifierForNewItem(rowData, s, rowCnt + obj.idx) || rowData;
+ try{
+ s.newItem(item);
+ newRows.push(targetPos + i);
+ mapping[rowCnt + obj.idx] = targetPos + i;
+ ++obj.idx;
+ }catch(e){
+ console.log("insertRows newItem:",e,item);
+ }
+ });
+ }else{
+ return;
+ }
+ g.layer("rowmap").setMapping(mapping);
+ s.save({
+ onComplete: function(){
+ g._refresh();
+ setTimeout(function(){
+ connect.publish("dojox/grid/rearrange/insert/" + g.id, ["row", newRows]);
+ }, 0);
+ }
+ });
+ }
+ }catch(e){
+ console.log("insertRows:",e);
+ }
+ },
+ removeRows: function(rowsToRemove){
+ var g = this.grid;
+ var s = g.store;
+ try{
+ array.forEach(array.map(rowsToRemove, function(rowIndex){
+ return g._by_idx[rowIndex];
+ }), function(row){
+ if(row){
+ s.deleteItem(row.item);
+ }
+ });
+ s.save({
+ onComplete: function(){
+ connect.publish("dojox/grid/rearrange/remove/" + g.id, ["row", rowsToRemove]);
+ }
+ });
+ }catch(e){
+ console.log("removeRows:",e);
+ }
+ },
+ _getPageInfo: function(){
+ // summary:
+ // Find pages that contain visible rows
+ // return: Object
+ // {topPage: xx, bottomPage: xx, invalidPages: [xx,xx,...]}
+ var scroller = this.grid.scroller,
+ topPage = scroller.page,
+ bottomPage = scroller.page,
+ firstVisibleRow = scroller.firstVisibleRow,
+ lastVisibleRow = scroller.lastVisibleRow,
+ rowsPerPage = scroller.rowsPerPage,
+ renderedPages = scroller.pageNodes[0],
+ topRow, bottomRow, matched,
+ invalidPages = [];
+
+ array.forEach(renderedPages, function(page, pageIndex){
+ if(!page){ return; }
+ matched = false;
+ topRow = pageIndex * rowsPerPage;
+ bottomRow = (pageIndex + 1) * rowsPerPage - 1;
+ if(firstVisibleRow >= topRow && firstVisibleRow <= bottomRow){
+ topPage = pageIndex;
+ matched = true;
+ }
+ if(lastVisibleRow >= topRow && lastVisibleRow <= bottomRow){
+ bottomPage = pageIndex;
+ matched = true;
+ }
+ if(!matched && (topRow > lastVisibleRow || bottomRow < firstVisibleRow)){
+ invalidPages.push(pageIndex);
+ }
+ });
+ return {topPage: topPage, bottomPage: bottomPage, invalidPages: invalidPages};
+ }
+});
+
+EnhancedGrid.registerPlugin(Rearrange/*name:'rearrange'*/);
+
+return Rearrange;
+
+}); \ No newline at end of file