JavaScript的ExtJS框架中表格的编写教程

ExtJS中表格的特性简介
表格由类Ext.grid.GridPanel定义,继承自Ext.Panel,xtype为grid
表格的列信息由Ext.grid.ColumnModel定义
表格的数据存储器由Ext.data.Store定义,根据解析数据的不同,数据存储器可具体分为如下几种:

JsonStore,SimpleStore,GroupingStore…

一个表格的基本编写过程:

1、创建表格列模型

var cm = new Ext.grid.ColumnModel({
 {header: '角色', dataIndex: 'role'},
 {header: '等级', dataIndex: 'grade'},
 {header: '创建日期', dataIndex: 'createDate', type: 'date', renderer: Ext.util.Format.dateRenderer('Y年m月d日')} //创建日期类型的数据
});

2、创建数据数组

var data = [
 ['士兵','7','2011-07-2412:34:56'],
 ['将军','10','2011-07-2412:34:56'],
];

3、创建一个数据存储对象store,包含两部分:proxy,获取数据的方式;reader,解析数据的方式

ArrayReader的mapping用来设置列的排列顺序

var store = new Ext.data.Store({
 proxy: new Ext.data.MemoryProxy(data),
 reader: new Ext.data.ArrayReader({}, [
 {name: 'role', mapping: 1},
 {name: 'grade', mapping: 0}
 {name: 'createDate', mapping: 2, type:'date', dateFormat:'Y-m-dH:i:s'} //创建日期列和显示格式
 ])
});
store.load();

4、创建GridPanel,装配ColumnModel和store

var grid = new Ext.grid.GridPanel({
 renderTo: 'grid',
 store: store,
 cm: cm
});

另外获取远程数据可以使用ScriptTagProxy,如下所示

var store = new Ext.data.Store({
 proxy: new Ext.data.ScriptTagProxy({
 url:'http://...'}),
 reader: new Ext.data.ArrayReader({}, [
 {name: 'role', mapping: 1},
 {name: 'grade', mapping: 0}
 ]),
 sortInfo: {field: "role", direction: "ASC"} //设置默认排序列,ASC/DESC
});


表格的常用属性功能

var grid = new Ext.grid.GridPanel({
 enableColumnMove: false, //禁止拖放列
 enableColumnResize: false, //禁止改变列的宽度
 stripeRows: true, //斑马线效果
 loadMask: true, //读取数据时的遮罩和提示功能
 renderTo: 'grid',
 store: store
 cm: cm
});

var cm = new Ext.grid.ColumnModel({
 {header: '角色', dataIndex: 'role', width:90, sortable: true}, //width设置列宽度,默认为100px,sortable设置排序功能
 {id:'grade', header: '等级', dataIndex: 'grade', width:40}
});
var grid = new Ext.grid.GridPanel({
 renderTo: 'grid',
 store: store,
 cm: cm
 viewConfig:{ //让每列自动填充满表格
 forceFit: true
 }
 autoExpandColumn: 'grade' //自动延伸列,列的id在ColumnModel中定义
});

渲染表格,为表格设置特殊样式
只需要在cm里面增加一个renderer属性,添加一个自定义函数来渲染传进来(由EXT自动传递)的参数的样式即可,即在返回value之前拼装上相应的HTML和CSS或者JS响应事件。

function renderSex(value) {
 if (value == 'male') {
 return "<span style='color:blue;'>男</span><img src='images/icon_male.png' />";
 } else {
 return "<span style='color:red;'>女</span><img src='images/icon_female.png' />";
 }
}

var cm = new Ext.grid.ColumnModel([
 {header:'id',dataIndex:'id'},
 {header:'name',dataIndex:'name'},
 {header:'sex',dataIndex:'sex',renderer:renderSex},
]);

var data = [
 ['1','Jason','male'],
 ['2','Kate','female']
];

