CopyPasteMenu.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /**
  2. * grid复制粘贴功能菜单
  3. *
  4. * @author yingp
  5. */
  6. Ext.define('erp.view.core.plugin.CopyPasteMenu', {
  7. ptype : 'copypastemenu',
  8. constructor : function(cfg) {
  9. if (cfg) {
  10. Ext.apply(this, cfg);
  11. }
  12. },
  13. clipPath : basePath + 'resource/ux/zero/ZeroClipboard.js',
  14. moviePath : basePath + 'resource/ux/zero/ZeroClipboard.swf',
  15. copyCls : 'grid-copy',
  16. init : function(grid) {
  17. this.grid = grid;
  18. if (grid.view) {
  19. var me = this;
  20. grid.on({
  21. cellclick : function(view, td, colIdx, record, tr, rowIdx, e) {
  22. if (e.ctrlKey) {
  23. if (typeof ZeroClipboard === 'undefined') {
  24. Ext.Loader.injectScriptElement(me.clipPath, function(){
  25. ZeroClipboard.moviePath = me.moviePath;
  26. });
  27. }
  28. me.createMultiCopy(view, td, colIdx, record, tr, rowIdx, e);
  29. return false;
  30. }
  31. return true;
  32. },
  33. cellpaste : function(view, record, column, e) {
  34. e.preventDefault();
  35. Ext.defer(function(){
  36. me.onEditorPaste(view, record, column, e);
  37. }, 300);
  38. },
  39. specialkey : function(e) {
  40. console.log(e);
  41. }
  42. });
  43. var gridView = grid.view.normalView || grid.view;
  44. gridView.on({
  45. cellcontextmenu : function(view, td, colIdx, record, tr, rowIdx, e) {
  46. me.loadSource();
  47. if (e.ctrlKey) {// 多行多列模式
  48. me.createMultiCopy(view, td, colIdx, record, tr, rowIdx, e);
  49. } else {
  50. me.createDefaultCopy(view, td, colIdx, record, tr, rowIdx, e);
  51. }
  52. }
  53. });
  54. Ext.defer(function(){
  55. me.loadSource();
  56. }, 2000);
  57. }
  58. },
  59. loadSource: function() {
  60. if (typeof ZeroClipboard === 'undefined') {
  61. var me = this;
  62. Ext.Loader.injectScriptElement(me.clipPath, function(){
  63. ZeroClipboard.moviePath = me.moviePath;
  64. });
  65. }
  66. },
  67. createDefaultCopy : function(view, td, colIdx, record, tr, rowIdx, e) {
  68. var me = this,
  69. column = view.getHeaderByCell(td) ||
  70. view.ownerCt.headerCt.getHeaderAtIndex(colIdx);
  71. if (!column) {
  72. return;
  73. }
  74. var dataIndex = column.dataIndex;
  75. e.preventDefault();
  76. var menu = view.copymenu;
  77. if (!menu) {
  78. menu = view.copymenu = me.createMenu();
  79. }
  80. menu.showAt(e.getXY());
  81. me.clearCopyCls();
  82. menu.grid = view.ownerCt;
  83. menu.record = record;
  84. menu.column = column;
  85. menu.dataIndex = dataIndex;
  86. menu.cell = view.getCell(menu.record, menu.column);
  87. menu.cell.addCls(me.copyCls);
  88. },
  89. createMultiCopy : function(view, td, colIdx, record, tr, rowIdx, e) {
  90. var me = this,
  91. column = view.getHeaderByCell(td) ||
  92. view.ownerCt.headerCt.getHeaderAtIndex(colIdx);
  93. if (!column) {
  94. return;
  95. }
  96. e.preventDefault();
  97. var picker = view.copypicker;
  98. if (!picker) {
  99. picker = view.copypicker = me.createPicker();
  100. }
  101. picker.grid = view.ownerCt;
  102. picker.graphics = picker.graphics || new Array();
  103. var cell = view.getCell(record, column),
  104. xy = {x : colIdx, y : rowIdx};
  105. if(Ext.Array.contains(picker.graphics, xy)) {
  106. picker.graphics.remove(xy);
  107. } else {
  108. picker.graphics.push(xy);
  109. }
  110. this.setCopyCls(picker.graphics);
  111. if(picker.graphics.length > 1) {
  112. picker.showAt([(cell.getX() + cell.getWidth()), (cell.getY() + cell.getHeight())]);
  113. }
  114. },
  115. setCopyCls : function(graphics) {
  116. var me = this;
  117. me.clearCopyCls();
  118. if (graphics.length == 1) {
  119. var cell = me.getCell(graphics[0].x, graphics[0].y);
  120. if (cell) {
  121. cell.addCls(me.copyCls);
  122. }
  123. } else if (graphics.length == 2) {
  124. var x = Math.min(graphics[0].x, graphics[1].x),
  125. m = Math.max(graphics[0].x, graphics[1].x),
  126. y = Math.min(graphics[0].y, graphics[1].y),
  127. n = Math.max(graphics[0].y, graphics[1].y);
  128. for (var i = x;i <= m;i++ ) {
  129. var cell = me.getCell(i, y);
  130. if (cell) {
  131. cell.addCls(me.copyCls + '-top');
  132. }
  133. cell = me.getCell(i, n);
  134. if (cell) {
  135. cell.addCls(me.copyCls + '-bottom');
  136. }
  137. }
  138. for (var i = y;i <= n;i++ ) {
  139. var cell = me.getCell(x, i);
  140. if (cell) {
  141. cell.addCls(me.copyCls + '-left');
  142. }
  143. cell = me.getCell(m, i);
  144. if (cell) {
  145. cell.addCls(me.copyCls + '-right');
  146. }
  147. }
  148. }
  149. },
  150. getCell : function(x, y) {
  151. var view = this.grid.view,
  152. column = view.ownerCt.headerCt.getHeaderAtIndex(x),
  153. record = this.grid.store.getAt(y);
  154. if (column)
  155. return view.getCell(record, column);
  156. return null;
  157. },
  158. clearCopyCls : function() {
  159. var view = this.grid.view, me = this;
  160. var doms = view.getEl().query('.' + me.copyCls);
  161. if (doms) {
  162. Ext.each(doms, function() {
  163. me.removeClass(this, me.copyCls);
  164. });
  165. }
  166. if(view.copypicker) {
  167. var dir = ['top', 'bottom', 'left', 'right'];
  168. for(var i in dir) {
  169. var cls = me.copyCls + '-' + dir[i];
  170. doms = view.getEl().query('.' + cls);
  171. if (doms) {
  172. Ext.each(doms, function() {
  173. me.removeClass(this, cls);
  174. });
  175. }
  176. }
  177. }
  178. },
  179. removeClass : function(dom, className) {
  180. var temp = dom.className;
  181. dom.className = null;
  182. dom.className = temp.split(new RegExp(" " + className + "|" + className + " " + "|" + "^" + className + "$","ig")).join("");
  183. },
  184. createPicker : function() {
  185. var me = this;
  186. return Ext.create('Ext.menu.Menu', {
  187. items : [{
  188. copyType : 'multi',
  189. iconCls : 'x-button-icon-copy',
  190. text : '复制'
  191. },{
  192. text : '取消'
  193. }],
  194. listeners: {
  195. delay : 100,
  196. mouseover : function(m, item, e) {
  197. if (item) {
  198. me.resetClip(m, item);
  199. }
  200. },
  201. hide : function (m) {
  202. m.graphics = null;
  203. me.clearCopyCls();
  204. }
  205. }
  206. });
  207. },
  208. createMenu : function() {
  209. var me = this;
  210. return Ext.create('Ext.menu.Menu', {
  211. items: [{
  212. copyType : 'cell',
  213. iconCls : 'x-button-icon-copy',
  214. text : '复制单元格'
  215. },{
  216. copyType : 'row',
  217. text : '复制行'
  218. },{
  219. copyType : 'table',
  220. text : '复制表格'
  221. },{
  222. xtype: 'menuseparator'
  223. },{
  224. text : '复制到整列',
  225. handler : function(t, e) {
  226. var m = t.up('menu'),
  227. val = me.getCellText(m.grid, m.record, m.column, m.dataIndex);
  228. m && me.onColumnPaste(val, m.grid, m.column, m.record, m.dataIndex, m.cell, e);
  229. }
  230. },{
  231. xtype: 'menuseparator'
  232. },{
  233. text : '粘贴',
  234. iconCls : 'x-button-icon-paste',
  235. handler : function() {console.log(arguments);
  236. me.onCellPaste();
  237. }
  238. }],
  239. listeners: {
  240. delay : 100,
  241. mouseover : function(m, item, e) {
  242. if (item) {
  243. me.resetClip(m, item);
  244. }
  245. },
  246. hide : function (m) {
  247. me.clearCopyCls();
  248. }
  249. }
  250. });
  251. },
  252. resetClip : function(m, item) {
  253. if(!item.copyType) {
  254. return;
  255. }
  256. var me = this, clip = item.clip;
  257. if(!clip) {
  258. clip = item.clip = new ZeroClipboard.Client();
  259. clip.setHandCursor(true);
  260. clip.glue(item.id + '-itemEl', item.id);
  261. clip.addEventListener('complete', function (client, text) {
  262. m.hide();
  263. });
  264. }
  265. if(item.copyType == 'cell') {
  266. clip.setText(me.getCellText(m.grid, m.record, m.column, m.dataIndex));
  267. } else if(item.copyType == 'row') {
  268. clip.setText(me.getRecordText(m.grid, m.record));
  269. } else if(item.copyType == 'table') {
  270. clip.setText(me.getTableText(m.grid));
  271. } else if(item.copyType == 'multi') {
  272. clip.setText(me.getMultiText(m.graphics));
  273. }
  274. },
  275. getCellText : function(grid, record, column, dataIndex) {
  276. var v = record.get(dataIndex);
  277. if (v) {
  278. if(Ext.isDate(v)) {
  279. return Ext.Date.format(v, column.format || Ext.Date.defaultFormat);
  280. }
  281. return v;
  282. }
  283. return '';
  284. },
  285. getRecordText : function(grid, record) {
  286. var s = [], columns = grid.headerCt.getGridColumns(), v = null;
  287. Ext.each(columns, function(c){
  288. if(!c.hidden && c.dataIndex && c.getWidth() > 0) {
  289. v = record.get(c.dataIndex);
  290. if(c == null) {
  291. s.push(' ');
  292. } else {
  293. if(Ext.isDate(v)) {
  294. s.push(Ext.Date.format(v, c.format || Ext.Date.defaultFormat));
  295. } else {
  296. s.push(v);
  297. }
  298. }
  299. }
  300. });
  301. return s.join('\t');
  302. },
  303. getTableText : function(grid) {
  304. var me = this, s = [];
  305. grid.store.each(function(){
  306. s.push(me.getRecordText(grid, this));
  307. });
  308. return s.join('\n');
  309. },
  310. getMultiText : function(graphics) {
  311. if (graphics.length > 0) {
  312. var x = Math.min(graphics[0].x, graphics[1].x),
  313. m = Math.max(graphics[0].x, graphics[1].x),
  314. y = Math.min(graphics[0].y, graphics[1].y),
  315. n = Math.max(graphics[0].y, graphics[1].y);
  316. var me = this, view = me.grid.view, s = [];
  317. for (var i = y;i <= n;i++ ) {
  318. var record = me.grid.store.getAt(i);
  319. var t = [];
  320. for (var j = x;j <= m;j++ ) {
  321. var column = view.ownerCt.headerCt.getHeaderAtIndex(j);
  322. t.push(me.getCellText(me.grid, record, column, column.dataIndex));
  323. }
  324. s.push(t.join('\t'));
  325. }
  326. return s.join('\n');
  327. }
  328. return null;
  329. },
  330. onEditorPaste : function(view, record, column, e) {
  331. var me = this, v = e.target.value;
  332. view = view.normalView || view;
  333. if(v && (v.indexOf('\n') > -1 || v.indexOf('\t') > -1)) {
  334. var list = v.split('\n'), map, store = view.store,
  335. ct = view.ownerCt.headerCt,
  336. x = ct.getHeaderIndex(column),
  337. y = store.indexOf(record),
  338. nextRecord = record,
  339. nextColumn = column;
  340. Ext.Array.each(list, function(l, i){
  341. if(i > 0)
  342. nextRecord = store.getAt(y + i);
  343. if(nextRecord) {
  344. map = l.split('\t');
  345. Ext.Array.each(map, function(p, j){
  346. nextColumn = j > 1 ? me.getNextHeader(ct, nextColumn) :
  347. (j == 1 ? me.getNextHeader(ct, column) : column);
  348. if(nextColumn) {
  349. nextRecord.set(nextColumn.dataIndex, p);
  350. }
  351. if(i == 0 && j == 0)
  352. e.target.value = p;
  353. });
  354. }
  355. });
  356. }
  357. },
  358. getNextHeader : function(headerCt, startColumn) {
  359. var me = this, index = headerCt.getHeaderIndex(startColumn),
  360. next = headerCt.getHeaderAtIndex(index + 1);
  361. if(next) {
  362. if(!next.hidden && next.getWidth() > 0)
  363. return next;
  364. return me.getNextHeader(headerCt, next);
  365. }
  366. return null;
  367. },
  368. onCellPaste : function() {
  369. var v = this.getClipboard();
  370. if (!v) {
  371. return;
  372. }
  373. var menu = this.grid.view.copymenu,
  374. record = menu.record, dataIndex = menu.dataIndex,
  375. column = menu.column;
  376. var editor = column.getEditor(record);
  377. if (!editor) {
  378. return;
  379. }
  380. if(column.xtype == 'datecolumn') {
  381. try {
  382. v = Ext.Date.parse(v, column.format || Ext.Date.defaultFormat);
  383. } catch (e) {
  384. alert('日期格式错误');return;
  385. }
  386. }
  387. record.set(dataIndex, v);
  388. if (editor.field) {
  389. editor.field.focus();
  390. }
  391. },
  392. onColumnPaste : function(val, grid, column, record, dataIndex, cell, e) {
  393. if(!grid.readOnly) {// 只允许可编辑的列粘贴
  394. var editor = column.getEditor(record);
  395. if(editor) {
  396. grid.store.each(function(record){
  397. record.set(dataIndex, val);
  398. });
  399. }
  400. }
  401. },
  402. getClipboard : function() {
  403. if (window.clipboardData) {
  404. return window.clipboardData.getData('Text');
  405. }
  406. return null;
  407. }
  408. });