Ext.lingo.EditGrid.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. /*
  2. * Ext JS Library 2.0.2
  3. * Copyright(c) 2006-2008, Ext JS, LLC.
  4. * licensing@extjs.com
  5. *
  6. * http://www.extjs.com/license
  7. *
  8. * @author Lingo
  9. * @since 2008-03-23
  10. * http://code.google.com/p/anewssystem/
  11. */
  12. Ext.namespace("Ext.lingo");
  13. /**
  14. * 拥有CRUD功能的表格.
  15. *
  16. * @param config 需要的配置{}
  17. */
  18. Ext.lingo.EditGrid = Ext.extend(Ext.grid.EditorGridPanel, {
  19. closable: true,
  20. clicksToEdit: 1,
  21. loadMask: true,
  22. removedRecords: [],
  23. insertedRecords: [],
  24. pageSize: 15,
  25. // 初始化
  26. initComponent: function() {
  27. this.buildColumnModel();
  28. this.buildRecord();
  29. this.buildDataStore();
  30. this.buildToolbar();
  31. Ext.lingo.EditGrid.superclass.initComponent.call(this);
  32. this.store.on('load', function() {
  33. this.removedRecords = [];
  34. this.insertedRecords = [];
  35. }, this);
  36. this.store.on('beforeload', function() {
  37. if (this.isDirty()) {
  38. Ext.MessageBox.show({
  39. title: '提示',
  40. msg: '是否保存本页的修改',
  41. buttons: Ext.MessageBox.YESNOCANCEL,
  42. fn: function(btn) {
  43. if (btn == 'yes') {
  44. this.save();
  45. } else if (btn == 'no') {
  46. this.cancel();
  47. } else {
  48. }
  49. },
  50. scope: this
  51. });
  52. return false;
  53. }
  54. }, this);
  55. },
  56. // 初始化ColumnModel
  57. buildColumnModel: function() {
  58. var columnHeaders = new Array();
  59. columnHeaders[0] = new Ext.grid.RowNumberer();
  60. for (var i = 0; i < this.formConfig.length; i++) {
  61. var col = this.formConfig[i];
  62. if (col.hideGrid === true) {
  63. continue;
  64. }
  65. var column = {
  66. header: col.fieldLabel,
  67. sortable: col.sortable,
  68. dataIndex: col.name
  69. };
  70. if (typeof(col.editor) != 'undefined') {
  71. column.editor = new Ext.grid.GridEditor(col.editor);
  72. }
  73. if (col.renderer) {
  74. column.renderer = col.renderer;
  75. }
  76. columnHeaders.push(column);
  77. }
  78. this.cm = new Ext.grid.ColumnModel(columnHeaders);
  79. this.cm.defaultSortable = true;
  80. this.columnModel = this.cm;
  81. },
  82. buildRecord: function() {
  83. this.dataRecord = Ext.data.Record.create(this.formConfig);
  84. },
  85. buildDataStore: function() {
  86. this.store = new Ext.data.Store({
  87. proxy : new Ext.data.HttpProxy({url:this.urlPagedQuery}),
  88. reader : new Ext.data.JsonReader({
  89. root : "result",
  90. totalProperty : "totalCount",
  91. id : "id"
  92. }, this.dataRecord),
  93. remoteSort : true
  94. });
  95. // this.store.setDefaultSort("id", "DESC");
  96. },
  97. buildToolbar: function() {
  98. //
  99. var checkItems = new Array();
  100. for (var i = 0; i < this.formConfig.length; i++) {
  101. var meta = this.formConfig[i];
  102. if (meta.showInGrid === false) {
  103. continue;
  104. }
  105. var item = new Ext.menu.CheckItem({
  106. text : meta.fieldLabel,
  107. value : meta.name,
  108. checked : true,
  109. group : "filter",
  110. checkHandler : this.onItemCheck.createDelegate(this)
  111. });
  112. checkItems[checkItems.length] = item;
  113. }
  114. this.filterButton = new Ext.Toolbar.MenuButton({
  115. iconCls : "refresh",
  116. text : this.formConfig[0].fieldLabel,
  117. tooltip : "选择搜索的字段",
  118. menu : checkItems,
  119. minWidth : 105
  120. });
  121. // 输入框
  122. this.filter = new Ext.form.TextField({
  123. 'name': 'filter'
  124. });
  125. this.filter.on('specialkey', this.onFilterKey.createDelegate(this));
  126. //
  127. this.tbar = new Ext.Toolbar([{
  128. id: 'addMenu',
  129. text: '添加',
  130. iconCls : 'add',
  131. tooltip : '添加',
  132. handler: this.add.createDelegate(this)
  133. },{
  134. id: 'deleteMenu',
  135. text: '删除',
  136. iconCls : 'delete',
  137. tooltip : '删除',
  138. handler: this.del.createDelegate(this)
  139. },{
  140. id: 'saveMenu',
  141. text: '提交修改',
  142. iconCls : 'edit',
  143. tooltip : '提交修改',
  144. handler: this.save.createDelegate(this)
  145. },{
  146. id: 'cancelMenu',
  147. text: '取消',
  148. iconCls: 'go',
  149. tooltip: '取消',
  150. handler: this.cancel.createDelegate(this)
  151. },{
  152. id: 'refreshMenu',
  153. text: '刷新',
  154. iconCls: 'refresh',
  155. tooltip: '刷新',
  156. handler: this.refresh.createDelegate(this)
  157. }, '->', this.filterButton, this.filter]);
  158. // 把分页工具条,放在页脚
  159. var paging = new Ext.PagingToolbar({
  160. pageSize: this.pageSize,
  161. store: this.store,
  162. displayInfo: true,
  163. displayMsg: '显示第 {0} 条到 {1} 条记录,一共 {2} 条',
  164. emptyMsg: "没有记录",
  165. plugins: [new Ext.ux.PageSizePlugin()]
  166. });
  167. this.store.load({
  168. params:{start:0, limit:paging.pageSize}
  169. });
  170. this.bbar = paging;
  171. },
  172. // 选中搜索属性选项时
  173. onItemCheck: function(item, checked) {
  174. if(checked) {
  175. this.filterButton.setText(item.text + ':');
  176. this.filter.setValue('');
  177. // this.store.baseParams.filterTxt = item.value;
  178. // this.store.baseParams.filterValue = '';
  179. }
  180. },
  181. // 监听模糊搜索框里的按键
  182. onFilterKey: function(field, e) {
  183. var filterTxt = this.store.baseParams.filterTxt;
  184. if (typeof filterTxt == 'undefined' || filterTxt == '') {
  185. Ext.Msg.alert('提示', '请先选择搜索的字段');
  186. return;
  187. }
  188. if(e.getKey() == e.ENTER && field.getValue().length > 0) {
  189. this.store.baseParams.filterValue = field.getValue();
  190. } else if (e.getKey() == e.BACKSPACE && field.getValue().length() === 0) {
  191. this.store.baseParams.filterValue = '';
  192. } else {
  193. return;
  194. }
  195. // delete this.store.lastOptions.params.meta;
  196. this.store.reload();
  197. },
  198. // 添加一行
  199. add: function() {
  200. this.stopEditing();
  201. var p = new this.dataRecord();
  202. var initValue = {};
  203. for (var i in p.fields.items) {
  204. var item = p.fields.items[i];
  205. if (item.name) {
  206. initValue[item.name] = null;
  207. }
  208. }
  209. p = new this.dataRecord(initValue);
  210. this.stopEditing();
  211. this.store.insert(0, p);
  212. this.startEditing(0, 0);
  213. p.dirty = true;
  214. p.modified = initValue;
  215. if(this.store.modified.indexOf(p) == -1){
  216. this.store.modified.push(p);
  217. }
  218. if (this.insertedRecords.indexOf(p) == -1) {
  219. this.insertedRecords.push(p);
  220. }
  221. },
  222. // 删除一行
  223. del: function() {
  224. this.stopEditing();
  225. Ext.Msg.confirm('信息', '确定要删除?', function(btn){
  226. if (btn == 'yes') {
  227. var sm = this.getSelectionModel();
  228. var cell = sm.getSelectedCell();
  229. var record = this.store.getAt(cell[0]);
  230. if(this.store.modified.indexOf(record) != -1){
  231. this.store.modified.remove(record);
  232. }
  233. // 记录删除了哪些id
  234. var id = record.get('id');
  235. if (id == null && this.insertedRecords.indexOf(record) != -1) {
  236. this.insertedRecords.remove(record);
  237. } else if (id != null && this.removedRecords.indexOf(record) == -1) {
  238. this.removedRecords.push(record);
  239. }
  240. this.store.remove(record);
  241. }
  242. }, this);
  243. },
  244. // 提交修改
  245. save: function() {
  246. this.stopEditing();
  247. var m = this.store.modified.slice(0);
  248. for (var i = 0; i < m.length; i++) {
  249. var record = m[i];
  250. var fields = record.fields.keys;
  251. for (var j = 0; j < fields.length; j++) {
  252. var name = fields[j];
  253. var value = record.data[name];
  254. var colIndex = this.getColumnModel().findColumnIndex(name);
  255. if (colIndex == -1) {
  256. continue;
  257. }
  258. var rowIndex = this.store.indexOfId(record.id);
  259. var editor = this.getColumnModel().getCellEditor(colIndex);
  260. if (editor && !editor.field.validateValue(value ? value : '')) {
  261. Ext.Msg.alert('提示', '请确保输入的数据正确。', function(){
  262. this.startEditing(rowIndex, colIndex);
  263. }, this);
  264. return;
  265. }
  266. }
  267. }
  268. // 进行到这里,说明数据都是有效的
  269. var data = [];
  270. Ext.each(m, function(p) {
  271. var value = {};
  272. for (var i in p.fields.items) {
  273. var item = p.fields.items[i];
  274. if (item.name) {
  275. value[item.name] = p.get(item.name);
  276. }
  277. }
  278. data.push(value);
  279. });
  280. var removedIds = [];
  281. Ext.each(this.removedRecords, function(item) {
  282. removedIds.push(item.get('id'));
  283. });
  284. if (!this.isDirty()) {
  285. // 没有修改,不需要提交
  286. return;
  287. }
  288. this.loadMask.show();
  289. Ext.Ajax.request({
  290. method: 'POST',
  291. url: this.urlSubmit,
  292. success: function(response) {
  293. var json = Ext.decode(response.responseText)
  294. this.loadMask.hide();
  295. if (json.success) {
  296. Ext.Msg.alert('信息', json.message, this.refresh.createDelegate(this));
  297. } else {
  298. Ext.Msg.alert('错误', json.message);
  299. }
  300. }.createDelegate(this),
  301. failure: function(){
  302. Ext.Msg.alert("错误", "与后台联系的时候出现了问题");
  303. },
  304. params: 'removedIds=' + removedIds +
  305. '&data=' + encodeURIComponent(Ext.encode(data))
  306. });
  307. },
  308. // 取消修改
  309. cancel: function() {
  310. this.stopEditing();
  311. // 返还修改
  312. this.store.rejectChanges();
  313. // 删除添加
  314. if (this.insertedRecords.length > 0) {
  315. for (var i = 0; i < this.insertedRecords.length; i++) {
  316. var p = this.insertedRecords[i];
  317. this.store.remove(p);
  318. }
  319. this.insertedRecoreds = [];
  320. }
  321. // 回复删除
  322. if (this.removedRecords.length > 0) {
  323. for (var i = 0; i < this.removedRecords.length; i++) {
  324. var p = this.removedRecords[i];
  325. this.store.add(p);
  326. }
  327. this.removedRecords = [];
  328. }
  329. },
  330. // 刷新表格数据
  331. refresh : function() {
  332. this.cancel();
  333. this.store.reload();
  334. },
  335. // 是否有改动
  336. isDirty: function() {
  337. return this.store.modified.length != 0 || this.removedRecords.length != 0;
  338. }
  339. });