这一节,我们将看到ExtJs功能强大的可编辑网格控件,几乎与VS.Net的GridView功能一样了,但是ExtJs的可是纯JS的UI
一.静态示例(改自ExtJs的官方示例)
a.因为我们是采用xml做为数据源的,这里贴出xml的内容
Code <?xml version="1.0" encoding="utf-8"?> <catalog> <plant> <common>红竹</common> <botanical>产自加拿大</botanical> <zone>4</zone> <light>喜阴</light> <price>2.44</price> <availability>03/15/2006</availability> <indoor>0</indoor> </plant> <plant> <common>紫罗兰</common> <botanical>Erythronium americanum</botanical> <zone>4</zone> <light>半阴半光</light> <price>9.04</price> <availability>02/01/2006</availability> <indoor>1</indoor> </plant> </catalog>
b.ExtJs调用页面
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <link rel="stylesheet" type="text/css" href="../resources/css/ext-all.css" /> <script type="text/javascript" src="../adapter/ext/ext-base.js"></script> <script type="text/javascript" src="../ext-all.js"></script> <title>可编辑的网格</title> </head> <body> <script type="text/javascript"> Ext.onReady(function() { Ext.QuickTips.init(); function formatDate(value) { return value ? value.dateFormat('Y年m月d日') : ''; }; var fm = Ext.form; //定义复选框列 var checkColumn = new Ext.grid.CheckColumn({ header: "室内?", dataIndex: 'indoor', width: 55 }); //定义网格的列模板 var cm = new Ext.grid.ColumnModel([{ id: 'common', header: "名称", dataIndex: 'common', width: 220, editor: new fm.TextField({ allowBlank: false }) }, { header: "光照", dataIndex: 'light', width: 130, editor: new Ext.form.ComboBox({ allowBlank:false, typeAhead: true, triggerAction: 'all', transform: 'sellight', lazyRender: true, listClass: 'x-combo-list-small' }) }, { header: "售价", dataIndex: 'price', width: 70, align: 'right', renderer: 'usMoney', editor: new fm.NumberField({ allowBlank: false, allowNegative: false, maxValue: 100000 }) }, { header: "上市时间", dataIndex: 'availDate', width: 105, renderer: formatDate, editor: new fm.DateField({ format: 'm/d/y', minValue: '01/01/06', disabledDays: [0, 6], disabledDaysText: '目前还未上市' }) }, checkColumn ]); cm.defaultSortable = true; //定义记录的类型 var Plant = Ext.data.Record.create([ {name: 'common', type: 'string' }, { name: 'botanical', type: 'string' }, { name: 'light' }, { name: 'price', type: 'float' }, { name: 'availDate', mapping: 'availability', type: 'date', dateFormat: 'm/d/Y' }, { name: 'indoor', type: 'bool' } ]); //创建数据源 var store = new Ext.data.Store({ url: 'plants.xml', reader: new Ext.data.XmlReader({ record: 'plant' }, Plant), sortInfo: { field: 'common', direction: 'ASC' } }); //创建可编辑的网格 var grid = new Ext.grid.EditorGridPanel({ store: store, cm: cm, renderTo: 'editor-grid', width: 600, height: 180, autoExpandColumn: 'common', title: '可编辑的网格', frame: true, plugins: checkColumn, clicksToEdit: 1, tbar: [{ text: '增加记录', handler: function() { var p = new Plant({ common: '新品种1', light: '喜光', price: 1.0, availDate: (new Date()).clearTime(), indoor: 1 }); grid.stopEditing(); store.insert(0, p); grid.startEditing(0, 0); } }] }); //加载数据 store.load(); }); //复选框列改变时,保存gird的id列值 Ext.grid.CheckColumn = function(config) { Ext.apply(this, config); if (!this.id) { this.id = Ext.id(); } this.renderer = this.renderer.createDelegate(this); }; Ext.grid.CheckColumn.prototype = { init: function(grid) { this.grid = grid; this.grid.on('render', function() { var view = this.grid.getView(); view.mainBody.on('mousedown', this.onMouseDown, this); }, this); }, onMouseDown: function(e, t) { if (t.className && t.className.indexOf('x-grid3-cc-' + this.id) != -1) { e.stopEvent(); var index = this.grid.getView().findRowIndex(t); var record = this.grid.store.getAt(index); record.set(this.dataIndex, !record.data[this.dataIndex]); } }, renderer: function(v, p, record) { p.css += ' x-grid3-check-col-td'; return '<div class="x-grid3-check-col' + (v ? '-on' : '') + ' x-grid3-cc-' + this.id + '"> </div>'; } }; </script> <select name="sellight" id="sellight" style="display: none;"> <option value="阴">阴</option> <option value="喜阴">喜阴</option> <option value="半阴半光">半阴半光</option> <option value="喜光">喜光</option> <option value="日光">日光</option> </select> <div id="editor-grid"></div> </body> </html>
二.结合WCF动态读取
1.WCF服务端
[OperationContract] [WebInvoke(ResponseFormat = WebMessageFormat.Xml, Method = "GET", UriTemplate = "GetData")] public T_Class[] GetData() { List<T_Class> _Result = new List<T_Class>(); using (DBDataContext db = new DBDataContext()) { _Result = db.T_Classes.Where(c => (new string[] { "shop", "product" }).Contains(c.F_Type.ToLower())).Take(30).ToList(); db.Connection.Close(); } return _Result.ToArray(); }
注意:为使linq to sql中的类支持WCF数据契约,还是要手动对类添加[DataContract]标志,对字段添加[DataMember]标志,否则无法序列化;另外对于System.DateTime类型的字段,最终序列化成xml时,格式类似<F_AddTime>2007-03-07T15:48:04</F_AddTime>,ExtJs不能正确识别这种格式,无奈之下,只好手动修改*.designer.cs文件中自动生成的T_Class类,把F_AddTime手动修改为System.String类型,同时人工处理返回格式,如下:
[Column(Storage="_F_AddTime", DbType="DateTime")] [DataMember] public string F_AddTime { get { return CNTVS.TOOLS.Utils.FormatDateString(this._F_AddTime,"yyyy-mm-dd"); } set { if ((this._F_AddTime != value)) { this.OnF_AddTimeChanging(value); this.SendPropertyChanging(); this._F_AddTime = value; this.SendPropertyChanged("F_AddTime"); this.OnF_AddTimeChanged(); } } }
这里,我调用了自己写的一个工具库的FormatDateString方法,当然大家也可以自己定义返回的格式,只要ExtJs能识别就可以了
2.前端页面,跟静态示例几乎一样,贴一下代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="03_Grid_Editable.aspx.cs" Inherits="Ajax_WCF._3_Grid_Editable" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <link rel="stylesheet" type="text/css" href="js/ext2.2/resources/css/ext-all.css" /> <script type="text/javascript" src="js/ext2.2/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="js/ext2.2/ext-all.js"></script> <title>可编辑的网格</title> </head> <body> <script type="text/javascript"> Ext.onReady(function() { Ext.QuickTips.init(); function newGuid() { var guid = ""; for (var i = 1; i <= 32; i++) { var n = Math.floor(Math.random() * 16.0).toString(16); guid += n; if ((i == 8) || (i == 12) || (i == 16) || (i == 20)) guid += "-"; } return guid; } function formatDate(value) { return value ? value.dateFormat('Y年m月d日') : ''; }; var fm = Ext.form; //定义复选框列 var checkColumn = new Ext.grid.CheckColumn({ header: "显示?", dataIndex: 'F_isShow', width: 55 }); //定义网格的列模板 var cm = new Ext.grid.ColumnModel([{ id: 'F_ID', header: "分类ID", dataIndex: 'F_ID', width: 220, editor: new fm.TextField({ allowBlank: false }) }, { header: "分类名称", dataIndex: 'F_ClassName', width: 130, editor: new fm.TextField({ allowBlank:false }) },{ header: "类别", dataIndex: 'F_Type', width: 130, editor: new fm.ComboBox({ allowBlank:false, typeAhead: true, triggerAction: 'all', transform: 'selType', lazyRender: true, listClass: 'x-combo-list-small' }) }, { header: "排序号", dataIndex: 'F_Orders', width: 70, align: 'right', editor: new fm.NumberField({ allowBlank: false, allowNegative: false, maxValue: 100000 }) }, { header: "添加时间", dataIndex: 'F_AddTime', width: 105, renderer: formatDate, editor: new fm.DateField({ format: 'm/d/y', minValue: '01/01/06', disabledDays: [0, 6], disabledDaysText: '不能早于2001年01月06日' }) }, checkColumn ]); cm.defaultSortable = true; //定义记录的类型 var T_Class = Ext.data.Record.create([ { name: 'F_ID', type: 'string' }, { name: 'F_ClassName', type: 'string' }, { name: 'F_ShortName',type:"string" }, { name: 'F_ParentID', type: 'string' }, { name: 'F_Depth', type: 'float' }, { name: 'F_RootID', type: 'float' }, { name: 'F_Orders', type: 'float' }, { name: 'F_ParentIDStr', type: 'string' }, { name: 'F_ParentNameStr', type: 'string' }, { name: 'F_ReadMe', type: 'string' }, { name: 'F_AddTime', type: 'date', dateFormat: 'Y-m-d' }, { name: 'F_Type' ,type:"string"}, { name: 'F_MaxPage', type: "float" }, { name: 'F_No', type: "float" }, { name: 'F_isShow', type: "bool" }, { name: 'F_AutoID', type: "float" } ]); //创建数据源 var store = new Ext.data.Store({ url: 'MyService.svc/GetData', reader: new Ext.data.XmlReader({ record: 'T_Class' }, T_Class), sortInfo: { field: 'F_ID', direction: 'ASC' } }); //创建可编辑的网格 var grid = new Ext.grid.EditorGridPanel({ store: store, cm: cm, renderTo: 'editor-grid', width: 750, height: 300, autoExpandColumn: 'F_ID', /*title: '基本网格示例',*/ viewConfig: { columnsText: '显示列', sortAscText: '升序', sortDescText: '降序' }, frame: false, plugins: checkColumn, clicksToEdit: 1, tbar: [{ text: '增加记录', handler: function() { var p = new T_Class({ F_ID:newGuid(), F_ClassName:"新分类1", F_ShortName:"", F_ParentID:"", F_Depth:0, F_RootID:0, F_Orders:0, F_ParentIDStr:"", F_ParentNameStr:"", F_ReadMe:"", F_AddTime:(new Date()).clearTime(), F_Type:"shop", F_MaxPage:0, F_No:"", F_isShow:0, F_AutoID:0 }); grid.stopEditing(); store.insert(0, p); grid.startEditing(0, 0); } }] }); //加载数据 store.load(); }); //复选框列改变时,保存gird的id列值 Ext.grid.CheckColumn = function(config) { Ext.apply(this, config); if (!this.id) { this.id = Ext.id(); } this.renderer = this.renderer.createDelegate(this); }; Ext.grid.CheckColumn.prototype = { init: function(grid) { this.grid = grid; this.grid.on('render', function() { var view = this.grid.getView(); view.mainBody.on('mousedown', this.onMouseDown, this); }, this); }, onMouseDown: function(e, t) { if (t.className && t.className.indexOf('x-grid3-cc-' + this.id) != -1) { e.stopEvent(); var index = this.grid.getView().findRowIndex(t); var record = this.grid.store.getAt(index); record.set(this.dataIndex, !record.data[this.dataIndex]); } }, renderer: function(v, p, record) { p.css += ' x-grid3-check-col-td'; return '<div class="x-grid3-check-col' + (v ? '-on' : '') + ' x-grid3-cc-' + this.id + '"> </div>'; } }; </script> <select name="selType" id="selType" style="display: none;"> <option value="shop">商家分类</option> <option value="product">产品分类</option> <option value="place">地区分类</option> </select> <form id="form1" runat="server"> <div id="editor-grid"></div> </form> </body> </html>
转载请注明来自"菩提树下的杨过"
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句