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重要知识更新
Jul 08 Javascript
AJAX异步从优酷专辑中采集所有视频及信息(JavaScript代码)
Nov 20 Javascript
javascript中typeof的使用示例
Dec 19 Javascript
jquery操作下拉列表、文本框、复选框、单选框集合(收藏)
Jan 08 Javascript
技术男用来对妹子表白的百度首页
Jul 23 Javascript
JavaScript实现继承的4种方法总结
Oct 16 Javascript
JavaScript实现在标题栏上显示当前日期的方法
Mar 19 Javascript
javascript省市区三级联动下拉框菜单实例演示
Nov 29 Javascript
原生js编写autoComplete插件
Apr 13 Javascript
angular5 httpclient的示例实战
Mar 12 Javascript
从0搭建vue-cli4脚手架
Jun 17 Javascript
vue使用echarts实现折线图
Mar 21 Vue.js
基于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
PHP 中dirname(_file_)讲解
2007/03/18 PHP
php二分查找二种实现示例
2014/03/12 PHP
CodeIgniter中使用Smarty3基本配置
2015/06/29 PHP
laravel 修改记住我功能的cookie保存时间的方法
2019/10/14 PHP
jscript之Read an Excel Spreadsheet
2007/06/13 Javascript
JS保存和删除cookie操作 判断cookie是否存在
2013/11/13 Javascript
浅析JavaScript 调试方法和技巧
2015/10/22 Javascript
jQuery实现多级联动下拉列表查询框
2016/01/18 Javascript
AngularJS基础 ng-mouseleave 指令详解
2016/08/02 Javascript
浅谈js中test()函数在正则中的使用
2016/08/19 Javascript
JS焦点图,JS 多个页面放多个焦点图的实例
2016/12/08 Javascript
关于不同页面之间实现参数传递的几种方式讨论
2017/02/13 Javascript
jQuery实现带右侧索引功能的通讯录示例【附源码下载】
2018/04/17 jQuery
爬虫利器Puppeteer实战
2019/01/09 Javascript
详解VS Code使用之Vue工程配置format代码格式化
2019/03/20 Javascript
基于Vue实现电商SKU组合算法问题
2019/05/29 Javascript
vue-cli在 history模式下的配置详解
2019/11/26 Javascript
[02:19]DOTA选手解说齐贺岁
2018/02/11 DOTA
[01:27:30]LGD vs Newbee 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/19 DOTA
python批量修改文件名的实现代码
2014/09/01 Python
简单的抓取淘宝图片的Python爬虫
2014/12/25 Python
Python bsddb模块操作Berkeley DB数据库介绍
2015/04/08 Python
Python实现两个list对应元素相减操作示例
2017/06/09 Python
Python贪心算法实例小结
2018/04/22 Python
python retrying模块的使用方法详解
2019/09/25 Python
python实现高斯(Gauss)迭代法的例子
2019/11/20 Python
python通过文本在一个图中画多条线的实例
2020/02/21 Python
Python爬取豆瓣数据实现过程解析
2020/10/27 Python
selenium判断元素是否存在的两种方法小结
2020/12/07 Python
英国品牌男装折扣网站:Brown Bag
2018/03/08 全球购物
美国最值得信赖的宠物药房:Allivet
2019/03/23 全球购物
食堂标语大全
2014/06/11 职场文书
化工实习心得体会
2014/09/09 职场文书
群众路线个人剖析材料及整改措施
2014/11/04 职场文书
2014年教师学期工作总结
2014/11/08 职场文书
2014年审计人员工作总结
2014/12/19 职场文书