var store = new Ext.data.Store({
 proxy: new Ext.data.MemoryProxy(data),
 reader: new Ext.data.ArrayReader({}, [
 {name: 'id'},
 {name: 'name'},
 {name: 'sex'}
 ])
});
store.load();

var grid = new Ext.grid.GridPanel({
 autoHeight: true,
 renderTo: 'grid',
 store: store,
 cm: cm
});

自动显示行号,只要在创建cm时创建一个RowNumberer就可以了

var cm = new Ext.grid.ColumnModel([
 new Ext.grid.RowNumberer(), //显示行号
 {header:'id',dataIndex:'id'},
 {header:'name',dataIndex:'name'},
 {header:'sex',dataIndex:'sex',renderer:renderSex},
]);

删除列

store.remove(store.getAt(i));

刷新表格

grid.view.refresh();

为表格添加复选框
需要使用CheckboxSelectionModel
SelectionModel sm在使用时要放到cm和表格中

var sm = new Ext.grid.CheckboxSelectionModel();

var cm = new Ext.grid.ColumnModel([
 new Ext.grid.RowNumberer(),
 sm,
 {header:'编号',dataIndex:'id'},
 {header:'名称',dataIndex:'name'}
]);

var data = [
 ['1','name1'],
 ['2','name2']
];

var store = new Ext.data.Store({
 proxy: new Ext.data.MemoryProxy(data),
 reader: new Ext.data.ArrayReader({}, [
 {name: 'id'},
 {name: 'name'}
 ])

});
store.load();

var grid = new Ext.grid.GridPanel({
 autoHeight: true,
 renderTo: 'grid',
 store: store,
 cm: cm,
 sm: sm
});

通过RowSelectionModel设置只选择一行:

var grid = new Ext.grid.GridPanel({
 autoHeight: true,
 renderTo: 'grid',
 store: store,
 cm: cm,
 sm: new Ext.grid.RowSelectionModel({singleSelect:true})
});

使用选择模型获取数据

grid.on('click', function() {
 var selections = grid.getSelectionModel().getSelections();
 for (var i = 0; i < selections.length; i++) {
 var record = selections[i];
 Ext.Msg.alert(record.get("id"));
 }
});

表格视图
从MVC的思想来看表格控件:
* Ext.data.Store可看做模型
* Ext.grid.GridPanel可看做控制器
* Ext.grid.GridView可看做视图
* 一般GridView由GridPanell自动生成,如果想设置GridView的属性时,可以通过Ext.grid.GridPanel的getView()获得视图实例

Ext.get('button1').on('click', function() {
 grid.getView().scrollToTop();
 grid.getView().focusCell(0, 0);
 var cell = grid.getView().getCell(0, 0);
 cell.style.backgroundColor = 'red';
});

使用GridPanel的viewConfig在创建表格时设置GridView的初始化参数

var grid = new Ext.grid.GridPanel({
 height: 100,
 width: 400,
 renderTo: 'grid',
 store: new Ext.data.Store({
 autoLoad: true,
 proxy: new Ext.data.MemoryProxy(data),
 reader: new Ext.data.ArrayReader({}, meta)
 }),
 columns: meta,
 viewConfig: {
 columnsText: '显示的列', //设置下拉菜单提示文字
 scrollOffset: 30, //设置右侧滚动条的预留宽度
 sortAscText: '升序', //设置下拉菜单提示文字
 sortDescText: '降序', //设置下拉菜单提示文字
 forceFit: true //自动延展每列的长度
 }
});

为表格添加分页工具条
* 可以使用GridPanel的bbar属性,并创建Ext.PagingToolbar分页工具条对象
* 注意,如果配置了分页工具条,store.load()就必须在构造表格以后执行。

var grid = new Ext.grid.GridPanel({
 renderTo: 'grid',
 autoHeight: true,
 store: store,
 cm: cm,
 bbar: new Ext.PagingToolbar({
 pageSize: 10, //每页显示10条数据
 store: store,
 displayInfo: true, //显示数据信息
 displayMsg: '显示第 {0} 条到 {1} 条记录,一共 {2} 条',
 emptyMsg: "没有记录" //没有数据时显示的信息
 })
});
store.load();

