鸣谢:http://www.shuyangyang.com.cn/jishuliangongfang/qianduanjishu/2013-11-27/185.html
-------------------------------------------------------------------------------------------
以下是完整代码:
/** * Grid * 此js演示了ExtJS之树形表格 * 注意:在加载附件时要注意路径。如加载TreeStore——'treegrid-data.json',icon: '../js/component/images/edit.png' */ //引入扩展组件 Ext.Loader.setConfig({enabled: true}); Ext.Loader.setPath('Ext.ux', '../ext-4.2.1/ux/'); Ext.require([ 'Ext.data.*', 'Ext.grid.*', 'Ext.tree.*', 'Ext.ux.CheckColumn' ]); Ext.onReady(function(){ Ext.QuickTips.init();//初始化一个单例。 任何一个基本标签的快速提示框将开始工作。 //we want to setup a model and store instead of using dataUrl Ext.define('Task', { extend: 'Ext.data.Model', fields: [ {name: 'task', type: 'string'}, {name: 'user', type: 'string'}, {name: 'duration', type: 'string'} ] }); var store = Ext.create('Ext.data.TreeStore', { model: 'Task', proxy: {//通过代理加载对象 type: 'ajax', //the store will get the content from the .json file url: 'treegrid-data.json'//在加载js时,Extjs找的路径是http://localhost:8081/extjsTest1/component(引用此js的jsp所在目录) }, folderSort: true }); //Ext.ux.tree.TreeGrid在UX扩展中也有,但不常用,您可以简单地使用一个tree.TreePanel var tree = Ext.create('Ext.tree.Panel', { title: 'Core Team Projects', 500, height: 300, renderTo: 'treegrid', collapsible: true,//设置为true是panel具有可折叠功能并且有一个展开/折叠的切换按钮被添加到panel的标题头区域。 useArrows: true,//true,在tree中使用Vista-style样式的箭头。 rootVisible: false,//false,隐藏根节点。 store: store, multiSelect: true, singleExpand: true, //the 'columns' property is now 'headers' columns: [{ xtype: 'treecolumn', //this is so we know which column will show the tree text: 'Task', flex: 2, sortable: true, dataIndex: 'task' },{ //we must use the templateheader component so we can use a custom tpl xtype: 'templatecolumn', text: 'Duration', flex: 1, sortable: true, dataIndex: 'duration', align: 'center', //add in the custom tpl for the rows //tpl:XTemplate实例,或XTemplate的配置对象, 用于把Model's data转换为要显示的值。 tpl: Ext.create('Ext.XTemplate', '{duration:this.formatHours}', { formatHours: function(v) { if (v < 1) {//0.12 return Math.round(v * 60) + ' mins'; } else if (Math.floor(v) !== v) {//1.2 var min = v - Math.floor(v); return Math.floor(v) + 'h ' + Math.round(min * 60) + 'm'; } else { return v + ' hour' + (v === 1 ? '' : 's'); } } }) },{ text: 'Assigned To', flex: 1, dataIndex: 'user', sortable: true }, { xtype: 'checkcolumn', // header: 'Done', text:'Done', dataIndex: 'done', 40, stopSelection: false//在鼠标单击时选择表格(所点击行) }, { text: 'Edit', 40, menuDisabled: true, xtype: 'actioncolumn', tooltip: 'Edit task',//鼠标悬浮时的提示消息。 需要先初始化Ext.tip.QuickTipManager。 align: 'center', icon: '../js/component/images/edit.png',//http://localhost:8081/extjsTest1/js/component/images/edit.png handler: function(grid, rowIndex, colIndex, actionItem, event, record, row) { Ext.Msg.alert('Editing' + (record.get('done') ? ' completed task' : '') , record.get('task')); } }] }); });
在列定义中有xtype: 'treecolumn',这是告诉列要以树形列来显示,在以后的表单或其他容器中也会以这样的方式来显示,有panelcolumn等,这里等以后讲到再说。
再看下JSON数据格式,后台只要符合这种形式,EXTJS就会给你自动解析出来:
//Ext.data.NodeInterface {"text":".","children": [ { task:'Project: Shopping', duration:13.25, user:'Tommy Maintz', iconCls:'task-folder',//应用于本节点的图标的CSS类。 expanded: true,//True如果节点是展开的。 children:[{ task:'Housewares', duration:1.25, user:'Tommy Maintz', iconCls:'task-folder', children:[{ task:'Kitchen supplies', duration:0.25, user:'Tommy Maintz', leaf:true, iconCls:'task' },{ task:'Groceries', duration:.4, user:'Tommy Maintz', leaf:true, iconCls:'task', done: true },{ task:'Cleaning supplies', duration:.4, user:'Tommy Maintz', leaf:true, iconCls:'task' },{ task: 'Office supplies', duration: .2, user: 'Tommy Maintz', leaf: true, iconCls: 'task' }] }, { task:'Remodeling', duration:12, user:'Tommy Maintz', iconCls:'task-folder', expanded: true, children:[{ task:'Retile kitchen', duration:6.5, user:'Tommy Maintz', leaf:true, iconCls:'task' },{ task:'Paint bedroom', duration: 2.75, user:'Tommy Maintz', iconCls:'task-folder', children: [{ task: 'Ceiling', duration: 1.25, user: 'Tommy Maintz', iconCls: 'task', leaf: true }, { task: 'Walls', duration: 1.5, user: 'Tommy Maintz', iconCls: 'task', leaf: true }] },{ task:'Decorate living room', duration:2.75, user:'Tommy Maintz', leaf:true, iconCls:'task', done: true },{ task: 'Fix lights', duration: .75, user: 'Tommy Maintz', leaf: true, iconCls: 'task', done: true }, { task: 'Reattach screen door', duration: 2, user: 'Tommy Maintz', leaf: true, iconCls: 'task' }] }] },{ task:'Project: Testing', duration:2, user:'Core Team', iconCls:'task-folder', children:[{ task: 'Mac OSX', duration: 0.75, user: 'Tommy Maintz', iconCls: 'task-folder', children: [{ task: 'FireFox', duration: 0.25, user: 'Tommy Maintz', iconCls: 'task', leaf: true }, { task: 'Safari', duration: 0.25, user: 'Tommy Maintz', iconCls: 'task', leaf: true }, { task: 'Chrome', duration: 0.25, user: 'Tommy Maintz', iconCls: 'task', leaf: true }] },{ task: 'Windows', duration: 3.75, user: 'Darrell Meyer', iconCls: 'task-folder', children: [{ task: 'FireFox', duration: 0.25, user: 'Darrell Meyer', iconCls: 'task', leaf: true }, { task: 'Safari', duration: 0.25, user: 'Darrell Meyer', iconCls: 'task', leaf: true }, { task: 'Chrome', duration: 0.25, user: 'Darrell Meyer', iconCls: 'task', leaf: true },{ task: 'Internet Exploder', duration: 3, user: 'Darrell Meyer', iconCls: 'task', leaf: true }] },{ task: 'Linux', duration: 0.5, user: 'Aaron Conran', iconCls: 'task-folder', children: [{ task: 'FireFox', duration: 0.25, user: 'Aaron Conran', iconCls: 'task', leaf: true }, { task: 'Chrome', duration: 0.25, user: 'Aaron Conran', iconCls: 'task', leaf: true }] }] } ]}
这里还有一个扩展功能,如下:
表头点击箭头就会出现过滤组件,便于筛选数据,每列都有,是不是很丰富啊。
下面看代码:
/** * Grid * 此js演示了ExtJS之树形表格,并且表头的ID列带有过滤组件,用来显示指定的行或某个区间的行信息。 * */ //引入扩展组件 Ext.Loader.setConfig({enabled: true}); Ext.Loader.setPath('Ext.ux', '../ext-4.2.1/ux/'); Ext.require([ 'Ext.grid.*', 'Ext.data.*', 'Ext.ux.grid.FiltersFeature', 'Ext.toolbar.Paging', 'Ext.ux.ajax.JsonSimlet', 'Ext.ux.ajax.SimManager' ]); Ext.define('Product', { extend: 'Ext.data.Model', fields: [{ name: 'id', type: 'int' }, { name: 'company' }, { name: 'price', type: 'float' }, { name: 'date', type: 'date', dateFormat: 'Y-m-d' }, { name: 'visible', type: 'boolean' }, { name: 'size' }] }); Ext.onReady(function(){ Ext.ux.ajax.SimManager.init({ delay: 300, defaultSimlet: null }).register({ 'myData': { data: [ ['small', 'small'], ['medium', 'medium'], ['large', 'large'], ['extra large', 'extra large'] ], stype: 'json' } }); var optionsStore = Ext.create('Ext.data.Store', { fields: ['id', 'text'], proxy: { type: 'ajax', url: 'myData', reader: 'array' } }); Ext.QuickTips.init(); // for this demo configure local and remote urls for demo purposes var url = { local: 'grid-filter.json', // static data file remote: 'grid-filter.php' }; // configure whether filter query is encoded or not (initially) var encode = false; // configure whether filtering is performed locally or remotely (initially) var local = true; var store = Ext.create('Ext.data.JsonStore', { // store configs autoDestroy: true, model: 'Product', proxy: { type: 'ajax', url: (local ? url.local : url.remote), reader: { type: 'json', root: 'data', idProperty: 'id', totalProperty: 'total' } }, remoteSort: false, sorters: [{ property: 'company', direction: 'ASC' }], pageSize: 50 }); var filters = { ftype: 'filters', // encode and local configuration options defined previously for easier reuse encode: encode, // json encode the filter query local: local, // defaults to false (remote filtering) // Filters are most naturally placed in the column definition, but can also be // added here. filters: [{ type: 'boolean', dataIndex: 'visible' }] }; // use a factory method to reduce code while demonstrating // that the GridFilter plugin may be configured with or without // the filter types (the filters may be specified on the column model var createColumns = function (finish, start) { var columns = [{ dataIndex: 'id', text: 'Id', // instead of specifying filter config just specify filterable=true // to use store's field's type property (if type property not // explicitly specified in store config it will be 'auto' which // GridFilters will assume to be 'StringFilter' filterable: true, 30 //,filter: {type: 'numeric'} }, { dataIndex: 'company', text: 'Company', id: 'company', flex: 1, filter: { type: 'string' // specify disabled to disable the filter menu //, disabled: true } }, { dataIndex: 'price', text: 'Price', filter: { //type: 'numeric' // specify type here or in store fields config }, 70 }, { dataIndex: 'size', text: 'Size', filter: { type: 'list', store: optionsStore //,phpMode: true } }, { dataIndex: 'date', text: 'Date', filter: true, renderer: Ext.util.Format.dateRenderer('m/d/Y') }, { dataIndex: 'visible', text: 'Visible' // this column's filter is defined in the filters feature config }]; return columns.slice(start || 0, finish); }; var grid = Ext.create('Ext.grid.Panel', { border: false, store: store, columns: createColumns(4), loadMask: true, features: [filters], dockedItems: [Ext.create('Ext.toolbar.Paging', { dock: 'bottom', store: store })], emptyText: 'No Matching Records' }); // add some buttons to bottom toolbar just for demonstration purposes grid.child('pagingtoolbar').add([ '->', { text: 'Encode: ' + (encode ? 'On' : 'Off'), tooltip: 'Toggle Filter encoding on/off', enableToggle: true, handler: function (button, state) { var encode = (grid.filters.encode !== true); var text = 'Encode: ' + (encode ? 'On' : 'Off'); grid.filters.encode = encode; grid.filters.reload(); button.setText(text); } }, { text: 'Local Filtering: ' + (local ? 'On' : 'Off'), tooltip: 'Toggle Filtering between remote/local', enableToggle: true, handler: function (button, state) { var local = (grid.filters.local !== true), text = 'Local Filtering: ' + (local ? 'On' : 'Off'), newUrl = local ? url.local : url.remote, store = grid.view.getStore(); // update the GridFilter setting grid.filters.local = local; // bind the store again so GridFilters is listening to appropriate store event grid.filters.bindStore(store); // update the url for the proxy store.proxy.url = newUrl; button.setText(text); store.load(); } }, { text: 'All Filter Data', tooltip: 'Get Filter Data for Grid', handler: function () { var data = Ext.encode(grid.filters.getFilterData()); Ext.Msg.alert('All Filter Data',data); } },{ text: 'Clear Filter Data', handler: function () { grid.filters.clearFilters(); } },{ text: 'Add Columns', handler: function () { if (grid.headerCt.items.length < 6) { grid.headerCt.add(createColumns(6, 4)); grid.view.refresh(); this.disable(); } } } ]); var win = Ext.create('Ext.Window', { title: 'Grid Filters Example', height: 400, 700, layout: 'fit', items: grid }).show(); store.load(); });
后记:Extjs中有些插件初次接触不是很好懂,如本博客中的第一个示例代码中的Ext.XTemplate,积累经验才是最重要的。