使用Ext的Grid,Form,Dialog来实现分页列表,创建,修改,删除功能

签于现在网上多数的Form的例子都多数是描述前台UI的,而没有对与服务端通讯的部分,故参考EXTJS的一个指南,写下此文,希望能对大家有所帮助.

在WEB应用中,大部分的页面都可以被分为:列表,创建,读取,更新,删除.在Ext的文档中心提供了一个非常好的例子,一个行内编辑的表格.然而,在现实中,行 内编辑的表格是远远不够的,还需要用不同的方式来展示表单.下面的例子中向你展示如何在表格中创建/更新一个对话框表单.

列表功能

首先是是一个权限列表页,它包含分页,查询/过滤功能,创建和删除功能.

先定义数据源:

this.ds = new Ext.data.Store({
                   proxy : new Ext.data.HttpProxy({ url : '/wit/data.shtml' }),//'/wit/data.shtml' 一个读取数据列表的Action
                   reader : new Ext.data.JsonReader({ //使用JSON传输入数据
                       root : 'roleList',
                       totalProperty : 'totalCount',
                       id : 'id'
                   },
                   // 定义字段映射
                   [
                       {
                           name : 'id',
                           mapping : 'id',
                           type : 'string'
                       },
                       {
                           name : 'name',
                           mapping : 'name',
                           type : 'string'
                       },
                       {
                           name : 'description',
                           mapping : 'description',
                           type : 'string'
                       },
                       {
                           name : 'createDate',
                           mapping : 'createDate',
                           type : 'string'

},
                       {
                           name : 'updateDate',
                           mapping : 'updateDate',
                           type : 'string'
                       }
                   ]),
                   remoteSort : true
               });
               this.ds.load({ params:{ start : 0, limit : 20 } });

指定数据的来源位置,解析的方式,以及字段的映射.

接下来是表格中表头的定义,匹配上面的字段:

this.cm = new Ext.grid.ColumnModel([
                   {
                       header : '#',
                       dataIndex : 'id',
                       width : 30,
                       sortable : 1
                   },
                   {
                       header : '名称',
                       dataIndex : 'name',
                       width : 140,
                       sortable : 1
                   },
                   {
                       header : '描述',
                       dataIndex : 'description',
                       width : 140,
                       sortable : 1
                   },
                   {
                       header : '创建日期',
                       dataIndex : 'createDate',
                       width : 150,
                       sortable : 1
                   },

{
                       header : '修改日期',
                       dataIndex : 'updateDate',
                       width : 150,
                       sortable : 1
                   }
               ]);

再定义一下Grid:

this.grid = new Ext.grid.Grid('htmlGridPanel', {
                   ds : Grid.ds,
                   cm : Grid.cm,
                   enableColLock : false,
                   autoSizeColumns : true,
                   loadMask : true
               });
               this.grid.render();

现在,就可以看到简单的表格了.功能还有待完善.

接下来,在表格的头部面板处,添加过滤/查询的下拉菜单:

this.gridHead =this.grid.getView().getHeaderPanel(true);
               this.toolbar = new Ext.Toolbar(this.gridHead);
               this.filterBtn = new Ext.Toolbar.MenuButton({
                   icon : '../images/class.gif',
                   cls : 'x-btn-text-icon',
                   text : '选择过滤器',
                   tooltip : '选择一个过滤器',
                   menu : { items : [
                       new Ext.menu.CheckItem({ text : '编号', value : 'id',checked : true, group : 'filter', checkHandler : this.onItemCheck}),
                       new Ext.menu.CheckItem({ text : '名称', value : 'name',checked : false, group : 'filter', checkHandler : this.onItemCheck}),
                       new Ext.menu.CheckItem({ text : '描述', value :'description', checked : false, group : 'filter', checkHandler :this.onItemCheck})
                   ]},
                   minWidth : 105
               });               
               this.toolbar.add(this.filterBtn);       
               this.filter = Ext.get(this.toolbar.addDom({
                   tag : 'input',
                   type : 'text',
                   size : '30',
                   value : '',
                   style : 'background : #F0F0F9;'
               }).el);
               this.filter.on('keypress', function(e) {
                   if (e.getKey() == e.ENTER && this.getValue().length > 0) {
                       Grid.ds.load({ params : { start : 0, limit : 20 }});
                   }
               });   