从后台脚本获取分页数据

使用HttpProxy传递请求,获取服务器的JSON数据,交给JsonReader解析

var cm = new Ext.grid.ColumnModel([
 {header:'编号',dataIndex:'id'},
 {header:'名称',dataIndex:'name'}
]);
var store = new Ext.data.Store({
 proxy: new Ext.data.HttpProxy({url:'page.jsp'}),
 reader: new Ext.data.JsonReader({
 totalProperty: 'totalProperty',
 root: 'root'
 }, [
 {name: 'id'},
 {name: 'name'}
 ])
});
var grid = new Ext.grid.GridPanel({
 renderTo: 'grid',
 autoHeight: true, //数据传回来之前高度未知,所以要使用自适应高度
 store: store,
 cm: cm,
 bbar: new Ext.PagingToolbar({
 pageSize: 10,
 store: store,
 displayInfo: true,
 displayMsg: '显示第 {0} 条到 {1} 条记录 / 共 {2} 条',
 emptyMsg: "没有记录"
 })
});
store.load({params:{start:0,limit:10}});

如果想让分页工具条显示在表格的顶部,可以使用GridPanel的tbar属性设置添加工具条

让ExtJS在对返回的数据进行分页

* 需要在页面中引入examples/locale目录下的PagingMemoryProxy.js文件
* 再使用PagingMemoryProxy设置代理

var store = new Ext.data.Store({
 proxy: new Ext.data.PagingMemoryProxy(data),
 reader: new Ext.data.ArrayReader({}, [
 {name: 'id'},
 {name: 'name'},
 {name: 'descn'}
 ])
});
//在创建GridPanel之后调用
store.load({params:{start:0,limit:3}});

可编辑表格控件EditorGrid的使用

制作一个简单的EditorGrid的步骤:

1、定义列ColumnModel,在里面添加editor属性

var cm = new Ext.grid.ColumnModel([{
 header: '编号',
 dataIndex: 'id',
 editor: new Ext.grid.GridEditor(
 new Ext.form.TextField({
 allowBlank: false //不允许在TextField中输入空值
 })
 )
}, {
 header: '名称',
 dataIndex: 'name',
 editor: new Ext.grid.GridEditor(
 new Ext.form.TextField({
 allowBlank: false
 })
 )
}]);

2、准备一个数组

var data = [
 ['1','Jason'],
 ['2','Jay']
];

3、创建Ext.data.Store,设置内存代理,设置ArrayReader解析数组

var store = new Ext.data.Store({
 proxy: new Ext.data.MemoryProxy(data),
 reader: new Ext.data.ArrayReader({}, [
 {name: 'id'},
 {name: 'name'}
 ])
});

4、加载数据,创建EditorGridPanel

store.load();
var grid = new Ext.grid.EditorGridPanel({
 autoHeight: true,
 renderTo: 'grid',
 store: store,
 cm: cm
});

为可编辑表格添加和删除数据

1、使用Record的create方法创建一个记录集MyRecord,MyRecord相当于一个类

var MyRecord = Ext.data.Record.create([
 {name: 'id', type: 'string'},
 {name: 'name', type: 'string'}
]);
store.load();

2、创建EditorGridPanel面板,在属性tbar中创建Ext.Toolbar

var grid = new Ext.grid.EditorGridPanel({
 autoHeight: true,
 renderTo: 'grid',
 store: store,
 cm: cm,
 tbar: new Ext.Toolbar(['-', { //-表示菜单分隔符
 text: '添加一行',
 handler: function(){
 var p = new MyRecord({
 id:'',
 name:''
 });
 grid.stopEditing(); //关闭表格的编辑状态
 store.insert(0, p); //创建的Record插入store的第一行
 grid.startEditing(0, 0); //激活第一行第一列的编辑状态
 }
 }, '-', {
 text: '删除一行',
 handler: function(){
 Ext.Msg.confirm('信息', '确定要删除?', function(btn){
 if (btn == 'yes') {
 var sm = grid.getSelectionModel(); //获取表格的选择模型
 var cell = sm.getSelectedCell(); //获取选中的单元格
 var record = store.getAt(cell[0]); //通过行号得到store这一行对应的Record
 store.remove(record); //移除数据
 }
 });
 }
 }, '-'])
});

