深入浅出ExtJS 第三章 表格控件
1 3.1 表格的特性简介 2 >.Ext中的表格功能:包括排序/缓存/拖动/隐藏某一列/自动显示行号/列汇总/单元格编辑等实用功能; 3 >.表格由类Ext.grid.GridPanel定义,继承自Ext.Panel,其xtype为grid; 4 >.表格控件必须包含列(columns)定义信息,并指定表格的数据存储器(Ext.data.Store);
1 3.2 制作一个简单的表格 2 >1.列的定义是一个JSON数组,它是整个表格的列模型,应该首先创建; 3 var columns = [ 4 {header:'编号',dataIndex:'id'}, 5 //每一行数据元素描述表格的一列信息; 包含首部显示文本(header),列对应的记录集字段(dataIndex); 6 {header:'名称',dataIndex:'name'}, 7 {header:'描述',dataIndex:'descn'} 8 ]; 9 10 >2.定义表格中要显示的数据; 11 var data = [ 12 ['1','name1','descn1'], 13 ['2','name2','descn2'], 14 ['3','name3','descn3'] 15 ] 16 17 >3.创建一个数据存储对象;表格必须配置的属性;负责把各种各样的原始数据(如二维数组,JSON,XML等)转换成Ext.data.Record类型的对象; 18 var store = new Ext.data.ArrayStore({ 19 data:data, 20 fields:[ 21 //这里定义的3个名称与columns的dataIndex相对应;将data数据与columns列模型链接; 22 {name:'id'}, 23 //{name:'id',mapping:1}, //可以设置mapping来设置列的排序; 24 {name:'name'}, 25 {name:'descn'} 26 ] 27 }); 28 store.load(); //初始化数据; 29 //store对应两个部分:proxy(指获取数据的方式)和render(指如何解析这一堆数据); 30 31 >4.创建表格 32 var grid = new Ext.grid.GridPanel({ 33 autoHeight:true, 34 renderTo:'grid', //指示Ext将表格渲染到什么地方; 35 store:store, 36 columns:columns 37 })
1 3.3 表格常用功能 2 3.3.1 部分属性功能 3 >1.enableColumnMove 拖放移动列; 4 >2.enableColumnResize 改变列宽; 5 >3.stripeRows 斑马线效果; 6 >4.loadMask 显示"Loading..." 7 8 3.3.2 自主决定每列的宽度 9 //每列默认是100px; 10 >1.自定义列宽 11 var columns = [ 12 {header:'编号',dataIndex:'id',width:200} 13 ] 14 >2.forceFit 15 var grid = new Ext.grid.GiidPanel({ 16 renderTo:'grid', 17 forceFit:true //让每列自适应填满表格; 18 }); 19 20 3.3.3 sortable表格列排序 21 var columns = new Ext.grid.ColumnModel([ 22 {header:'编号',dataIndex:'id',sortable:true} 23 ]) 24 //Ascending:正序; Descending:倒序; 25 26 3.3.4 中文排序 27 28 3.3.5 显示日期类型数据 29 //Ext可以从后台取得日期类型的数据,交给表格进行格式化; 30 var columns = [{header:'日期',dataIndex:'date',renderer:Ext.util.Format.dateRenderer('Y-m-d')}]; 31 //renderer的属性值就是Ext提供的日期格式化方法; 32 var data = [['1','name1','descn1','1970-01-15T02:58:04']] 33 var store = new Ext.data.ArrayStore({ 34 data:data, 35 fields:[{name:'date',type:'date',dateFormat:'Y-m-dTH:i:s'}] 36 //type属性告诉ExtJS解析数据时按日期类型处理; 37 //dateFormat:将数据中的字符串格式转换成日期格式; 38 });
1 3.4 表格渲染 2 >1.修改文字颜色样式和添加图片; 3 function renderSex(value){ 4 if(value == 'male'){ 5 return "<span style='color:red; font-weight:bold'>红男</span><img src="user_male.png" />"; 6 }else{ 7 return "<span style='color:green, font-weight:bold'>绿女</span><img src="user_female.png" />"; 8 }; 9 //在返回value之前,拼装上相应的HTML和CSS即可; 10 }; 11 var columns = [{header:'性别',dataIndex:'sex',renderer:renderSex}]; 12 //renderer的值是一个自定义函数; 13 >2.其他可用参数 14 function renderDescn(value, cellmeta, record, rowIndex, columnIndex, store){ 15 var str = value+cellmeta+record+rowIndex+columnIndex+store; 16 return str; 17 } 18 //value:将要显示到单元格的值; 19 //cellmeta:单元格的属性,主要有id和CSS; 20 //record:所在行的数据对象; 21 //rowIndex:所在行行号; 22 //columnIndex:所在列列号; 23 //store:构造表格传递的ds;
1 3.5 给表格的行和列设置颜色 2 <style>.yellow-row{ background-color: #FBF8BF !important; }</style> 3 Ext.onReady(function(){ 4 5 var data = [['boy',0,'#fbf8bf']]; //表格数据; 6 7 var store = new Ext.data.ArraySotre({ //数据存储对象; 8 data:data, //引入表格数据; 并将数据转换成Ext.data.Record类型的对象; 9 fields:[ //与columns参数对应; 10 {name:'name',type:'string'}, 11 {name:'sex',type:'int'}, 12 {name:'color',type:'string'} 13 ] 14 }); 15 store.load(); //初始化数据; 16 17 var grid = new Ext.grid.GridPanel({ 18 store:store, //引入record数据对象; 19 columns:[ //创建列模型; 20 {header:'name',dataIndex:'name'}, 21 {header:'sex',dataIndex:'sex'} 22 ], 23 renderTo:'grid', 24 viewConfig:{ 25 enableRowBody:true, 26 getRowClass:function(record,rowIndex,p,ds){ 27 var cls = 'white-row'; //默认是白色; 28 switch(record.data.color){ //先查找record对象即store,再查找data属性,再查找到color在data里对应的值; 29 case '#fbf8bf': //匹配值,设置class名; 30 cls = "yellow-row" 31 break; 32 } 33 return cls; 34 } 35 } 36 }); 37 });
1 3.6 自动显示行号和复选框 2 3.6.1 自动显示行号 3 var columns = [ 4 new Ext.grid.RowNmuberer(), 5 //在列模型中加入RowNumberer对象, 6 {header:'姓名',dataIndex:'name'} 7 ] 8 >.删除行/刷新表格 9 Ext.get('remove').on('click',function(){ 10 store.remove(store.getAt(0)); //删除第一条数据; 11 grid.view.refresh(); //刷新视图重新加载store,并重新渲染模板的数据; 12 }) 13 14 3.6.2 复选框 15 var sm = new Ext.selection.CheckboxModel({checkOnly:true}); 16 //CheckboxModel会在每行数据前添加一个复选框; 17 //checkOnly属性表示是否可以通过选中行进行选取,还是必须选中复选框选取; 18 var grid = new Ext.grid.GridPanel({ 19 ..., 20 selModel:sm 21 //selModel在总体上控制用户对表格的选择功能; 22 })
1 3.7 选择模型 2 >1.RowModel(行选择模型) 3 //在定义Ext.grid.GridPanel时,默认使用RowModel--行选择模型; 4 var grid = new Ext.grid.GridPanel({ 5 ..., 6 sm:new Ext.grid.RowModel({singleSelect:true}) //设置只能选中一行; 7 }) 8 >2.CellModel(单元格选择模型) 9 //在EditorGrid里默认使用CellModel; 10 >3.选中行信息显示 11 grid.on('itemclick',function(){ 12 //表格绑定单机事件; 13 var selected = grid.getSelectionModel().selected; //gSM():返回正在使用的选择模型 selected:所有当前已选择的记录的混合集合 14 for(var i=0; i<selected.getCount(); i++){ 15 var record = selected.get(i); 16 Ext.Msg.alert('提示',record.get("id")+","+record.get("name")+","+record.get("descn")); 17 } 18 })
1 3.8 表格视图--Ext.grid.GridView 2 //表格控件都遵循MVC模型 3 //Ext.data.Store:可看做模型(Model); 4 //Ext.grid.GridPanel:设置的各种监听器可看做控制器(Controller); 5 //Ext.grid.GridView:对应的就是视图(View); 6 //通常情况下不需要自行创建Ext.grid.GridView的实例,Ext.grid.GridPanel会自动生成对应的实例,使用默认的样式将表格显示到页面上; 7 //若希望操作Ext.grid.GridView的属性时,可以通过Ext.grid.GridPanel的getView()函数来获取当前表格使用的视图实例; 8 //与GridView相关的操作都集中在视图的显示功能部分;grid.getView()必须在创建Ext.grid.GridPanel之后调用,它只能获得Ext.grid.GridPanel中创建好的GridView实例; 9 //可以使用Ext.grid.GridPanel的viewConfig参数,在创建GridView时设置一些初始参数; 10 var grid = new Ext.grid.GridPanel({ //控制器Controller; 11 store:new Ext.data.ArrayStore({ //模型Model; 12 data:data, 13 fields:meta, 14 autoLoad:true 15 }), 16 columns:meta, 17 renderTo:'grid', //GridPanel自动创建对应的实例,即视图View; 18 width:450, 19 height:80, 20 viewConfig:{ //为创建的GridView设置初始参数; 21 columnsText:'显示的列', //中文显示; 22 scrollOffset:30, //滚动条的宽度,默认是20px; 23 sortAscText:'升序', 24 sortDescText:'降序', 25 forceFit:true //自适应列宽; 26 } 27 });
1 3.9 表格分页 2 3.9.1 为表格添加分页工具条 3 var grid = new Ext.grid.GridPanel({ 4 renderTo:'grid', 5 autoHeight:true, 6 store:store, 7 columns:columns, 8 bbar:new Ext.PagingToolvar({ 9 pageSize:10, //每页显示几条数据; 10 store:store, 11 displayInfo:true, //是否显示数据信息; 12 displayMsg:'显示第{0}条到{1}条记录,一共{2}条', 13 //用来显示有数据时的提示信息; 14 emptyMsg:'没有记录' //没有记录时显示的信息; 15 }) 16 }); 17 store.load(); //必须在构造表格以后执行,否则分页工具条将不起作用; 18 //将分页工具条和store相关联,从而实现与表格共享数据模型; 19 20 3.9.2 通过后台脚本获得分页数据 21 var columns = [{header:'编号',dataIndex:'id'}] 22 23 var store = new Ext.data.Store({ 24 //Store:仓库/存储;它封装了一个客户端缓存,用于存储Model对象;Store通过一个代理Proxy来加载数据,并提供函数来排序/过滤以及查询内部所包含的model实例; 25 //而Ext.data.ArrayStore是一个小巧的帮助类,更方便的从一个数组的数据来创建Ext.data.Store; 26 proxy:{ //换掉proxy,不再到内存中查找,而是通过HTTP获得想要的数据; 27 type:'ajax', //表示使用Ajax向后台请求数据; 28 url:'xxx.jsp', //请求地址; 29 reader:{ //不再是解析简单的数组,而是后台传过来的JsonReader, 30 type:'json', //所以reader设置type为json; 31 totalProperty:'totalProperty',//对应JSP中的代码,数据的总数; 32 root:'root', //JSP中的数据数组; 33 idProperty:'id' 34 } 35 }, 36 fields:[ 37 {name:'id'}, 38 {name:'name'}, 39 {name:'descn'} 40 ] 41 }); 42 43 var grid = new Ext.grid.GridPanel({...(分页代码)}); 44 store.load({params:{start:0,limit:10}}); //在初始化时通过传递对应的分页参数去获取希望得到的数据; 45 46 3.9.3 分页工具条在表格顶部 47 var grid = new Ext.grid.GridPanel({ 48 ... 49 tbar:new Ext.PagingToolvar({...}) //tbar:顶部工具条;bbar:底部工具条; 50 }); 51 52 3.9.4 Ext前台分页 53 //需要引用PagingMemoryProxy.js,从本地数组读取数据,实现内存分页;
1 3.10 后台排序 2 //把排序信息提交到后台,由后台排序信息组装到SQL里;然后再由后台将处理好的数据返回给前台; 3 var store = new Ext.data.Store({ 4 proxy:{...}, 5 fields:[...], 6 remoteSort:true //是否允许远程排序,默认值是false; 7 //向后台提交两个参数:sort(要排序的字段)和dir(升序或降序); 8 });
1 3.11 多重排序 2 //对"Rating"和"Salary"两列进行排序; 3 store.sort([{ 4 property:'rating', 5 direction:'DESC' 6 },{ 7 property:'salary', 8 direction:'ASC' 9 }]);
1 3.12 可编辑表格控件--EditorGrid 2 3.12.1 制作一个EditorGrid; 3 var columns = [{header:'编号',dataIndex:'id', 4 editor:{allowBlank:false}}] //表格不能为空; 5 //为每列添加了TextField插件; 6 7 var grid = new Ext.grid.GridPanel({ 8 columns:columns, 9 store:store, 10 selType:'cellmodel', //设置选择模型为单元格模型;默认是:rowmodel;行模型; 11 plugins:[ 12 Ext.create('Ext.grid.plugin.CellEditing',{ //启用CellEditing插件; 13 clidksToEdit:1 //设置单击激活编辑器; 默认双击; 14 }) 15 ] 16 }); 17 18 3.12.2 添加一行数据 19 var grid = new Ext.grid.GridPanel({ 20 autoHeight:true, 21 renderTo:'grid', 22 store:store, 23 columns:columns, 24 selType:'cellmodel', 25 plugins:[ 26 Ext.create('Ext.grid.plugin.CellEditing',{ 27 clicksToEdit:1 28 }) 29 ], 30 tbar:['-',{ //创建顶部工具条; '-':在页面显示'|'; 31 text:'添加一行', //按钮显示值; 32 handler:function(){ //定义按钮按下时执行的函数; 33 var p = { 34 id:'',name:'',descn:''//新添加的行对应的列属性; 35 }; 36 store.insert(0,p); //在第一行的上面添加一个新行; 37 } 38 },'-',{ 39 text:'删除一行', 40 handler:function(){ 41 Ext.Msg.confirm('信息','确定要删除?',function(btn){ 42 //弹出确认窗口; 43 if(btn == 'yes'){ //用户选中"yes"; 44 var sm = grid.getSelectionModel(); //定位选中单元格对象; 45 var record = sm.getSelection()[0]; //单元格对应的行模型; 46 store.remove(record); //删除对应行; 47 } 48 }) 49 }; 50 },'-'] 51 }); 52 53 3.12.3 保存修改结果 54 接上..,'=',{ 55 text:'保存', //添加保存按钮; 56 handler:function(){ 57 var m = store.getModifiedRecrods().slice(0); 58 //从Store(数据存储对象)获得所有record(表格行对象); 59 var jsonArray = []; 60 Ext.each(m,function(item){ 61 //遍历m数组,并对其中每个元素调用fn函数; 62 jsonArray.push(item.data); 63 }); 64 65 Ext.Ajax.request({ 66 method:'POST', 67 url:'xxx.jsp', 68 success:function(response){ 69 Ext.Msg.alert("信息",response.responseText,function(){ 70 store.reload(); 71 }) 72 }, 73 failure:function(){ 74 Ext.Msg.alert("错误","与后台连接出现问题"); 75 }, 76 params:'data='+encodeURIComponent(Ext.encode(jsonArray)) 77 }); 78 } 79 } 80 81 3.12.4 限制输入数据的类型 82 var comboData = [ 83 [0,'新版ext教程'], 84 [1,'ext在线支持'], 85 [2,'ext扩展'] 86 ]; 87 //数据部分单独抽离出来,为了在editor和renderer里保持数据同步; 88 var columns = [{ 89 header:'数字列', 90 dataIndex:'number', 91 editor:new Ext.form.NumberField({ 92 allowBlank:false, //不为空; 93 allowNegative:false, //不为负数; 94 maxValue:10 //最长10位; 95 }) 96 },{ 97 header:'选择列', 98 dataIndex:'combo', 99 editor:new Ext.form.ComboBox({ 100 //传统的<input>和<select>域的综合;用户可以自由的在域中键入; 101 store:new Ext.data.SimpleStore({ 102 fields:['value','text'], //绑定模型的字段; 103 data:comboData //读写数据comboData; 104 }), 105 emptyText:'请选择', 106 mode:'local', 107 triggerAction:'all', //触发器被点击时的操作; 108 valueField:'value', //相关的数据值绑定到ComboBox; 109 displayField:'text', 110 editable:false //只读模式; 111 }), 112 renderer:function(value){ //渲染函数; 113 return comboData[value][1];//返回comboData数组里的text值; 114 } 115 },{ 116 header:'日期列', 117 dataIndex:'data', 118 editor:new Ext.form.DateField({ 119 //提供一个带有日期选择器(picker)下拉框并会自动进行日期验证的日期输入表单项; 120 format:'Y-m-d', //日期格式; 121 minValue:'2007-12-14', //日期最小值; 122 disabledDays:[0,6], //禁止选择的日期; 123 disabledDaysText:'只能选择工作日' 124 }), 125 renderer:function(value){ 126 return Ext.Date.format(value,'Y-m-d'); 127 //返回格式化的日期字符串; 128 } 129 },{ 130 header:'判断列', 131 dataIndex:'check', 132 editor:new Ext.form.Checkbox({ 133 allowBlank:false 134 }), 135 renderer:function(value){ 136 return value ? '是' : '否'; 137 } 138 }];
1 3.13 表格属性控件--PropertyGrid 2 3.13.1 简介 3 //PropertyGrid(属性表格)扩展自EditGrid,可以直接编辑右边的内容; 4 var grid = new Ext.grid.PropertyGrid({ 5 title:'属性表格', //表格标题; 6 autoHeight:true, //自适应高度; 7 width:300, 8 renderTo:'grid', 9 viewConfig:{ //初始化设置表格属性; 10 forceFit:true //表格列自适应; 11 }, 12 source:{ //JSON数据,指定了表格里的key和value; 13 "名字":"不说", //string对应TextField编辑器; 14 "创建时间":new Date(Date.parse('12/15/2014')), //date对应DateField编辑器; 15 "是否有效":false, //bool对应ComboBox编辑器(下拉列表); 16 "版本号":.02, //number对应NumberField编辑器; 17 } 18 }); 19 20 3.13.2 只读表格 21 //PropertyGrid没有直接关闭编辑功能的属性;可以通过Ext的事件监听器实现; 22 grid.on("beforeedit",function(e){ 23 e.cancel = true; 24 return false; 25 });
1 3.14 分组表格控件--GroupingGrid 2 var meta = [ 3 {header:'index',dataIndex:'id',name:'id'} 4 {header:'sex',dataIndex:'sex',name:'sex'} 5 {header:'name',dataIndex:'name',name:'name'} 6 {header:'descn',dataIndex:'descn',name:'descn'} 7 ] 8 var data = [ 9 ['1','male','name1','descn1'] 10 ['2','female','neme2','descn2'] 11 ] 12 var grid = new Ext.grid.GridPanel({ 13 store:new Ext.data.ArrayStore({ //数据存储器; 14 fields:meta, 15 data:data, 16 groupField:'sex', //需要分组的域;分组行; 17 sortInfo:{field:'id',direction:'ASC'} //排序列; 18 }), 19 columns:meat, 20 features:[{ftype:'grouping'}], //分组设置;!!! 21 renderTo:'grid', 22 autoHeight:true 23 }); 24 25 Ext.get('expand').on('click',function(){ 26 grid.view.features[0].expandAll(); //展开所有分组; 27 }); 28 Ext.get('collapse').on('click',function(){ 29 grid.view.features[0].collapseAll();//折叠所有分组; 30 }); 31 Ext.get('one').on('click',function(){ //先判断再操作; 32 var feature = grid.view.features[0];//获得feature的实例; 33 if(feature.isExpanded('female')){ 34 feature.expand('female'); 35 feature.collapse('female'); 36 }else{ 37 feature.collapse('female'); 38 feature.expand('female'); 39 } 40 });
1 3.15 可拖拽的表格 2 3.15.1 拖放改变表格的大小 3 var rz = new Ext.Resizable(grid.getE1(),{ //放在render之后; 4 wrap:true, //在构造Resizable()函数时,自动在指定id的外边包裹一层div 5 minHeight:100, 6 pinned:true, //可拖拽提示,一直显示在表格下边; 7 handles:'s' //下边可拖拽; 8 }); 9 rz.on('resize',function(resizer,width,height,event){ 10 grid.setHeight(height); 11 //在拖拽完成之后,调用setHeight()方法修改自己的大小; 12 }) 13 14 3.15.2 在同一个表格里拖放 15 var grid = new Ext.grid.GridPanel({ 16 renderTo:'grid',store:store,coluns:columns, 17 viewConfig:{ 18 plugins:{ //提供了插件的注册表,通过ptype助记码来编入索引; 19 ptype:'gridviewdragdrop' 20 } 21 } 22 }); 23 24 3.15.3 表格之间的拖放 25 //两个表格都设置了gridviewdragdrop插件,即可互相拖放; 26 var grid1 = new Ext.grid.GridPanel({ 27 .. 28 viewConfig:{ 29 plugins:{ptype:'gridviewdragdrop'} 30 } 31 }); 32 var grid2 = new Ext.grid.GridPanel({ 33 .. 34 viewConfig:{ 35 plugins:{ptype:'gridviewdragdrop'} 36 } 37 });
1 3.16 表格与右键菜单 2 var contextmenu = new Ext.menu.Menu({ 3 id:'theContextMenu', 4 items:[{ 5 text:'查看详情', 6 handler:function(){..}//右键函数; 7 }] 8 }); 9 grid.on('itemcontextmeun',function(view,record,item,index,e){ 10 e.preventDefault(); //e:事件对象; 禁止浏览器默认右键菜单; 11 contextmenu.showAt(e.getXY()); //显示自定义右键菜单; 12 });
1 3.17 基于表格的扩展插件 2 3.17.1 行编辑器 3 columns:[{ 4 header:'Email', 5 dataIndex:'email', 6 width:160, 7 editor:{ 8 xtype:'textfield', //替代全类型创建对象; 9 allowBlank:false, 10 vtype:'email' 11 } 12 }] 13 plugins:[rowEditing], //行编辑器控件; 14 15 3.17.2 进度条分页组件 16 3.17.3 缓冲式表格视图 17 3.17.4 分组表头 18 var grid = Ext.create('Ext.grid.Panel',{ 19 columnLines:true, 20 columns:[{ 21 text:'Company', 22 flex:1, 23 sortable:false, 24 dataIndex:'company' 25 },{ 26 text:'Stock Price', 27 columns:[{ 28 text:'Price', 29 renderer:'usMoney', 30 dataIndex:'price' 31 },{ 32 text:'Change', 33 renderer:change, 34 dataIndex:'change' 35 }] 36 }] 37 }); 38 3.17.5 锁定列