這一節,我們將看到ExtJs功能強大的可編輯網格控件,幾乎與VS.Net的GridView功能一樣了,但是ExtJs的可是純JS的UI
一.靜態示例(改自ExtJs的官方示例)
a.因爲我們是採用xml做爲數據源的,這裏貼出xml的內容
<?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>
轉載請註明來自"菩提樹下的楊過"http://www.cnblogs.com/yjmyzz/archive/2008/08/29/1279307.html