18.1分组表格的使用
先看一个例子:
Ext.onReady(function() {
Ext.QuickTips.init();
// data for grid
var data = [
[1,"张三",20,"man"],
[2,"里斯",22,"man"],
[3,"李四",24,"man"],
[4,"丽丝",25,"woman"],
[5,"王五",26,"man"],
[6,"王武",26,"man"],
[7,"周瑜",27,"man"],
[8,"小乔",27,"woman"],
[9,"罗密欧",27,"man"],
[10,"朱丽叶",28,"woman"]
];
// array reader
var reader =new Ext.data.ArrayReader({},[
{name:"id",type:"int"},
{name:"name"},
{name:"age",type:"int"},
{name:"sex"}
]);
// grid
vargrid = newExt.grid.GridPanel({
title:"分组表格",
columns:[
{header:"编号",dataIndex:"id",sortable:true},
{header:"名字",dataIndex:"name"},
{header:"年龄",dataIndex:"age",sortable:true},
{header:"性别",dataIndex:"sex",sortable:true}
],
store:newExt.data.GroupingStore({
data:data,
reader:reader,
groupField:"sex",// 分组字段,即根据性别分组
sortInfo:{// sortInfo要求必须配置
field:"id", //排序字段
direction:"ASC"// 升序排列
}
}),
frame:true,
width: 700,
height: 450,
collapsible: true,
animCollapse: false,
renderTo: document.body,
//height:350,
view:newExt.grid.GroupingView({
forceFit:true,// 自动扩充各列以填满表格
//groupTextTpl:'{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" :"Item"]})'
groupTextTpl:"{text}({values.rs.length}条数据)"//分组显示内容。
})
});
});
效果:
解析:1.定义了一组数据data
2.使用GroupingStore,对“性别”列进行分组,而且根据id进行升序排列
3.而且为了显示的效果是这样的,还必须在GridPanel中配置View为Ext.grid.GroupingView。
否则显示的效果就是这样的:
再GroupingView中:
groupTextTpl:"{text}({values.rs.length}条数据)",这个看截图应该就明白了,分组显示时显示此分组有多少条数据。
groupTextTpl:'{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" :"Item"]})',这个意思也很明显,就是如果某个分组的记录只有1条,则显示’XItem’,否则,显示’XXItems’。
18.2分组表格常用功能
现在添加4个按钮,分别实现:展开所有分组、收缩所有分组、自动展开或收缩所有分组、自动展开或伸缩某个分组。
代码:
首先,再HTML中添加4个BUTTON。
<inputtype="button"id="one"value="ExpandAll"/>
<inputtype="button"id="two"value="CollapseAll"/>
<inputtype="button"id="three"value="Toggle"/>
<inputtype="button"id="four"value="ToggleOne"/>
然后在js中添加Click事件处理。
// 增加4各按钮实现展开、收缩所有分组或单个分组。
// 展开所有分组
Ext.get("one").on("click",function() {
// get GroupingView
var view = grid.getView();
view.expandAllGroups();
});
// 关闭所有分组
Ext.get("two").on("click",function() {
// get GroupingView
var view = grid.getView();
view.collapseAllGroups();
});
// 自动展开或收缩所有分组
Ext.get("three").on("click",function() {
// get GroupingView
var view = grid.getView();
view.toggleAllGroups();
});
// 自动展开或收缩某个分组
Ext.get("four").on("click",function() {
// get GroupingView
var view = grid.getView();
var groupId = view.getGroupId("woman");
view.toggleGroup(groupId);
});
18.3拖动改变表格大小
在表格render后,添加Resizable。
// 让表格可以拖动改变大小
var resize =new Ext.Resizable(document.body,{
minHeight:100, // 拖动最小高度100
handles: 'all', // 可以向各个方向拖动
pinned:true,//true:会一直显示可以拖动的提示;false:鼠标移上去才显示
wrap:true //为TRUE会再表格外包裹一层div
});
// 触发resize事件,表格调用syncSize改变自身大小。Grid为作用scope。
resize.on("resize",grid.syncSize,grid);
document.body:可以拖动的区域。
Handles:拖动的方向。All:所有方向。N:北,S:南,E:东,W:西。Nw:西北,sw:西南,se:东南,ne:东北。东、南、西、北分别对应上、下、左、右。
18.4在同一个表格里拖放数据
表里面的数据都是以行为单位,因此这里也是指行之间的拖放。
A. 将GridPanel中enableDragDrop设置为true。
此时拖动是这样的:
可以看到,这样是不能拖放的。因为没有设置拖放的DropTarget,不知道往哪儿放数据。
B. 将表格容器设置为DropTarget,让数据在表格内拖放。
vardropTarget= newExt.dd.DropTarget(grid.container,{
ddGroup:"groupingGroup",
copy:false,
notifyDrop:function(dd,e,sd) {//DragSource,Event,Object(包含拖放的数据)
//获取拖放的行
var rows = sd.selections;
//alert(rowsinstanceofArray);//Record数组
//拖动到第几行
var rowIndex =dd.getDragData(e).rowIndex;
if (typeof(rowIndex) =='undefind') {
return;
}
for (vari=0;i<rows.length;i++) {
var row = rows[i];
//alert(rowinstanceofExt.data.Record);//true
if (!this.copy) {// copy:false,表示删除原数据
store.remove(row);
}
}
//插入到拖放的位置,一次可以插入多行Records
store.insert(rowIndex,rows);
}
});
在Grid中增加ddGroup配置(默认值是GridDD),DropTarget中ddGroup要与Grid中一致,这样才能把数据拖放到表格上。
DropTarget中copy:false表示删除,即将数据拖放到新位置后,删除原来位置的数据。
拖放事件触发时会调用notifyDrop()方法,该方法有3各参数:DropSource,Event,Object(包含拖放数据)。
通过这3个参数可以获取拖放的数据,拖放到哪一行。然后判断是否是copy,如果为TRUE,则直接将拖放的数据insert到被拖放位置;如果不是copy,则先删除被拖放的数据,然后insert数据到被拖放到的位置。
效果:
首先呢,拖放时显示的是OK图标,表示可以拖放。
看看拖放后的效果:
我将第一行数据拖放到第7行后面:
18.5表格之间数据拖放
代码:
/**
*表格与表格之间数据拖放。
*2个表格的ddGroup需要一样,这样才可以将一个表格上的数据拖放到令一个表格。
*/
Ext.onReady(function() {
// data for grid
var data1 = [
[2,"里斯",22,"man"],
[3,"李四",24,"man"],
[4,"丽丝",25,"woman"],
[5,"王五",26,"man"],
[6,"王武",26,"man"],
[7,"周瑜",27,"man"],
[8,"小乔",27,"woman"],
[9,"罗密欧",27,"man"],
[10,"朱丽叶",28,"woman"]
];
var data2 = [[1,"张三",20,"man"]];
// array reader
var reader =new Ext.data.ArrayReader({},[
{name:"id",type:"int"},
{name:"name"},
{name:"age",type:"int"},
{name:"sex"}
]);
varstore1= new Ext.data.Store({
data:data1,
reader:reader
});
var store2 =new Ext.data.Store({
data:data2,
reader:reader
});
// 创建2个表格。
var grid1 =new Ext.grid.GridPanel({
id:"grid1",
title:"Grid1",
viewConfig:{
forceFit:true
},
columns:[
{header:"编号",dataIndex:"id",sortable:true},
{header:"名字",dataIndex:"name"},
{header:"年龄",dataIndex:"age",sortable:true},
{header:"性别",dataIndex:"sex",sortable:true}
],
store:store1,
frame:true,
width: 500,
height:200,
collapsible: true,
animCollapse: false,
enableDragDrop :true,
renderTo: "grid1",
ddGroup:"groupingGroup"
});
var grid2 =new Ext.grid.GridPanel({
id:"grid2",
title:"Grid2",
viewConfig:{
forceFit:true
},
columns:[
{header:"编号",dataIndex:"id",sortable:true},
{header:"名字",dataIndex:"name"},
{header:"年龄",dataIndex:"age",sortable:true},
{header:"性别",dataIndex:"sex",sortable:true}
],
store:store2,
frame:true,
width: 500,
height:200,
collapsible: true,
animCollapse: false,
enableDragDrop :true,
renderTo: "grid2",
ddGroup:"groupingGroup"
});
// 拖放处理
// 将grid2的数据拖放到grid1上的拖放处理
vardropTarget1 = new Ext.dd.DropTarget(grid1.container,{
ddGroup:"groupingGroup",
copy:false,
notifyDrop:function(ds,e,data) {
//拖动的数据
var rows = data.selections;
//拖放到多少行
var rowIndex = ds.getDragData(e).rowIndex;
//如果grid1只有1行,我拖放的位置是2,那么返回的rowIndex就是undefined。
//这种情况下,我们应该让它把数据插入到第一行。
if (typeof(rowIndex) =='undefined') {
rowIndex = store1.getCount()==0?0:store1.getCount();
}
for (var i=0;i<rows.length;i++) {
var row = rows[i];
if (!this.copy) {
// store1和store2保存的是不同的数据,如果拖放的数据在store1中,说明是从grid2拖放到grid1或者grid1行间拖放。
//正常情况下,即2个表格之间的拖放,从grid1拖放到grid2,则应该删除store1中的数据。
//但是如果同一个表格之间拖放呢?因为数据不同,所以,拖放的数据跟哪个store相同,则应该从那个Store中清除。
if(store2.indexOf(row) != -1) {// -1表明没有找到。
store2.remove(row);// 将grid2中的数据删除
}
else {
store1.remove(row); // 将grid2中的数据删除
}
}
}
store1.insert(rowIndex,rows);// 将拖放的数据insert到grid1
}
});
// 将grid1的数据拖放到grid2上的拖放处理
vardropTarget2 = new Ext.dd.DropTarget(grid2.container,{
ddGroup:"groupingGroup",// 需要与grid1一样
copy:false,
notifyDrop:function(ds,e,data) {
//拖动的数据
var rows = data.selections;
//拖放到多少行
var rowIndex = ds.getDragData(e).rowIndex;
if (typeof(rowIndex) =='undefined') {
rowIndex =store2.getCount()==0?0:store2.getCount();
}
for (var i=0;i<rows.length;i++) {
var row = rows[i];
if (!this.copy) {
if (store1.indexOf(row) !=-1) {
store1.remove(row); // 将grid1中的数据删除
}
else {
store2.remove(row);// 将grid1中的数据删除
}
}
}
store2.insert(rowIndex,rows);// 将拖放的数据insert到grid2
}
});
});
效果:
这是初始的样子,现在将Grid1中的2,3,4这3条数据拖放到Grid2
这里的拖放包含2种情况:
1. grid1与grid2之间的拖放。
2. 同一个表格行间的拖放。
因为2个表格的数据是不同的,因此拖放的数据包含在哪个store,就应该从哪个store中删除。
很明显,如果是表格1与表格2之间的拖放,则应该删除表格1的数据,insert到表格2;如果是同一个表格的拖放,则应先删除再insert。
18.6表格与树之间的拖放
18.7Grid与右键菜单
Grid提供了4个与右键菜单相关的事件:
事件 |
参数 |
说明 |
Contextmenu |
Ext.EventObject e |
全局性的右键菜单事件 |
Cellcontextmenu |
Grid this,Number rowIndex,Number cellIndex,Ext.EventObject e |
单元格右键菜单事件 |
Rowcontextmenu |
Grid this,Number rowIndex,Ext.EventObject e |
行右键菜单事件 |
Headercontextmenu |
Grid this,Number cellIndex,Ext.EventObject e |
表头右键菜单事件 |
对4种右键菜单事件的处理参考:
var contextmenuEventHandler =function() {
};
// 添加右键菜单
var contextmenu =new Ext.menu.Menu({
items:[
{
text:'查看详细信息',
handler:function() {
if(contextmenuEventHandler.eventType == 0) {//contextmenu
Ext.Msg.show({
title:'提示',
msg:"全局右键菜单"
});
}
elseif(contextmenuEventHandler.eventType== 1){// rowcontextmenuvar grid =contextmenuEventHandler.grid;
var rowIndex =contextmenuEventHandler.rowIndex;
var record =grid.getStore().getAt(rowIndex);
var propertyGrid =newExt.grid.PropertyGrid({
title:"详细信息",
width:500,
autoHeight:true,
renderTo:grid.id,
source:{
"ID":record.data.id,
"NAME":record.data.name,
"AGE":record.data.age,
"SEX":record.data.sex
},
tbar:new Ext.Toolbar({
items:[{
text:"Close",
handler:function() {
propertyGrid.hide();
}
}]
})
});
}
elseif(contextmenuEventHandler.eventType == 2) {// cellcontextmenu
vargrid =contextmenuEventHandler.grid;
varrowIndex =contextmenuEventHandler.rowIndex;
varcellIndex =contextmenuEventHandler.cellIndex;
Ext.Msg.show({
title:"提示",
msg:"单元格右键菜单事件"
}) ;
}
elseif(contextmenuEventHandler.eventType == 3) {// headercontextmenu
vargrid =contextmenuEventHandler.grid;
var columnIndex =contextmenuEventHandler.columnIndex;
Ext.Msg.show({
title:"表头右键菜单事件",
msg:"columnIndex:"+ columnIndex
});
}
}
}
]
});
/*grid.on("contextmenu",function(e){
e.preventDefault(); // 阻止弹出默认浏览器菜单
contextmenuEventHandler.eventType = 0;
contextmenu.showAt(e.getXY());
});*/
grid.on("rowcontextmenu",function(grid,rowIndex,e) {
e.preventDefault(); // 阻止弹出默认浏览器菜单
grid.getSelectionModel().selectRow(rowIndex);
contextmenuEventHandler.eventType = 1;
contextmenuEventHandler.grid = grid;
contextmenuEventHandler.rowIndex =rowIndex;
contextmenu.showAt(e.getXY());
});
/*grid.on("cellcontextmenu",function(grid,rowIndex,cellIndex,e){
e.preventDefault(); // 阻止弹出默认浏览器菜单
contextmenuEventHandler.eventType = 2;
contextmenuEventHandler.grid = grid;
contextmenuEventHandler.rowIndex =rowIndex;
contextmenuEventHandler.cellIndex =cellIndex;
contextmenu.showAt(e.getXY());
});*/
grid.on("headercontextmenu",function(grid,columnIndex,e){
e.preventDefault(); // 阻止弹出默认浏览器菜单
contextmenuEventHandler.eventType = 3;
contextmenuEventHandler.grid = grid;
contextmenuEventHandler.columnIndex =columnIndex;
contextmenu.showAt(e.getXY());
});