表格控件GridPanel

表格控件GridPanel

表格由类Ext.grid.GridPanel定义,继承自Panel,xtype为grid。在Ext中,表格控件Grid必须包含列定义信息,并制定表格的数据存储器Store。表格的列信息由类Ext.grid.ColumnModel定义,而表格的数据存储器由Ext.data.Store定义,数据存储器根据解析的数据的不同,可分为JsonStore、SimpleStore、GroupingStore等。
 

Grid需要进行哪些配置呢?

首先,表格是二维的,跟数据库表一样。我们需要设置表的列数、每列的名称和类型,以及如何显示。

 

在ext中,列的定义叫做ColumnModel,cm是它的简称。它作为表格的列模型,是应该首先创建的。

 

下面创建一个包含3列的Grid,第1列编号(id),第二列是名称(name),第3列是描述(description)。

 

var cm = new Ext.grid.ColumnModel({

        {header:'编号',dataIndex:'id'},

        {header:'名称',dataIndex:'name'},

        {header:'描述',dataIndex:'description'}

    });

 

Var cm = new Ext.grid.ColumnModel(…)负责创建表格的列信息。表格包含的列由columns配置属性来描述,简称cm。columsn是一个数组,每一行数据元素描述表格的一列信息,表格的列信息包含首部显示文本(header)、列对应的记录集字段(dataIndex)、列是否可以排序(sortable)、列的渲染函数(renderer)、宽度(width)、格式化信息(format)等。上面的代码中只用到的header和dataIndex。

 

表格是二维的,数据自然也应该是二维的,下面用一个数组定义数据。

var data = [

        ['1','name1','desc1'],

        ['2','name2','desc2'],

        ['3','name3','desc3'],

        ['4','name4','desc4'],

        ['5','name5','desc5']

    ];

 

         此二维数据中,每一维都是一行数据。为了将数据展示出来,还需要做转换。

 

var store = new Ext.data.Store({

        proxy:new Ext.data.MemoryProxy(data),

        reader:new Ext.data.ArrayReader({},[

            {name:'id'},

            {name:'name'},

            {name:'description'},

        ]),

    });

   

    store.load();

 

         Varstore=…用来创建一个数据存储对象,这是GridPanel必须配置的属性。数据存储对象负责把各种各样的原始数据(如二维数组、Json对象数组、XML文本等)转换成Ext.data.Record类型的对象。通过Ext.data.Store,可以把任何格式的数据转换成Grid可以使用的形式,这样就不需要为每种数据格式写一个对应的实现。

 

         Store对应两个部分:proxy和reader。Proxy是指获取数据的方式。Reader是指如何解析这些数据。这里使用的是Ext.data.MemoryProxy,它是专门用来解析javascript变量的。在定义MemoryProxy对象时,只需要将上面定义的data作为参数传递进去即可。

 

         Ext.data.ArrayReader专门用来解析数组,并且告诉我们它会按照定义的规范进行解析,定义3个名称:id、name和description。再看前面cm定义的地方,这里的3个名称就和cm李的dataIndex相对应。这样,cm就知道column是如何与store中的数据相对应。需注意,要执行一次store.load(),以对数据进行初始化。

        

         如果第1列显示的不是id而是name,第2列显示的不是name而是id,那么可以通过mapping来指定。

         var store = new Ext.data.Store({

        proxy:newExt.data.MemoryProxy(data),

        reader:newExt.data.ArrayReader({},[

            {name:'id',mapping:1},

            {name:'name',mapping:0},

            {name:'description',mapping:2},

        ]),

    });

 

表格的列模型创建好了,原始数据与数据的转换也已经完成,剩下的就是把他们组装到一起,这样我们的Grid就创建好了。

 

var grid1 = newExt.grid.GridPanel({

        title:'员工信息',

        renderTo:'grid1',

        cm:cm,

        store:store,

        width:500,

        height:350

    });

 

显示结果如下图:

 

11.2列拖放和改变列宽

默认情况下,是可以拖放列、改变列的宽度的。如果要取消则将enableColumnMore和enableColumnResize设置为false即可。

         var grid1 = new Ext.grid.GridPanel({

        title:'员工信息',

        renderTo:'grid1',

        cm:cm,

        store:store,

        width:500,

        height:350,

        enableColumnMove:false,

        enableColumnResize:false

    });

 

