ExtJs 备忘录(7)—— GirdPanl表格(三) [ 统计|查看、修改单行记录 ]


前言

  关键字:Ext GirdPanel, Ext.Window 居中,Ext 统计,Ext.ux.grid.GroupSummary

  有些好习惯不能因为这样那样的事情而中止或拖延,比如加班、找工作...... N天之后——继续内疚和纠结,本意是鼓励自己来着,既然没法长期有效那短期有效也行吧,总比什么效果没有要好 :)

 

 

系列

  1.  ExtJs 备忘录(1)—— Form表单(一) [ 控件使用 ]
  2.  ExtJs 备忘录(2)—— Form表单(二) [ 控件封装 ]
  3.  ExtJs 备忘录(3)—— Form表单(三) [ 数据验证 ]
  4.  ExtJs 备忘录(4)—— Form表单(四) [ 数据提交 ]
  5.  ExtJs 备忘录(5)—— GirdPanl表格(一)[ 基本用法 ]
  6.  ExtJs 备忘录(6)—— GirdPanl表格(二)[ 搜索分页 ]
  7.  ExtJs 备忘录(7)—— GirdPanl表格(三)[ 统计|查看、修改单行记录 ]

 

 

正文

  一、查看/修改单行记录

    目的:单击某行某个字段,查看/编辑该行详细数据。

    1.1  效果截图

    

    1.2  实现代码

      后台的代码参见上篇文章:ExtJs 备忘录(6)—— GirdPanl表格(二)[ 搜索分页 ]

      前端代码:7.1.aspx

        var currentWindow,detailWindow,OpenDetailFunc,detailForm;
        
        Ext.onReady(
function() {
            Ext.QuickTips.init();
            Ext.form.Field.prototype.msgTarget 
= 'side';

            
var store = new Ext.data.Store({
                proxy: 
new Ext.data.HttpProxy({
                    url: 
'7.1.aspx?method=search',
                    method: 
'GET'
                }),
                reader: 
new Ext.data.JsonReader({
                    totalProperty: 
'count',
                    root: 
'result'
                }, [
                        { name: 
'Name' },
                        { name: 
'Id' },
                        { name: 
'Email' },
                        { name: 
'Gender' }
                ])
            });
            
            
//加载数据
            store.load({
                params:{   limit: 
10    }
            });

            
var dataColumns = new Ext.grid.ColumnModel({
                columns: [
                    
new Ext.grid.RowNumberer(), //显示行号
                    { header: "编  号", dataIndex: 'Id', sortable: true },
                    { header: 
"名  称", dataIndex: 'Name' },
                    { header: 
"邮  箱", dataIndex: 'Email' },
                    { header: 
"性  别", dataIndex: 'Gender'
                        renderer: 
function(value, cell, record) {
                            
//alert(record.data.Age);
                            var GenderStr = record.data.Gender == 0 ? "" : "";
                            
return  '<a href="javascript:void(0);" onclick=javascript:OpenDetailFunc('+record.data.Id+',"'+record.data.Name+'","'+record.data.Email+'",'+record.data.Gender+'); style="cursor:hand">' + GenderStr + '</a>';
                         }
                    }
                ],
                defaults: {
                    align: 
'center'
                }
            });
            
            
//easy-ext.js
            var grid = GridPanel(store,dataColumns,10,'<center style="curor:hand" onclick="window.location.reload();">表格查看、修改单行记录|统计</center>');
            grid.width
=800;
            grid.render(Ext.getBody());
            
            
//-------------------------------------------查看、修改单条记录
            
            
var   tbId = new NumberField('tbId','编  号');
            
var   tbName = new TextField('tbName','名  称');
            
var   tbEmail = new TextField('tbEmail','邮  箱');
            
var   cbGender = new ComboBox('cbGender','性  别',[[1,''],[0,'']]);
            
            detailForm 
= new Ext.FormPanel({
                layout: 
'form',
                frame:
true,
                items:[ tbId, tbName, tbEmail, cbGender],
                buttons: [
                    { text: 
'修  改' },
                    {  text: 
'取  消' , handler : function(){ detailWindow.hide(); }}
                ]
            });

            
            
//参数赋值,显示窗体
            OpenDetailFunc = function(Id,Name,Email,Gender){
                
                
var form = detailForm.getForm();
                tbId.value 
= Id;
                tbName.value 
= Name;
                tbEmail.value 
= Email;
                cbGender.value 
= Gender;
                detailWindow.show();
            };
            
            detailWindow 
= new Ext.Window({
                title:
"详情",
                closable:
true,
                iconCls:
'add',
                autoWidth:
true,
                autoHeight: 
true,
                buttonAlign:
'center',
                closeAction:
'hide',
                plain:
true,
                
//width:400,
                //height:380,
                items:[detailForm],
                listeners: {
                    
'show':function(){
                        
this.center();         //屏幕居中
                    }
                }
            });
        });

      代码说明:

        a).  GridPanelNumberField以及ComboBox等参见源代码easyext.js(系列第二篇文章也有专门介绍封装)。

        b).  这里仅给出了修改的例子,没有再多些一个显示的,这里考虑的是修改都出来了,显示就不是什么问题了。

 

  二、统计

    2.1  在3.0里面之前官方没有正式的统计插件,如需要可以参见本文底部相关文章来写,想想当初要实现这个功能也是大费周章,这里探讨另外一种灵活的形式来实现统计,对于熟悉写后台的人来说比较简单 :)

      2.1.1  思路:

        前端:只用对增加一行显示就行,比如本来是显示12行,你让他显示13行,需要做特殊处理,比如红字显示统计数据可以在renderer里面做判断处理;

        后端:自己写代码统计要统计的数据,然后把这个数据包装一下放到返回显示数据的最后一条。

      2.1.2  效果截图

       

      2.1.3  代码片段

        主要实现代码(参见源代码7.2.1.aspx.cs):

    /// <summary>
    
