表格控件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、付费专栏及课程。

余额充值