11.3遮罩和提示

Grid还支持一种遮罩和提示功能,设置loadMasktrue,在store.load()完成之前,会一直显示“loading…”。

 

具体实现:

    var grid1 = newExt.grid.GridPanel({

        title:'员工信息',

        renderTo:'grid1',

        cm:cm,

        store:store,

        width:500,

        height:350,

        enableColumnMove:false,

        enableColumnResize:false,

        loadMask:true

    });

    store.load();

 

11.4为表格中的列指定宽度

上面的表格中每列的宽度都是一样的,我们可以自己指定每列的宽度(如果不指定,则宽度是默认值100px)。

var cm = newExt.grid.ColumnModel([

        {header:'编号',dataIndex:'id',width:50},

        {header:'名称',dataIndex:'name',width:100},

        {header:'描述',dataIndex:'description',width:200}

    ]);

 

11.5自动扩展列1

这样还是比较麻烦,需要自己计算每列宽度,如果想让每列自动填满整个表格,可以使用viewConfig中的forceFit即可。它是给GridView用的配置,它在视图层会重新计算所有列宽后填充Grid。使用了forceFit后,Grid会根据cm里面的宽度按比例分配。

 

var grid1 = newExt.grid.GridPanel({

        title:'员工信息',

        renderTo:'grid1',

        cm:cm,

        store:store,

        width:500,

        height:350,

        enableColumnMove:false,

        enableColumnResize:false,

        loadMask:true,

        viewConfig:{

            forceFit:true

        }

    });

 

11.6自动扩展列2

除了使用forceFit外,还可以考虑使用autoExpandColumn,它会自动扩展某列,从而填充整个表格。autoExpandColumn只能指定一列的ID,因此假设扩展description列,则需要在cm中指定id

var cm = newExt.grid.ColumnModel([

        {header:'编号',dataIndex:'id',width:50},

        {header:'名称',dataIndex:'name',width:100},

        {id:'descn',header:'描述',dataIndex:'description',width:200}

    ]);

 

var grid1 = newExt.grid.GridPanel({

        title:'员工信息',

        renderTo:'grid1',

        cm:cm,

        store:store,

        width:500,

        height:350,

        enableColumnMove:false,

        enableColumnResize:false,

        loadMask:true,

        /* viewConfig:{

            forceFit:true

        } */

        autoExpandColumn:'descn'

    });

 

11.7让表格支持排序

Ext中可以很方便的实现排序功能,只需要在定义列模型时,指定sortable为true即可。

var cm = newExt.grid.ColumnModel([

        {header:'编号',dataIndex:'id',width:50},

        {header:'名称',dataIndex:'name',width:100,sortable:true},

        {id:'descn',header:'描述',dataIndex:'description',width:200}

    ]);

 

这样名称这一列就支持排序了。

结果如图:

 

 

11.8解决中文排序问题

Ext默认是用ASCII进行排序,我们却按拼音排序,因此Ext自动排好的中文在我们看来一团糟。

如何解决呢?我们可以通过一个sortInfo来为Ext.data.Store设置一个默认的排序方式。

var store = newExt.data.Store({

        proxy:newExt.data.MemoryProxy(data),

        reader:newExt.data.ArrayReader({},[

            {name:'id',mapping:0},

            {name:'name',mapping:1},

            {name:'description',mapping:2},

        ]),

        sortInfo:{field:'name',direction:'ASC'}

    });

Field:指定排序的列,direction:指定排序方式,ASC升序,DESC降序。

这样排序看起来还是乱套的。

 

 

为了实现正确的中文排序, 我们需要自己重写Ext.data.Store的applySort()函数。

// Ext支持中文排序

     Ext.data.Store.prototype.applySort = function() {

        if( this.sortInfo && !this.remoteSort) {

           var s = this.sortInfo,f =s.field;

           var st = this.fields.get(f).sortType;

           var fn = function(r1,r2) {

                var v1 = st(r1,data[f]),v2 = st(r2.data[f]);

                if (typeof(v1) == "string") {

                     returnv1.localeCompare(v2);

                }

                return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);

           };

         

            this.data.sort(s.direction,fn);

            if (this.snapshot&& this.snapshot != this.data) {

                 this.snapshot.sort(s.direction,fn);

            }  

         }

    }

