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);" οnclick=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" οnclick="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 ;
                        }
                    
default break ;
                }
                i
++ ;
            }
            i 
=   0 ;
            stringBuilder.Append(
string .Format(formatStr, objectArray));
        }
        
if  (stringBuilder.ToString().EndsWith( " , " ))
        {
            stringBuilder.Remove(stringBuilder.Length 
-   1 1 ); // 去掉尾部","号
        }

        
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已经出来了 - - #

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值