在表格的底部面板添加分页,添加,删除按钮:

this.gridFoot =this.grid.getView().getFooterPanel(true);               
               this.paging = new Ext.PagingToolbar(this.gridFoot, this.ds, {
                   pageSize : 20,
                   displayInfo : true,
                   displayMsg : '共有 {2} 条记录.当前显示 {0} - {1}条记录.',
                   emptyMsg : '没有记录!'
               });
               this.paging.add('-', {
                   pressed : true,
                   enableToggle : true,
                   text : '添加',
                   cls : '',
                   toggleHandler : this.doAdd
               });
               this.paging.add('-', {
                   pressed : true,
                   enableToggle : true,
                   text : '删除',
                   cls : '',
                   toggleHandler : this.doDel
               });

在分页中,你需要在从服务器端加载数据之前发送过滤的字段和值:

this.ds.on('beforeload', function() {
                   Grid.ds.baseParams = {
                       filterValue : Grid.filter.getValue(),
                       filterTxt : Grid.filterBtn.getText()
                   };
               });
从服务器端返回的列表的JSON结果如下:

{"roleList":[{"id":21,"description":"description21","name":"puras21","createDate":"FriSep 07 15:54:44 CST 2007","updateDate":"Fri Sep 07 15:54:44CST 2007"},{"id":40,"description":"description40","name":"puras40","createDate":"FriSep 07 15:54:44 CST2007","updateDate":"Fri Sep 07 15:54:44CST 2007"}],"totalCount":2}

删除

删除方法如下:

doDel : function() {
               var c = Grid.grid.getSelections();
               if (c.length > 0)
                   Ext.MessageBox.confirm('消息', '确认要删除所选记录?', Grid.doDelProc);
               else
                   Ext.MessageBox.alert('警告', '最少需要选择一条记录!');   
            },
            doDelProc :function(btn) {
               if (btn == 'yes') {
                   if (Grid.grid.getSelectionModel().hasSelection()) {
                       var ids = new Array();
                       var records = Grid.grid.getSelectionModel().getSelections();
                       for (var i = 0, len = records.length; i < len; i++) {
                           ids[ids.length] = records[i].id;
                       }
                       Ext.lib.Ajax.request(
                           'GET',
                           '/wit/delete.shtml?ids=' + ids,
                           {
                               success : Grid.onSuccess,
                               failure : function(form, action) { Ext.MessageBox.alert('消息', '删除失败!');}
                           },
                           null
                       );
                   }
               }
            },
            onSuccess :function(o) {
               var response = function(json) {
                   try {
                       return eval('(' + json + ')');
                   } catch(e) {}
                   return null;
       &nbsp;       }(o.responseText);
               if (response.failure && response.failure == true) {
                   Ext.MessageBox.alert('消息', response.info);
               }
               Grid.ds.reload();
            }

通过Ajax的形式提交到服务器端.如果删除失败,则将失败信息显示给用户.onSuccess可以用于添,删,改三个功能的处理.返回的JSON数据结构如下:

"{success : true, info : '删除成功!'}"

前面已经把列表,分页,删除等部分说完了,这里再把创建和修改说说,基本的功能就差不多了.

创建

在这里,创建和修改者是用Dialog的形式来做的,首先则需要创建相应的DIV:

<!-- add div -->
    <div id="a-addInstance-dlg"style="visibility:hidden;">
        <divclass="x-dlg-hd">添加权限</div>
        <divclass="x-dlg-bd">
            <divid="a-addInstance-inner"class="x-layout-inactive-content">
               <div id="a-addInstance-form"></div>
            </div>
       </div>       
    </div>