将这段代码放到ext-all.js或放到页面的最前面,反正在ext初始化后,调用实际代码前就可以了。

 

11.9显示日期类型数据

完整的代码:

var cm = newExt.grid.ColumnModel([

        {header:'编号',dataIndex:'id',width:50},

        {header:'名称',dataIndex:'name',width:100,sortable:true},

        {header:'生日',dataIndex:'birthday',width:100,sortable:true,

            /* renderer:new Ext.util.Format.dateRenderer('y-m-d') */

            renderer:function(value) {

                if (value instanceof Date) {

                    returnnew Date(value).format('y-m-d');

                }      

                return value;

            }

        },

        {id:'descn',header:'描述',dataIndex:'description',width:200}

    ]);

   

    var data = [

        ['1','','desc1','2000-01-15'],

        ['2','','desc2','2010-01-15'],

        ['3','','desc3','2006-01-15'],

        ['4','','desc4','2009-01-15'],

        ['5','','desc5','2002-01-15']

    ];

   

    var store = newExt.data.Store({

        proxy:newExt.data.MemoryProxy(data),

        reader:newExt.data.ArrayReader({},[

            {name:'id'},

            {name:'name'},

            {name:'description'},

            {name:'birthday'}

        ]),

        sortInfo:{field:'name',direction:'ASC'}

    });

   

    var grid1 = newExt.grid.GridPanel({

        title:'员工信息',

        renderTo:'grid1',

        cm:cm,

        store:store,

        width:500,

        height:350,

        enableColumnMove:false,

        enableColumnResize:true,

        loadMask:true,

        /* viewConfig:{

            forceFit:true

        } */

        autoExpandColumn:'descn'

    });

    store.load();

在上面的代码中,我加了一列birthday,本来按照文章中的说法,

ColumnModelbirthday列加

type:’date’,renderer:newExt.util.Format.DateRenderer(‘y-m-d’)

Store中的birthday列增加type:’date’,dateFormat:’y-m-d’都不行,没法显示birthday

然后在往上看到Ext日期格式化的问题,我就想着还不如在后台就格式化好,然后传递一个字符串到页面,直接显示。但是如果是可编辑的列,即日期可以编辑,这样就有问题了,显示的又不对。那么综合起来,就像上面的代码写的,重新写了renderer,如果是Date型就格式化,否则就直接返回。

 

11.10在表格中显示红色的字、图片和按钮

在上面的代码基础上,增加了性别这一列,让男性显示为红色,女性显示为绿色。其实,很简单,通过自定义renderer就可以实现了。

{

header : '性别',

dataIndex : 'sex',

sortable : true,

renderer : function(value) {

  if (value == 'man') {

      return'<spanstyle="color:red;font-weight:bold">'+ value + '</span>';

  }

  return'<spanstyle="color:green;font-weight:bold">'+ value + '</span>';

}

}      

结果:

 

 

在性别前加图片,这个更容易了。

{

header : '性别',

dataIndex : 'sex',

sortable : true,

renderer : function(value) {

  if (value == 'man') {

      return'<spanstyle="color:red;font-weight:bold"><img src=”../imgs/man.png”/>'+ value + '</span>';

  }

  return'<spanstyle="color:green;font-weight:bold"><img src=”../imgs/woman.png”/>'+ value + '</span>';

}

}      

 

我们可以在renderer中得到多个参数,如下所示:

Value:要显示的单元格的值。

Cellmeta:单元格的相关属性,主要是Id和Css。

Record:这一行的数据对象,要获取某个列的值,可以通过record.data[“name”]这样获取。

rowIndex:行号,这里的行号是所有记录的顺序。

columnIndex:列号。

Store:创建表格时传递的数据存储器,通过它可以获取表格所有的数据。

 

参数的顺序:

renderer:function(value,cellmeta,record,rowIndex,columnIndex,store) {

                   

}

 

11.11为表格的奇偶行设置不同的颜色

在viewConfig中增加getRowClass配置项,用它来处理。