/// 将数据表转换成JSON类型串
    
/// </summary>
    
/// <param name="dt">要转换的数据表</param>
    
/// <param name="dispose">数据表转换结束后是否dispose掉</param>
    
/// <returns></returns>
    public static StringBuilder DataTableToJson(System.Data.DataTable dt, bool dt_dispose)
    {
        StringBuilder stringBuilder 
= new StringBuilder();
        stringBuilder.Append(
"[");//\r\n

        
//数据表字段名和类型数组
        string[] dt_field = new string[dt.Columns.Count];
        
int i = 0;
        
string formatStr = "{{";
        
string fieldtype = "";
        
foreach (System.Data.DataColumn dc in dt.Columns)
        {
            dt_field[i] 
= dc.Caption.Trim();//ToLower().
            formatStr += "'" + dc.Caption.Trim() + "':";//ToLower().
            fieldtype = dc.DataType.ToString().Trim().ToLower();
            
if (fieldtype.IndexOf("int"> 0 || fieldtype.IndexOf("deci"> 0 ||
                fieldtype.IndexOf(
"floa"> 0 || fieldtype.IndexOf("doub"> 0 ||
                fieldtype.IndexOf(
"bool"> 0)
            {
                formatStr 
+= "{" + i + "}";
            }
            
else
            {
                formatStr 
+= "'{" + i + "}'";
            }
            formatStr 
+= ",";
            i
++;
        }

        
if (formatStr.EndsWith(","))
        {
            formatStr 
= formatStr.Substring(0, formatStr.Length - 1);//去掉尾部","号
        }
        formatStr 
+= "}},";

        i 
= 0;
        
object[] objectArray = new object[dt_field.Length];
        
foreach (System.Data.DataRow dr in dt.Rows)
        {

            
foreach (string fieldname in dt_field)
            {   
//对 \ , ' 符号进行转换 
                objectArray[i] = dr[dt_field[i]].ToString().Trim().Replace("\\""\\\\").Replace("'""\\'");
                
switch (objectArray[i].ToString())
                {
                    
case "True":
                        {
                            objectArray[i] 
= "true"break;
                        }
                    
case "False":
                        {
                            objectArray[i] 
= "false"break;
                        }
                    
defaultbreak;
                }
                i
++;
            }
            i 
= 0;
            stringBuilder.Append(
string.Format(formatStr, objectArray));
        }
        
if (stringBuilder.ToString().EndsWith(","))
        {
            stringBuilder.Remove(stringBuilder.Length 
- 11);//去掉尾部","号
        }

        
if (dt_dispose)
        {
            dt.Dispose();
        }
        
return stringBuilder.Append("]");//\r\n
    }

    
public override string Search()
    {
        
int start = -1;
        
int.TryParse(Request.QueryString["start"], out start);
        
int limit = -1;
        
int.TryParse(Request.QueryString["limit"], out limit);
        
string id = Request.QueryString["id"];
        IList
<User> result = new List<User>();

        
if (string.IsNullOrEmpty(id))
            result 
= GetPage(ConverToList(dataSource.Values), start, limit);
        
else
        {
            
int uid;
            
if (int.TryParse(id, out uid))
            {
                
if (dataSource.ContainsKey(uid))
                    result.Add(dataSource[uid]);
            }
        }

        
//统计
        DataTable dt = new DataTable();
        dt.Columns.Add(
"Id");
        dt.Columns.Add(
"Email");
        dt.Columns.Add(
"Name");
        dt.Columns.Add(
"Gender");
        dt.Columns.Add(
"Age");

        
int avg_Age = 0;
        
foreach (User item in result)
        {
            avg_Age 
+= item.Age;
            dt.Rows.Add(item.Id, item.Email, item.Name, item.Gender, item.Age);
        }
        
if (result.Count > 0)
            dt.Rows.Add(
""""""""string.Format("平均:{0}", avg_Age / result.Count));

        
return new StringBuilder().Append("{count:")
        .Append(
1000)
        .Append(
",result:")
        .Append(DataTableToJson(dt, 
true))
            
//        .Append(JavaScriptConvert.SerializeObject(result))
        .Append('}')
        .ToString();
    }

      代码说明:

        相比之下我可能更加愿意这种方式进行统计,在后台写代码也好控制,而前端几乎可以不改动就能达到统计的效果。

        a).  与1.2例子的后台相比,多增加了一个字段,Age。

        b).  这里用的DataTable,因为强类型不好赋值为空,这里也可以返回特定的强类型,比如Id返回-1就表示是统计列,然后在renderer里面做判断显示。

 

    2.2  3.0中的统计插件用

      查了一圈,发现还是不支持简单统计,必须分组统计,得使用Ext.data.GroupingStore才行,不过没关系,咱们可以变通:)

      2.2.1  截图

       

      2.2.2  实现代码

        Ext.onReady(function() {
            Ext.QuickTips.init();
            Ext.form.Field.prototype.msgTarget 
= 'side';

            
var store = new Ext.data.GroupingStore ({
                proxy: 
new Ext.data.HttpProxy({
                    url: 
'7.2.2.aspx?method=search',
                    method: 
'GET'
                }),
                reader: 
new Ext.data.JsonReader({
                    totalProperty: 
'count',
                    root: 
'result'
                }, [
                        { name: 
'Name' },
                        { name: 
'Id' },
                        { name: 
'Email' },
                        { name: 
'Gender' },
                        { name: 
'Age' },
                        { name: 
'groupField',convert:function(v){  return '数据';} }
                ]),
                sortInfo:{field: 
'Age', direction: "ASC"},
                groupField:
'groupField'
            });
            
            
//加载数据
            store.load({
                params:{   limit: 
10    }
            });
            
            
//自定义
//
            Ext.ux.grid.GroupSummary.Calculations['totalCost'] = function(v, record, field){
//
                return v + (record.data.estimate * record.data.rate);
//
            };
            
            
var summary = new Ext.ux.grid.GroupSummary();

            
var dataColumns = new Ext.grid.ColumnModel({
                columns: [
                    
new Ext.grid.RowNumberer(), //显示行号
                    { header: "编  号", dataIndex: 'Id', sortable: true },
                    { header: 
"名  称", dataIndex: 'Name' },
                    { header: 
"邮  箱", dataIndex: 'Email' },
                    { header: 
"性  别", dataIndex: 'Gender' },
                    { header: 
"数据", dataIndex: 'groupField' },
                    
//max,min,count,sum,average
                    { header: "总年龄", dataIndex: 'Age',summaryType:'average'}
                    
//,summaryType:'totalCost',groupable: false
                ],
                defaults: {
                    align: 
'center'
                }
            });

            
var grid = new Ext.grid.GridPanel({
                store: store,
                cm: dataColumns,
                renderTo: Ext.getBody(),
                autoExpandColumn: 
1,
                autoHeight: 
true,
                buttonAlign:
'center',
                border: 
true,
                disableSelection: 
true,
                frame: 
true,
                loadMask:
true,
                width: 
800,
                view: 
new Ext.grid.GroupingView({
                    forceFit: 
true,
                    showGroupName: 
false,
                    enableNoGroups: 
false,
                    enableGroupingMenu: 
false,
                    hideGroupedColumn: 
true
                }),
                plugins : summary,
                
//设置单行选中模式
                selModel: new Ext.grid.RowSelectionModel({ singleSelect: true }),
                
//columnLines: true,//显示列线条
                viewConfig: {   forceFit: true  }//使列自动均分
            });
        });

    代码说明:

      a).  这种办法就是不用服务端来进行统计,支持内置的5种统计,也支持自定义的统计,这个在代码注释里面可以看得到。

      b).  这里是通过一个虚拟字段groupField来模拟分组的,这样一来,就能满足基本的统计了。

      C).  注意sortInfo与groupField必须配置,然后必须使用Ext.data.GroupingStore。

 

  三、 下载  

    ExtJS2010-1-17.rar

    注意本章的事例在工程里面均是按章节来命名了,比如7.1.aspx。

 

结束语

  再不把这系列结束就来不及了,3.1已经出来了 - - #

 

 

本博相关文章

1.  ExtJs Grid 合计 [Ext | GridPanel | GridSummary]

 

 

 

 

 

 

 

 

 

posted @ 2010-01-17 17:06  农民伯伯  阅读(7803)  评论(0编辑  收藏  举报