为可编辑表格保存修改的结果

在上面例子的基础之上,添加一个保存按钮

text: '保存',
handler: function(){
 var m = store.modified.slice(0); //获得store中修改过得数据
 for (var i = 0; i < m.length; i++) { //验证表格信息是否正确,是否包含空格
 var record = m[i];
 var fields = record.fields.keys;

 for (var j = 0; j < fields.length; j++) {
 var name = fields[j];
 var value = record.data[name];

 var colIndex = cm.findColumnIndex(name);
 var rowIndex = store.indexOfId(record.id);
 var editor = cm.getCellEditor(colIndex).field;

 if (!editor.validateValue(value)) {
 Ext.Msg.alert('提示', '请检查输入的数据是否正确!', function(){
 grid.startEditing(rowIndex, colIndex);
 });
 return;
 }
 }
 }
 var jsonArray = [];
 Ext.each(m, function(item) {
 jsonArray.push(item.data); //把修改过得数据放到jsonArray中
 });

 Ext.lib.Ajax.request( //使用Ajax请求提交给后台
 'POST',
 'save_data.jsp',
 {success: function(response){ //返回成功
 Ext.Msg.alert('信息', response.responseText, function(){
 store.reload();
 });
 },failure: function(){ //返回失败
 Ext.Msg.alert("错误", "服务器保存数据出错!");
 }},
 'data=' + encodeURIComponent(Ext.encode(jsonArray))
 );
}

另外store可以设置属性pruneModifiedRecords: true。这样,每次remove或load操作时store会自动清除modified标记,可以避免出现下次提交时还会把上次那些modified信息都带上的现象。


限制表格输入的数据类型

NumberField

{
 header:'ID',
 dataIndex:'id',
 editor:new Ext.grid.GridEditor(new Ext.form.NumberField({ //NumberField限制只能输入数字
 allowBlank: false,
 allowNegative: false, //不能输入减号
 maxValue: 10
 }))
}

ComboBox

var comboData = [
 ['0','Java'],
 ['1','Android']
];
{
 header:'ComboBox',
 dataIndex:'combo',
 editor:new Ext.grid.GridEditor(new Ext.form.ComboBox({
 store: new Ext.data.SimpleStore({
 fields:['value','text'],
 data: comboData
 }),
 emptyText: '请选择',
 mode: 'local',
 triggerAction: 'all',
 valueField: 'value',
 displayField: 'text',
 readOnly:true
 })),
 renderer: function(value){
 return comboData[value][1];
 }
}

DateField

{
 header:'Date',
 dataIndex:'date',
 editor:new Ext.grid.GridEditor(new Ext.form.DateField({
 format: 'Y-m-d',
 minValue: '2011-07-24',
 disabledDays: [0, 6],
 disabledDaysText: '选择周一到周六之间的日期'
 })),
 renderer: function(value) {
 return value.format("Y-m-d");
 }
}

属性表格控件PropertyGrid的使用
是在EditorGrid的基础上开发的更智能的高级表格组件

var grid = new Ext.grid.PropertyGrid({
 title: '属性表格控件PropertyGrid',
 autoHeight: true,
 width: 400,
 renderTo: 'grid',
 viewConfig: {
 forceFit: true
 },
 source: {
 "String": "String",
 "Date": new Date(Date.parse('07/24/2011')),
 "boolean": false,
 "float": .01
 }
});

禁用PropertyGrid编辑功能的方法

grid.on('beforeedit', function(e){
 e.cancel = true;
 return false;
});

根据表格的name获取value

grid.store.getById('Jason').get(value);