var grid1 = newExt.grid.GridPanel({

        title : '员工信息',

        renderTo : 'grid1',

        cm : cm,

        store : store,

        width : 700,

        height : 350,

        enableColumnMove : false,

        enableColumnResize : true,

        loadMask : true,

        viewConfig:{

        forceFit:true,

        getRowClass:function(record,rowIndex,p,ds){

            if (rowIndex % 2 ==0) {

                return'oushu-row-color';

            }

            return'jishu-row-color';

        }

    },

    autoExpandColumn : 'descn'

});

 

CSS

<style>

    .jishu-row-color{

        background-color:white;

    }

   

    .oushu-row-color {

        background-color:yellow;

    }

</style>   

 

结果:

 

 

11.12自动显示行号

只需要在ColumnModel中加入一行代码就可以了。

 

 

还存在一个问题,如果删除表格中的数据,行号就不连续了。那么我们就需要刷新Grid视图,让Grid重新计算行号。

我们在表格上添加一个右键菜单,用它来执行删除操作。

// 添加右键菜单。

grid1.addListener('rowcontextmenu', function(grid, rowIndex, e) {

    e.preventDefault();

    var menu = newExt.menu.Menu({

        id : Ext.id(),

        items : [ {

                id : Ext.id(),

                text : '<span font-weight:"BOLD">删除人员信息</span>',

                handler : function() {

                        store.remove(store.getAt(rowIndex));// 删除对应行的数据

                        grid1.view.refresh(); //刷新视图,重新计算行号

                }

    }

    ]

});

                   

menu.showAt(e.getXY());

});    

           

 

11.13显示复选框

在ColumnModel中和Grid中增加CheckboxSelectionModel即可。

// 复选框

var sm = newExt.grid.CheckboxSelectionModel();

var cm = newExt.grid.ColumnModel(

     [

    new Ext.grid.RowNumberer(),

    sm,

    {

        header : '编号',

        dataIndex : 'id',

        width : 50

    },

    {

        header : '名称',

        dataIndex : 'name',

        width : 100,

        sortable : true

    },

    {

        header : '生日',

        dataIndex : 'birthday',

        width : 100,

        sortable : true,

        /* renderer:new Ext.util.Format.dateRenderer('y-m-d') */

        renderer : function(value) {

            if (value instanceof Date) {

                returnnew Date(value).format('y-m-d');

            }

            return value;

        }

    },

    {

        header : '性别',

        dataIndex : 'sex',

        sortable : true,

        renderer : function(value) {

            if (value == 'man') {

                return'<spanstyle="color:red;font-weight:bold">'+ value + '</span>';

            }

            return'<span style="color:green;font-weight:bold">'+ value + '</span>';

        }

    }, {

       id: 'descn',

       header: '描述',

       dataIndex: 'description',

       width: 200

} ]);

 

var grid1 = newExt.grid.GridPanel({

    title : '员工信息',

    renderTo : 'grid1',

    cm : cm,

    store : store,

    width : 700,

    height : 350,

    enableColumnMove : false,

    enableColumnResize : true,

    loadMask : true,

    viewConfig:{

        forceFit:true,

        getRowClass:function(record,rowIndex,p,ds){

            if (rowIndex %2 == 0) {

                return'oushu-row-color';

            }

            return'jishu-row-color';

        }

    },

    autoExpandColumn : 'descn',

    sm:sm

});

 

结果:

 

 

Grid里面提供的这种功能称为行选择模型,单击某个单元格时,选中的是整行,Ext默认的是RowSelectionModel——行选择模型。行选择模型默认支持多选,鼠标单击时按住ctrl/shift就可以选择多行。如果只希望选择一行,设置singleSelect参数为true。

在Grid中设置sm为RowSelectionModel,并指定singleSelect为true。

var grid1 = newExt.grid.GridPanel({

    title : '员工信息',

    renderTo : 'grid1',

    cm : cm,

    store : store,

    width : 700,

    height : 350,

    enableColumnMove : false,

    enableColumnResize : true,

    loadMask : true,

    viewConfig:{

        forceFit:true,

        getRowClass:function(record,rowIndex,p,ds){

            if (rowIndex %2 == 0) {

                return'oushu-row-color';

            }

            return'jishu-row-color';

        }

    },

    autoExpandColumn : 'descn',

    sm:new Ext.grid.RowSelectionModel({

        singleSelect:true

})

});

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值