1
// /<reference path="vswd-ext_2.0.2.js" />
2
/*
3
*作者:大笨
4
*日期:2009-10-20
5
*版本:1.0
6
*博客地址:http://yage.cnblogs.com
7
*QQ:14202190
8
*/
9
Ext.BLANK_IMAGE_URL = ' ../extjs/resources/images/default/s.gif ' ;
10
11
Ext.onReady( function () {
12
Ext.QuickTips.init();
13
14
// 格式化日期
15
function formatDate(value) {
16
return value ? value.dateFormat( ' Y年m月d日 ' ) : '' ;
17
}
18
19
// 别名
20
var fm = Ext.form;
21
22
// 构造一个只能包含checkbox的列
23
var checkColumn = new Ext.grid.CheckColumn( {
24
header: ' Indoor? ' ,
25
dataIndex: ' indoor ' ,
26
width: 55
27
} );
28
29
// 构造ColumnModel
30
var cm = new Ext.grid.ColumnModel( {
31
columns: [ {
32
id: ' common ' ,
33
header: ' Common Name ' ,
34
dataIndex: ' common ' ,
35
width: 220 ,
36
// 使用上边定义好的别名
37
editor: new fm.TextField( {
38
allowBlank: false
39
} )
40
} , {
41
header: ' Light ' ,
42
dataIndex: ' light ' ,
43
width: 130 ,
44
editor: new fm.ComboBox( {
45
typeAhead: true ,
46
triggerAction: ' all ' ,
47
transform: ' light ' ,
48
lazyRender: true ,
49
listClass: ' x-combo-list-small '
50
} )
51
} , {
52
header: ' Price ' ,
53
dataIndex: ' price ' ,
54
width: 70 ,
55
align: ' right ' ,
56
renderer: ' usMoney ' ,
57
editor: new fm.NumberField( {
58
allowBlank: false ,
59
allowNegative: false ,
60
maxValue: 100000
61
} )
62
} , {
63
header: ' Available ' ,
64
dataIndex: ' availDate ' ,
65
width: 95 ,
66
renderer: formatDate,
67
editor: new fm.DateField( {
68
format: ' Y年m月d日 ' ,
69
minValue: ' 01/01/06 ' ,
70
disabledDays: [ 0 , 6 ],
71
disabledDaysText: ' Plants are not available on the weekends '
72
} )
73
} ,
74
checkColumn
75
],
76
defaults: {
77
sortable: true
78
}
79
} );
80
81
82
// 构造一个Store对象
83
var store = new Ext.data.Store( {
84
85
url: ' plants.xml ' ,
86
87
reader: new Ext.data.XmlReader(
88
{
89
record: ' plant '
90
} ,
91
92
[
93
{ name: ' common ' , type: ' string ' } ,
94
{ name: ' botanical ' , type: ' string ' } ,
95
{ name: ' light ' } ,
96
{ name: ' price ' , type: ' float ' } ,
97
{ name: ' availDate ' , mapping: ' availability ' , type: ' date ' , dateFormat: ' m/d/Y ' } ,
98
{ name: ' indoor ' , type: ' bool ' }
99
]
100
),
101
102
sortInfo: { field: ' common ' , direction: ' ASC ' }
103
} );
104
105
// 构造可编辑的grid
106
var grid = new Ext.grid.EditorGridPanel( {
107
store: store,
108
cm: cm,
109
renderTo: ' grid ' ,
110
width: 600 ,
111
height: 300 ,
112
autoExpandColumn: ' common ' ,
113
title: ' Edit Plants? ' ,
114
frame: true ,
115
plugins: checkColumn,
116
clicksToEdit: 1 ,
117
listeners: {
118
" afterEdit " : {
119
fn: afterEdit,
120
scope: this
121
}
122
} ,
123
tbar: [ {
124
text: " 保存 " ,
125
handler: function () {
126
var modified = store.modified;
127
updateData(modified);
128
}
129
} ]
130
} );
131
132
// 触发数据的加载
133
store.load();
134
135
// 发送数据到服务器端进行更新
136
function updateData(modified) {
137
var json = [];
138
Ext.each(modified, function (item) {
139
json.push(item.data);
140
} );
141
if (json.length > 0 ) {
142
Ext.Ajax.request( {
143
url: " EditGrid.aspx " ,
144
params: { data: Ext.util.JSON.encode(json) } ,
145
method: " POST " ,
146
success: function (response) {
147
Ext.Msg.alert( " 信息 " , " 数据更新成功! " , function () { store.reload(); } );
148
} ,
149
failure: function (response) {
150
Ext.Msg.alert( " 警告 " , " 数据更新失败,请稍后再试! " );
151
}
152
} );
153
}
154
else {
155
Ext.Msg.alert( " 警告 " , " 没有任何需要更新的数据! " );
156
}
157
}
158
159
// 编辑后触发的事件,可在此进行数据有效性的验证
160
function afterEdit(e) {
161
if (e.field == " common " ) {
162
if (e.value == " 大笨 " ) {
163
Ext.Msg.alert( " 错误 " , "大笨是人物不是植物 " , function () { grid.startEditing(e.row, e.column) } );
164
}
165
}
166
}
167
} );
红色部分是新增加的代码,我们首先给grid增加了一个afterEdit事件,顾名思义,该事件在编辑之后被触发,我们可以在此时对数据的有效性进行验 证,在本例中,我们只是简单的让common列的值不能等于一个特定的字符串,实际的项目中可能需要对每一列用正则表达式来进行验证。在触发 afterEdit事件的时候会传递一个事件对象,该对象有如下几个属性:
grid:当前grid。
record:当前行。
field:当前列名。
value:被设置的值。
originalValue:编辑前的值。
row:行索引。
column:列索引。
我们还在grid上加了一个工具栏,上边放了一个保存按钮,用以将修改后的数据传递到服务器进行保存。由于记录的集合是一个复杂的json对象,我们需要 的只是相关数据的几个,因此第137-140行对该集合进行了处理。当然,我们还需要在服务器端接收数据然后进行处理,在系列一中我们已经学习到相关的方 法,这里不再赘述。我们看一看运行之后的效果图:
通过firebug,我们可以看到向服务器投递的数据:
接下来看看如何添加数据,我们在工具栏里边添加一个增加按钮,相关代码如下:
tbar: [
{2
text: " 保存 " ,3
handler: function () {4
var modified = store.modified;5
6
updateData(modified);7
} 8
}
,9
'
-
'
,10
{11
text: " 增加 " ,12
handler: function () {13
var Plant = store.recordType;14
var p = new Plant( {15
common: ' New Plant 1 ' ,16
light: ' Mostly Shade ' ,17
price: 0 ,18
availDate: ( new Date()).clearTime(),19
indoor: false 20
} );21
grid.stopEditing();22
store.insert( 0 , p);23
grid.startEditing( 0 , 0 );24
} 25
}
26
]
在向grid中插入数据之前,必须要先获得插入数据的格式,Store类的recordType属性返回Record的构造函数,表明了数据的格式,然后 通过构造函数传递数据,这样就准备好了要插入的数据了。接下来将grid的编辑状态关闭,插入数据,然后把要插入数据的第一列设置为编辑状态。运行后点击 增加按钮后的效果如下:
可以看到,在grid的最上边增加了一行,对应行索引0,第一列出于编辑状态,对应列索引1,增加行中的默认初始数据就是我们在构造函数中传递进来的数据。注意,新增加的数据在修改之前是不会保存在store的modified属性里边的。
我们再来看看如何进行删除操作。在进行删除之前,我们必须要选择需要删除的行,grid有单元格选择模型和行选择模型两种,分别以类 CellSelectionModel和RowSelectionModel来表示,默认是单元格选择模型,也就是在点击单元格的时候选中的是当前单元 格,可以通过配置属性selModle(可简写为sm)来指定选择模式:sm:new Ext.grid.RowSelectionModel({singleSelection:true}), 这样就把选择模型改为了行选择模型,参数singleSelect指明是否是单选的,为真的时候只能选择一行,默认是false,可以按下ctrl键或者 shift键进行多行的选择。选择好之后,我们就来看看如何删除吧:
tbar: [
{2
text: " 保存 " ,3
handler: function () {4
var modified = store.modified;5
updateData(modified);6
} 7
}
,8
'
-
'
,9
{10
text: " 增加 " ,11
handler: function () {12
var Plant = store.recordType;13
var p = new Plant( {14
common: ' New Plant 1 ' ,15
light: ' Mostly Shade ' ,16
price: 0 ,17
availDate: ( new Date()).clearTime(),18
indoor: false 19
} );20
grid.stopEditing();21
store.insert( 0 , p);22
grid.startEditing( 0 , 0 );23
} 24
}
,25
"
"
,26
{27
text: " 删除 " ,28
handler: function () {29
var selModel = grid.getSelectionModel();30
if (selModel.hasSelection()) {31
Ext.Msg.confirm( " 警告 " , " 确定要删除吗? " , function (button) {32
if (button == " yes " ) {33
var selections = selModel.getSelections();34
Ext.each(selections, function (item) {35
store.remove(item);36
} );37
} 38
} );39
} 40
else {41
Ext.Msg.alert( " 错误 " , " 没有任何行被选中,无法进行删除操作! " );42
} 43
} 44
}
45
]
我们先通过grid的getSelectionModel方法获得当前的选择模型,由于当前我们使用了行选择模型,所以返回的是 RowSelectionModel的对象,然后通过该对象的hasSelection方法判断有没有行呗选中,没有的话就弹出一个对话框,如果有选中的 行要被删除,弹出一个提示框让用户确定删除操作,如果确实要删除,使用RowSelectionModel对象的getSelections方法返回所有 被选择行的集合,遍历此集合,从store中去掉集合中的行。看看效果图:
点击“是”,所有选中的行被删除,通过firebug可以看到被删除的行在store的removed属性中保存。
但是有些人可能不习惯这里所谓的行选择模型,他们可能喜欢看到在每一行的前边有一个checkbox,勾选了之后表示选择该行,extjs中的 CheckboxSelectionModel类可以方便的让我们实现这一点,该类继承自RowSelectionModel,说明这只是一种特殊的行选 择模型。我们具体来看看怎么进行操作。首先需要定义一个CheckboxSelectionModel的对象:var sm=new Ext.grid.CheckboxSelctionModle({checkOnly:true}),这里chckOnly:true表明只能通过 checkbox来选择行,为false的话则还可以通过我们上边提到的方法来选择行。接下来需要把原来的行选择模型替换成我们新的sm,然后运行一下看 看吧。我们没有看到预期中的效果,这是为什么呢?仔细想一想,确实应该是看不到什么效果,我们知道列都是在ColumnModel里边配置的,我们的 CheckboxSelectionModel需要添加一列,自然也要在其中配置。那我们就加上去吧,完整的代码如下:
///
<
reference
path
="vswd-ext_2.0.2.js"
/>
2
/*
3
*作者:大笨
4
*日期:2009-10-20
5
*版本:1.0
6
*博客地址:http://yage.cnblogs.com 7
*QQ:14202190
8
*/
9
Ext.BLANK_IMAGE_URL = '../extjs/resources/images/default/s.gif';10
11
Ext.onReady(function() {12
Ext.QuickTips.init();13
14
//格式化日期
15
function formatDate(value) {16
return value ? value.dateFormat('Y年m月d日') : '';17
}18
19
// 别名
20
var fm = Ext.form;21
22
//checkbox选择模型
23
var sm = new Ext.grid.CheckboxSelectionModel({ checkOnly: true });24
25
//构造一个只能包含checkbox的列
26
var checkColumn = new Ext.grid.CheckColumn({27
header: 'Indoor?',28
dataIndex: 'indoor',29
width: 5530
});31
32
// 构造ColumnModel
33
var cm = new Ext.grid.ColumnModel({34
columns: [35
sm,36
{37
id: 'common',38
header: 'Common Name',39
dataIndex: 'common',40
width: 220,41
// 使用上边定义好的别名42
editor: new fm.TextField({43
allowBlank: false44
})45
}, {46
header: 'Light',47
dataIndex: 'light',48
width: 130,49
editor: new fm.ComboBox({50
typeAhead: true,51
triggerAction: 'all',52
transform: 'light',53
lazyRender: true,54
listClass: 'x-combo-list-small'55
})56
}, {57
header: 'Price',58
dataIndex: 'price',59
width: 70,60
align: 'right',61
renderer: 'usMoney',62
editor: new fm.NumberField({63
allowBlank: false,64
allowNegative: false,65
maxValue: 10000066
})67
}, {68
header: 'Available',69
dataIndex: 'availDate',70
width: 95,71
renderer: formatDate,72
editor: new fm.DateField({73
format: 'Y年m月d日',74
minValue: '01/01/06',75
disabledDays: [0, 6],76
disabledDaysText: 'Plants are not available on the weekends'77
})78
},79
checkColumn,80
],81
defaults: {82
sortable: true83
}84
});85
86
87
// 构造一个Store对象
88
var store = new Ext.data.Store({89
90
url: 'plants.xml',91
92
reader: new Ext.data.XmlReader(93
{94
record: 'plant'95
},96
97
[98
{ name: 'common', type: 'string' },99
{ name: 'botanical', type: 'string' },100
{ name: 'light' },101
{ name: 'price', type: 'float' },102
{ name: 'availDate', mapping: 'availability', type: 'date', dateFormat: 'm/d/Y' },103
{ name: 'indoor', type: 'bool' }104
]105
),106
sortInfo: { field: 'common', direction: 'ASC' }107
});108
109
// 构造可编辑的grid
110
var grid = new Ext.grid.EditorGridPanel({111
//sm: new Ext.grid.RowSelectionModel({ singleSelect: false }),
112
sm: sm,113
store: store,114
cm: cm,115
renderTo: 'grid',116
width: 600,117
height: 300,118
autoExpandColumn: 'common',119
title: 'Edit Plants?',120
frame: true,121
plugins: checkColumn,122
clicksToEdit: 2,123
listeners: {124
"afterEdit": {125
fn: afterEdit,126
scope: this127
}128
},129
tbar: [{130
text: "保存",131
handler: function() {132
var modified = store.modified;133
updateData(modified);134
}135
},136
'-',137
{138
text: "增加",139
handler: function() {140
var Plant = store.recordType;141
var p = new Plant({142
common: 'New Plant 1',143
light: 'Mostly Shade',144
price: 0,145
availDate: (new Date()).clearTime(),146
indoor: false147
});148
grid.stopEditing();149
store.insert(0, p);150
grid.startEditing(0, 0);151
}152
},153
" ",154
{155
text: "删除",156
handler: function() {157
var selModel = grid.getSelectionModel();158
if (selModel.hasSelection()) {159
Ext.Msg.confirm("警告", "确定要删除吗?", function(button) {160
if (button == "yes") {161
var selections = selModel.getSelections();162
Ext.each(selections, function(item) {163
store.remove(item);164
store.removed.push(item);165
});166
}167
168
});169
}170
else {171
Ext.Msg.alert("错误", "没有任何行被选中,无法进行删除操作!");172
}173
}174
}175
]176
});177
178
// 触发数据的加载
179
store.load();180
181
//发送数据到服务器端进行更新
182
function updateData(modified) {183
var json = [];184
Ext.each(modified, function(item) {185
json.push(item.data);186
});187
if (json.length > 0) {188
Ext.Ajax.request({189
url: "EditGrid.aspx",190
params: { data: Ext.util.JSON.encode(json) },191
method: "POST",192
success: function(response) {193
Ext.Msg.alert("信息", "数据更新成功!", function() { store.reload(); });194
},195
failure: function(response) {196
Ext.Msg.alert("警告", "数据更新失败,请稍后再试!");197
}198
});199
}200
else {201
Ext.Msg.alert("警告", "没有任何需要更新的数据!");202
}203
}204
205
//编辑后触发的事件,可在此进行数据有效性的验证
206
function afterEdit(e) {207
if (e.field == "common") {208
if (e.value == "大笨") {209
Ext.Msg.alert("错误", "大笨是人物不是植物", function() { grid.startEditing(e.row, e.column) });210
}211
}212
}213
});
再运行一下看看,OK,我们想要的效果出来了:
最后我们来总结一下,当修改grid中的内容时,Store类的modified会自动将被修改的行保存下来;当删除的时候,Store类给我们提供了一 个 removed属性,但不知道为什么不自动保存删除的行,不过自己添加也很简单;增加是最麻烦的,我们可能需要一些小技巧来保存添加的行,无论是修改的还 是未修改的,可以都放到Store类的modified属性之中,也可以放在自己建的一个集合中,但是需要从modified里边去被添加之后修改的行。 无论是编辑,增加或者删除操作,都是在本地进行,需要自己写代码将改动发送到服务器端进行处理。
1267

被折叠的 条评论
为什么被折叠?