ExtJS中实现嵌套表格
先看效果:

2016521104833438.jpg (433×300)

代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>test</title>
<script type="text/javascript">
</script>
<link rel="stylesheet" type="text/css" href="Lib/ExtJs/2_2/resources/css/ext-all.css" />
<script type="text/javascript" src="Lib/ExtJs/2_2/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="Lib/ExtJs/2_2/ext-all-debug.js"></script>
<script type="text/javascript" src="Lib/ExtJs/2_2/source/locale/ext-lang-zh_CN.js"></script>
<script type="text/javascript" src="Lib/ExtJs/plus/RowExpander.js"></script>
<script type="text/javascript">
Ext.onReady(function(){
var testData=[
 ["lugreen","男",26,[["数学",100],["语文",150]]]
 ,["lisi","男",25,[["数学",100],["语文",150]]]
 ,["zhangsan","男",27,[["数学",120],["语文",158]]] 
];
//
storeTest= new Ext.data.SimpleStore({
 fields: ["name","sex","age","grade"]
 ,data: testData
});
var expander = new Ext.grid.RowExpander({
 tpl : new Ext.XTemplate(
 '<div class="detailData">',
 '',
 '</div>'
 )
 });
expander.on("expand",function(expander,r,body,rowIndex){
 //查找 grid 
 window.testEle=body;
 //alert(body.id);
 if (Ext.DomQuery.select("div.x-panel-bwrap",body).length==0){
 //alert("a");
 var data=r.json[3];
 var store=new Ext.data.SimpleStore({
 fields: ["class","degrade"]
 ,data:data
 });
 var cm = new Ext.grid.ColumnModel([
 {header: "科目",dataIndex: 'class',width: 130,hideable:false,sortable:false,resizable:true}
 ,{header: "成绩",dataIndex: 'degrade',width: 130,hideable:false,sortable:false,resizable:true}
 ]);
 Ext.DomQuery.select("div.detailData")[0];
 var grid = new Ext.grid.GridPanel(
 {
 store:store,
 cm:cm,
 renderTo:Ext.DomQuery.select("div.detailData",body)[0],
 autoWidth:true,
 autoHeight:true
 }
 );
 
 }
});
//var sm=new Ext.grid.CheckboxSelectionModel({singleSelect:true});
 var cm = new Ext.grid.ColumnModel([
 expander
 ,{header: "姓名",dataIndex: 'name',width: 50,hideable:false,sortable:false}
 ,{header: "性别",dataIndex: 'sex',width: 130,hideable:false,sortable:false,resizable:true}
 ,{header: "年龄",dataIndex: 'age',width: 130,hideable:false,sortable:false,resizable:true}
 ]);
 var grid = new Ext.grid.GridPanel(
 {
 id:'testgrid',
 store:storeTest,
 cm:cm,
 renderTo:"grid1",
 width:780,
 autoHeight:false,
 height:300,
 listeners:{},
 plugins:[expander]
 }
 );
});
</script>
<style type="text/css">
#div2 h2 {
 font-weight:200;
 font-size:12px;
}
.c1 h2 {
 font-weight:200;
}
</style>
</head>
<body>
<div id="grid1">
 
</div>
<div id="grid2">
 
</div>
</body>
</html>

其中使用到的"RowExpander.js"为extjs官方示例中自带的。

实现这个嵌套表格要注意两点技巧:
1.提供给外层表格的dataStore的数据源以嵌套数组的形式表示细节区的数据,如下面的黑体所示。

var testData=[
 ["lugreen","男",26,[["数学",100],["语文",150]]]
 ,["lisi","男",25,[["数学",100],["语文",150]]]
 ,["zhangsan","男",27,[["数学",120],["语文",158]]] 
];

使用数组集中record对象的json属性来获取以细节区数据

var data=r.json[3];

2.在rowExpander的 expand事件中添加嵌套表格.

    作者:郑文亮

    %s 个评论

    要回复文章请先登录注册