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 getElementsByClassName实现代码
Oct 11 Javascript
JQuery实现展开关闭层的方法
Feb 17 Javascript
JavaScript动态提示输入框输入字数的方法
Jul 27 Javascript
JavaScript中removeChild 方法开发示例代码
Aug 15 Javascript
详解webpack es6 to es5支持配置
May 04 Javascript
Node.js如何实现注册邮箱激活功能 (常见)
Jul 23 Javascript
Vue源码学习之初始化模块init.js解析
Nov 02 Javascript
详解ES6中的三种异步解决方案
Jun 28 Javascript
vue实现点击选中,其他的不选中方法
Sep 05 Javascript
element el-input directive数字进行控制
Oct 11 Javascript
详解Vue组件之作用域插槽
Nov 22 Javascript
vue npm install 安装某个指定的版本操作
Aug 11 Javascript
基于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
造势之举?韩国总统候选人发布《星际争霸》地图
2017/04/22 星际争霸
《忧国的莫里亚蒂》先导宣传图与STAFF公开
2020/03/04 日漫
PHP结合Jquery和ajax实现瀑布流特效
2016/01/07 PHP
Discuz论坛密码与密保加密规则
2016/12/19 PHP
Zend Framework框架中实现Ajax的方法示例
2017/06/27 PHP
PHP使用curl_multi_select解决curl_multi网页假死问题的方法
2018/08/15 PHP
jquery限制输入字数,并提示剩余字数实现代码
2012/12/24 Javascript
js漂浮广告实现代码
2015/08/15 Javascript
jQuery中on绑定事件后引发的事件冒泡问题如何解决
2016/05/25 Javascript
JavaScript实现移动端滑动选择日期功能
2016/06/21 Javascript
angularjs 源码解析之scope
2016/08/22 Javascript
angularjs 的数据绑定实现原理
2018/07/02 Javascript
JS学习笔记之数组去重实现方法小结
2019/05/29 Javascript
微信小程序实现弹出菜单动画
2019/06/21 Javascript
深入浅析Vue中mixin和extend的区别和使用场景
2019/08/01 Javascript
[18:16]sakonoko 2017年卡尔集锦
2018/02/06 DOTA
[01:15:00]LGD vs Mineski Supermajor 胜者组 BO3 第一场 6.5
2018/06/06 DOTA
[01:52]PWL S2开团时刻第四期——DOTA2成语故事
2020/12/03 DOTA
python 实现堆排序算法代码
2012/06/05 Python
Python使用BeautifulSoup库解析HTML基本使用教程
2016/03/31 Python
python多个模块py文件的数据共享实例
2019/01/11 Python
django rest framework serializer返回时间自动格式化方法
2020/03/31 Python
Python实现从N个数中找到最大的K个数
2020/04/02 Python
HTML5 canvas基本绘图之绘制五角星
2016/06/27 HTML / CSS
Waterford加拿大官方网站:世界著名的水晶杯品牌
2016/11/01 全球购物
乐高奥地利官方商店:LEGO Shop AT
2019/07/16 全球购物
Audible英国:有声读物,30天免费试用
2019/10/16 全球购物
俄罗斯在线服装店:STOLNIK
2021/03/07 全球购物
blueseventy官网:铁人三项和比赛泳衣
2021/02/06 全球购物
《藤野先生》教学反思
2014/02/19 职场文书
行政部工作岗位职责范本
2014/03/05 职场文书
酒店开业庆典主持词
2014/03/21 职场文书
《我的伯父鲁迅先生》教学反思
2016/02/16 职场文书
初中运动会闭幕词范本3篇
2019/12/09 职场文书
Windows10下安装MySQL8
2021/04/06 MySQL
使用php的mail()函数实现发送邮件功能
2021/06/03 PHP