我們先通過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需要添加一列,自然也要在其中配置。那我們就加上去吧,完整的代碼如下:
2/*
3*作者:大笨
4*日期:2009-10-20
5*版本:1.0
6*博客地址:http://yage.cnblogs.com
7*QQ:14202190
8*/
9Ext.BLANK_IMAGE_URL = '../extjs/resources/images/default/s.gif';
10
11Ext.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: 55
30 });
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: false
44 })
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: 100000
66 })
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: true
83 }
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: this
127 }
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: false
147 });
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裏邊去被添加之後修改的行。無論是編輯,增加或者刪除操作,都是在本地進行,需要自己寫代碼將改動發送到服務器端進行處理。