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


Posted in Javascript onMay 21, 2016

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中实现嵌套表格
先看效果:

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

代码如下:

<!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事件中添加嵌套表格.

Javascript 相关文章推荐
用JavaScript事件串连执行多个处理过程的方法
Mar 09 Javascript
JS 跳转页面延迟2种方法
Mar 29 Javascript
浅析jQuery1.8的几个小变化
Dec 10 Javascript
扩展IE中一些不兼容的方法如contains、startWith等等
Jan 09 Javascript
javascript使用正则表达式检测IP地址
Dec 03 Javascript
JavaScript必看小技巧(必看)
Jun 07 Javascript
Bootstrap模态框(Modal)实现过渡效果
Mar 17 Javascript
jquery中$.fn和图片滚动效果实现的必备知识总结
Apr 21 jQuery
5分钟打造简易高效的webpack常用配置
Jul 04 Javascript
node.js实现微信JS-API封装接口的示例代码
Sep 06 Javascript
JS实现自定义弹窗功能
Aug 08 Javascript
jQuery实现获取及设置CSS样式操作详解
Sep 05 jQuery
基于HTML5上使用iScroll实现下拉刷新,上拉加载更多
May 21 #Javascript
jQuery插件pagination实现无刷新分页
May 21 #Javascript
JavaScript中对JSON对象的基本操作示例
May 21 #Javascript
iscroll碰到Select无法选择下拉刷新的解决办法
May 21 #Javascript
jQuery EasyUI Pagination实现分页的常用方法
May 21 #Javascript
总结JavaScript设计模式编程中的享元模式使用
May 21 #Javascript
在JavaScript中模拟类(class)及类的继承关系
May 20 #Javascript
You might like
mysql时区问题
2008/03/26 PHP
Ext.data.PagingMemoryProxy分页一次性读取数据的实现代码
2010/04/07 PHP
表格展示无限级分类(PHP版)
2012/08/21 PHP
基于PHP文件操作的详细诠释
2013/06/21 PHP
使用PHP强制下载PDF文件示例
2014/01/17 PHP
PHP管理依赖(dependency)关系工具 Composer 安装与使用
2014/08/18 PHP
Symfony2框架学习笔记之表单用法详解
2016/03/18 PHP
PHP发送AT指令实例代码
2016/05/26 PHP
Colortip基于jquery的信息提示框插件在IE6下面的显示问题修正方法
2010/12/06 Javascript
JS中setInterval、setTimeout不能传递带参数的函数的解决方案
2013/04/28 Javascript
完美兼容各大浏览器获取HTTP_REFERER方法总结
2014/06/24 Javascript
jQuery获取单击节点对象的方法
2016/06/02 Javascript
Bootstrap基本模板的使用和理解1
2016/12/14 Javascript
Nodejs实现多房间简易聊天室功能
2017/06/20 NodeJs
利用canvas实现的加载动画效果实例代码
2017/07/05 Javascript
基于AngularJS实现表单验证功能
2017/07/28 Javascript
VS Code转换大小写、修改选中文字或代码颜色的方法
2017/12/15 Javascript
基于openlayers4实现点的扩散效果
2020/08/17 Javascript
浅谈vue项目4rs vue-router上线后history模式遇到的坑
2018/09/27 Javascript
详解webpack之图片引入-增强的file-loader:url-loader
2018/10/08 Javascript
react用Redux中央仓库实现一个todolist
2019/09/29 Javascript
解决node.js含有%百分号时发送get请求时浏览器地址自动编码的问题
2019/11/20 Javascript
Python Learning 列表的更多操作及示例代码
2018/08/22 Python
python3 实现对图片进行局部切割的方法
2018/12/05 Python
Django中文件上传和文件访问微项目的方法
2020/04/27 Python
解决windows上安装tensorflow时报错,“DLL load failed: 找不到指定的模块”的问题
2020/05/20 Python
Python之字典添加元素的几种方法
2020/09/30 Python
CSS3 Flexbox中flex-shrink属性的用法示例介绍
2013/12/30 HTML / CSS
Hotels.com印度:酒店预订
2019/05/11 全球购物
班组安全员工作职责
2014/02/01 职场文书
我与祖国共奋进演讲稿
2014/09/13 职场文书
求职自我评价范文
2015/03/09 职场文书
2015年学校德育工作总结
2015/04/22 职场文书
高中语文教学反思范文
2016/02/16 职场文书
Innodb存储引擎中的后台线程详解
2022/04/03 MySQL
Flink 侧流输出源码示例解析
2022/09/23 Servers