之后就是在这个DIV里创建Form了,直接用Ext的Form组件:

createNewForm : function(){       
               this.name_tf = new Ext.form.TextField({
                   fieldLabel : '名称',
                   name : 'name',
                   allowBlank : false
               });
               this.description_tf = new Ext.form.TextField({
                   fieldLabel : '描述',
                   name : 'description'
               });
               this.addForm = new Ext.form.Form({
                   labelAlign : 'right',
                   url : '/wit/add.shtml'
               });
               this.addForm.column({
                   width : 430,
                   labelWidth : 120,
                   style : 'margin-left : 8px; margin-top : 8px;'
               });
               this.addForm.fieldset(
                   {id : 'desc', legend : '请填写字段值'},
                   Grid.name_tf,
                   Grid.description_tf
               );
               this.addForm.applyIfToFields({ width : 255 });
              &nbsp;this.addForm.render('a-addInstance-form');
               this.addForm.end();
            }

之后别忘了在加载的时候调用这个方法:

this.createNewForm();

Form窗体定义完,现在可以处理前面说的过那个创建按钮的事件了,在这里事件处理的方法名为doAdd:

doAdd : function() {
               if (!Grid.addInstanceDlg) {
                   Grid.addInstanceDlg = Grid.createNewDialog('a-addInstance-dlg');
                   Grid.addInstanceDlg.addButton('重置',Grid.resetForm, Grid.addInstanceDlg);
                   Grid.addInstanceDlg.addButton('保存', Grid.saveNewForm,Grid.addInstanceDlg);
                   var layout = Grid.addInstanceDlg.getLayout();
                   layout.beginUpdate();
                   var t = new Ext.ContentPanel('a-addInstance-inner', {title : 'createaccount'});
                   layout.add('center', new Ext.ContentPanel('a-addInstance-inner', {title : '添加权限'}));
                   layout.endUpdate();           
               }                   
               Grid.addInstanceDlg.show();           
            }

首先用Grid.createNewDialog创建一个LayoutDialog,之后再把添加里的特有的按钮加上去,然后更新一下Dialog的布局,把它显示出来,这时就可以看到添加的窗体了:

呵,窗体做的很难看,因为只是为了实现功能,没有在这方便下什么功夫.

Grid.createNewDialog用于创建和修改时创建对话框,代码如下:

createNewDialog : function(title) {
               var newDialog = new Ext.LayoutDialog(title, {
                   modal : true,
                   autoTabs : true,
                   proxyDrag : true,
                   resizable : false,
                   width : 480,
                   height : 302,
                   shadow : true,
                   center : {
                       autoScroll : true,
                       tabPosition : 'top',
                       closeOnTab : true,
                       closeOnTab : true,
                       alwaysShowTabs : false

   }
               });
               newDialog.addKeyListener(27, newDialog.hide, newDialog);
               newDialog.addButton('取消', function(){ newDialog.hide(); } );
               returnnewDialog;           
            }

如 果添加成功,则自动关闭这个Dialog,并重新加载列表,如果添加失败,只是简单的弹出一个对话框,提示失败,其实这里可以做的更人性化一些,可以在服 务器端传回错误的原因,比如某字段有问题,可以红色显示出其输入框等等.这里服务端返回的JSON数据与删除返回的一样.

处理代码如下:

saveNewForm : function() {
               if (Grid.addForm.isValid()) {
                   Grid.addForm.submit({
                       waitMsg : '正在保存数据...',
                       reset : true,
                       failure : function(form, action) {
                           Ext.MessageBox.alert('友情提示', action.result.info);
                       },
                       success : function(form, action) {
                           Grid.addInstanceDlg.hide();
                           Grid.ds.reload();
                       }
                   });
               } else {
                   Ext.MessageBox.alert('错误', '字段填写不正确!');
                   Grid.name_tf.focus();
               }
            }

修改

修改则和创建差不多了,不同的有两点,一是事件是在列表的行上双击,来触发事件,弹出修改对话框,另一个则是需要在显示对话框的同时,把所要修改的记录的数据加载进来.

首先在列表加上事件捕捉:

this.grid.on('rowdblclick', this.onRowDbClick, this);   

下面则是处理这个事件的代码:

onRowDbClick : function(grid,rowIndex, e) {
               var selectId = this.ds.data.items[rowIndex].id;
               var roleData = new Ext.data.Store({
                   proxy : new Ext.data.HttpProxy({url : '/wit/edit.shtml?id=' + selectId}),
                   reader : new Ext.data.JsonReader({}, ['id', 'name', 'description']),
                   remoteSort : false
               });
               roleData.on('load', function() {
                   Grid.updateId = roleData.getAt(0).data['id'];
      &nbsp;            Grid.name_show.setValue(roleData.getAt(0).data['name']);
                   Grid.description_show.setValue(roleData.getAt(0).data['description']);
                   if (!Grid.updateInstanceDlg) {
                       Grid.updateInstanceDlg = Grid.createNewDialog('a-updateInstance-dlg');
                       Grid.updateInstanceDlg.addButton('保存', Grid.saveUpdateForm, Grid.updateInstanceDlg);
                       var layout = Grid.updateInstanceDlg.getLayout();
                       layout.beginUpdate();
                       layout.add('center', new Ext.ContentPanel('a-updateInstance-inner', {title : '修改权限'}));
                       layout.endUpdate();
                   }
                   Grid.updateInstanceDlg.show();
               });
               roleData.load();
            }

这里做了两件事,一个是把欲修改的数据加载到本地, 服务端返回的数据结构为:

([{"id":"12","description":"test role12","name":"puras 12"}])

一个是将数据置入Form窗体的字段中,并将Dialog显示出来.修改的Form与创建的相似:

createEditForm : function() {
               this.name_show = new Ext.form.TextField({
                   fieldLabel : '名称',
                   name : 'name',
                   allowBlank : false
               });
               this.description_show = new Ext.form.TextField({
                   fieldLabel : '名称',
                   name : 'description'
               });
               this.editForm = new Ext.form.Form({
                   labelAlign : 'right',
                   url : '/wit/edit_ok.shtml'
               });
               this.editForm.column({width : 430, labelWidth : 120, style : 'margin-left :8px; margin-top : 8px;'});
               this.editForm.fieldset(
                   {legend : '请更新字段值'},
                   Grid.name_show,
                   Grid.description_show
               );
          &nbsp;    this.editForm.applyIfToFields({width : 255});
               this.editForm.render('a-updateInstance-form');
               this.editForm.end();
            }

这个Form对应的Div为:

<!-- update div -->
    <div id="a-updateInstance-dlg"style="visibility:hidden;">
        <divclass="x-dlg-hd">修改权限</div>
        <divclass="x-dlg-bd">
            <divid="a-updateInstance-inner"class="x-layout-inactive-content">
               <div id="a-updateInstance-form"></div>
            </div>
        </div>
    </div>

双击某条记录,则会弹出修改Dialog了,大概的样子如下:

修改的处理事件与添加类似,需要注意的地方就是ID是怎么传过去的:

saveUpdateForm : function() {
               if (Grid.editForm.isValid()) {
                   Grid.editForm.submit({
                       params : { id : Grid.updateId},
                       waitMsg : '正在更新数据...',
                       reset : false,
                       failure : function(form, action) {
                               Ext.MessageBox.alert('友情提示', action.result.info);
                           },
                       success : function(form, action) {
                           Grid.updateInstanceDlg.hide();
                           Grid.ds.reload();
                       }
                   });                   
               } else {
                   Ext.MessageBox.alert('错误', '字段填写不正确!');
               }
            }

到此就Over啦,列表,添,删,改都OK了.在没有做的时候,总是感觉找不到入口点,做完之后才发现,原来自己担心的问题,都不是问题,哈,想想,还是挺简单的.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值