extjs-mvc 0.4.0.f → 0.4.0.g
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/bin/extjs-mvc +0 -3
- data/lib/extjs-mvc.rb +10 -6
- data/lib/extjs-mvc/api.rb +0 -1
- metadata +8 -84
- data/lib/src/App.js +0 -219
- data/lib/src/MVC.js +0 -260
- data/lib/src/Presenter.js +0 -52
- data/lib/src/README.rdoc +0 -69
- data/lib/src/controller/Controller.js +0 -278
- data/lib/src/controller/CrudController.js +0 -460
- data/lib/src/lib/Array.js +0 -26
- data/lib/src/lib/Booter.js +0 -416
- data/lib/src/lib/ClassManager.js +0 -191
- data/lib/src/lib/ControllerClassManager.js +0 -95
- data/lib/src/lib/Dependencies.js +0 -44
- data/lib/src/lib/DispatchMatcher.js +0 -98
- data/lib/src/lib/Dispatcher.js +0 -129
- data/lib/src/lib/Environment.js +0 -43
- data/lib/src/lib/Inflector.js +0 -155
- data/lib/src/lib/ModelClassManager.js +0 -19
- data/lib/src/lib/Route.js +0 -139
- data/lib/src/lib/Router.js +0 -282
- data/lib/src/lib/String.js +0 -94
- data/lib/src/lib/ViewClassManager.js +0 -229
- data/lib/src/lib/notes.txt +0 -32
- data/lib/src/model/AdapterManager.js +0 -30
- data/lib/src/model/Association.js +0 -26
- data/lib/src/model/Base.js +0 -63
- data/lib/src/model/BelongsToAssociation.js +0 -116
- data/lib/src/model/Cache.js +0 -131
- data/lib/src/model/HasManyAssociation.js +0 -160
- data/lib/src/model/Model.js +0 -331
- data/lib/src/model/UrlBuilder.js +0 -106
- data/lib/src/model/adapters/AbstractAdapter.js +0 -296
- data/lib/src/model/adapters/MemoryAdapter.js +0 -103
- data/lib/src/model/adapters/RESTAdapter.js +0 -345
- data/lib/src/model/adapters/RESTJSONAdapter.js +0 -68
- data/lib/src/model/adapters/notes.txt +0 -42
- data/lib/src/model/associations/Association.js +0 -192
- data/lib/src/model/associations/notes.txt +0 -87
- data/lib/src/model/validations/Errors.js +0 -136
- data/lib/src/model/validations/Plugin.js +0 -139
- data/lib/src/model/validations/Validations.js +0 -276
- data/lib/src/notes/Charts.graffle +0 -0
- data/lib/src/overrides/Ext.Component.js +0 -21
- data/lib/src/overrides/Ext.extend.js +0 -142
- data/lib/src/spec/Array.spec.js +0 -15
- data/lib/src/spec/ExtMVC.spec.js +0 -65
- data/lib/src/spec/Model.spec.js +0 -370
- data/lib/src/spec/OS.spec.js +0 -83
- data/lib/src/spec/Router.spec.js +0 -99
- data/lib/src/spec/SpecHelper.js +0 -106
- data/lib/src/spec/String.spec.js +0 -83
- data/lib/src/spec/model/AbstractAdapter.spec.js +0 -49
- data/lib/src/spec/model/Associations.spec.js +0 -99
- data/lib/src/spec/model/Cache.spec.js +0 -5
- data/lib/src/spec/model/RESTAdapter.spec.js +0 -19
- data/lib/src/spec/model/ValidationErrors.spec.js +0 -64
- data/lib/src/spec/model/Validations.spec.js +0 -166
- data/lib/src/spec/model/ValidationsPlugin.spec.js +0 -108
- data/lib/src/spec/suite.html +0 -60
- data/lib/src/specs-old/JSSpec.css +0 -216
- data/lib/src/specs-old/JSSpec.js +0 -1512
- data/lib/src/specs-old/all.html +0 -66
- data/lib/src/specs-old/base.js +0 -14
- data/lib/src/specs-old/controller.js +0 -17
- data/lib/src/specs-old/diff_match_patch.js +0 -1
- data/lib/src/specs-old/model.js +0 -70
- data/lib/src/specs-old/route.js +0 -38
- data/lib/src/specs-old/router.js +0 -59
- data/lib/src/specs-old/string.js +0 -22
- data/lib/src/testrunner/JSpecFormatter.js +0 -111
- data/lib/src/testrunner/TestClient.js +0 -181
- data/lib/src/testrunner/TestGrid.js +0 -351
- data/lib/src/testrunner/TestRunner.js +0 -110
- data/lib/src/testrunner/TestViewport.js +0 -94
- data/lib/src/vendor.yml +0 -29
- data/lib/src/vendor/ext-3.1.1/vendor.yml +0 -16
- data/lib/src/view/FormWindow.js +0 -184
- data/lib/src/view/HasManyEditorGridPanel.js +0 -211
- data/lib/src/view/scaffold/Edit.js +0 -46
- data/lib/src/view/scaffold/Index.js +0 -561
- data/lib/src/view/scaffold/New.js +0 -20
- data/lib/src/view/scaffold/ScaffoldFormPanel.js +0 -255
@@ -1,46 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @class ExtMVC.view.scaffold.Edit
|
3
|
-
* @extends ExtMVC.view.scaffold.ScaffoldFormPanel
|
4
|
-
* Shows a generic edit form for a given model
|
5
|
-
*/
|
6
|
-
ExtMVC.registerView('scaffold', 'edit', {
|
7
|
-
xtype : 'scaffold_form',
|
8
|
-
registerXType: 'scaffold_edit',
|
9
|
-
|
10
|
-
/**
|
11
|
-
* Sets the panel's title, if not already set
|
12
|
-
*/
|
13
|
-
initComponent: function() {
|
14
|
-
Ext.applyIf(this, {
|
15
|
-
title: 'Edit ' + this.model.prototype.singularHumanName
|
16
|
-
});
|
17
|
-
|
18
|
-
ExtMVC.getView('scaffold', 'form').prototype.initComponent.apply(this, arguments);
|
19
|
-
},
|
20
|
-
|
21
|
-
/**
|
22
|
-
* Loads the given record into the form and maintains a reference to it so that it can be returned
|
23
|
-
* when the 'save' event is fired
|
24
|
-
* @param {ExtMVC.Model.Base} instance The model instance to load into this form
|
25
|
-
*/
|
26
|
-
loadRecord: function(instance) {
|
27
|
-
this.instance = instance;
|
28
|
-
this.getForm().loadRecord(instance);
|
29
|
-
},
|
30
|
-
|
31
|
-
/**
|
32
|
-
* Called when the save button is clicked or CTRL + s pressed. By default this simply fires
|
33
|
-
* the 'save' event, passing this.getForm().getValues() as the sole argument
|
34
|
-
*/
|
35
|
-
onSave: function() {
|
36
|
-
this.fireEvent('save', this.instance, this.getFormValues(), this);
|
37
|
-
}
|
38
|
-
|
39
|
-
/**
|
40
|
-
* @event save
|
41
|
-
* Fired when the user clicks the save button, or presses ctrl + s
|
42
|
-
* @param {ExtMVC.model.Base} instance The existing instance that is to be updated
|
43
|
-
* @param {Object} values The values entered into the form
|
44
|
-
* @param {ExtMVC.view.scaffold.ScaffoldFormPanel} this The form panel
|
45
|
-
*/
|
46
|
-
});
|
@@ -1,561 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @class ExtMVC.view.scaffold.Index
|
3
|
-
* @extends Ext.grid.GridPanel
|
4
|
-
* A default index view for a scaffold (a paging grid with double-click to edit)
|
5
|
-
*/
|
6
|
-
// ExtMVC.view.scaffold.Index = Ext.extend(Ext.grid.GridPanel, {
|
7
|
-
ExtMVC.registerView('scaffold', 'index', {
|
8
|
-
xtype : 'grid',
|
9
|
-
registerXType: 'scaffold_grid',
|
10
|
-
|
11
|
-
constructor: function(config) {
|
12
|
-
config = config || {};
|
13
|
-
|
14
|
-
this.model = config.model;
|
15
|
-
|
16
|
-
if (this.model == undefined) throw new Error("No model supplied to scaffold Index view");
|
17
|
-
|
18
|
-
this.controller = this.controller || config.controller;
|
19
|
-
|
20
|
-
//we can't put these in applyIf block below as the functions are executed immediately
|
21
|
-
if (config.columns == undefined && config.colModel == undefined && config.cm == undefined) {
|
22
|
-
config.columns = this.buildColumns(this.model);
|
23
|
-
}
|
24
|
-
config.store = config.store || this.model.find();
|
25
|
-
|
26
|
-
Ext.applyIf(config, {
|
27
|
-
viewConfig: { forceFit: true },
|
28
|
-
id: String.format("{0}_index", this.model.prototype.tableName),
|
29
|
-
|
30
|
-
loadMask: true,
|
31
|
-
|
32
|
-
/**
|
33
|
-
* @property dblClickToEdit
|
34
|
-
* @type Boolean
|
35
|
-
* True to edit a record when it is double clicked (defaults to true)
|
36
|
-
*/
|
37
|
-
dblClickToEdit: true
|
38
|
-
});
|
39
|
-
|
40
|
-
Ext.grid.GridPanel.prototype.constructor.call(this, config);
|
41
|
-
|
42
|
-
this.initListeners();
|
43
|
-
},
|
44
|
-
|
45
|
-
initComponent: function() {
|
46
|
-
var tbarConfig = this.hasTopToolbar ? this.buildTopToolbar() : null;
|
47
|
-
var bbar = this.hasBottomToolbar ? this.buildBottomToolbar(this.store) : null;
|
48
|
-
|
49
|
-
Ext.applyIf(this, {
|
50
|
-
title: this.getTitle(),
|
51
|
-
tbar: tbarConfig,
|
52
|
-
bbar: bbar,
|
53
|
-
|
54
|
-
keys: [
|
55
|
-
{
|
56
|
-
key: 'a',
|
57
|
-
scope: this,
|
58
|
-
handler: this.onAdd
|
59
|
-
},
|
60
|
-
{
|
61
|
-
key: 'e',
|
62
|
-
scope: this,
|
63
|
-
handler: this.onEdit
|
64
|
-
},
|
65
|
-
{
|
66
|
-
key: Ext.EventObject.DELETE,
|
67
|
-
scope: this,
|
68
|
-
handler: this.onDelete
|
69
|
-
}
|
70
|
-
]
|
71
|
-
});
|
72
|
-
|
73
|
-
Ext.grid.GridPanel.prototype.initComponent.apply(this, arguments);
|
74
|
-
},
|
75
|
-
|
76
|
-
/**
|
77
|
-
* Sets up events emitted by the grid panel
|
78
|
-
*/
|
79
|
-
initEvents: function() {
|
80
|
-
this.addEvents(
|
81
|
-
/**
|
82
|
-
* @event edit
|
83
|
-
* Fired when the user wishes to edit a particular record
|
84
|
-
* @param {ExtMVC.Model.Base} instance The instance of the model the user wishes to edit
|
85
|
-
*/
|
86
|
-
'edit',
|
87
|
-
|
88
|
-
/**
|
89
|
-
* @event new
|
90
|
-
* Fired when the user wishes to add a new record
|
91
|
-
*/
|
92
|
-
'new',
|
93
|
-
|
94
|
-
/**
|
95
|
-
* @event delete
|
96
|
-
* Fired when the user wishes to destroy a particular record
|
97
|
-
* @param {ExtMVC.Model.Base} instance The instance fo the model the user wishes to destroy
|
98
|
-
*/
|
99
|
-
'delete'
|
100
|
-
);
|
101
|
-
|
102
|
-
Ext.grid.GridPanel.prototype.initEvents.apply(this, arguments);
|
103
|
-
},
|
104
|
-
|
105
|
-
/**
|
106
|
-
* Listens to clicks in the grid and contained components and takes action accordingly.
|
107
|
-
* Mostly, this is simply a case of capturing events received and re-emitting normalized events
|
108
|
-
*/
|
109
|
-
initListeners: function() {
|
110
|
-
if (this.dblClickToEdit === true) {
|
111
|
-
this.on({
|
112
|
-
scope : this,
|
113
|
-
'rowdblclick': this.onEdit
|
114
|
-
});
|
115
|
-
}
|
116
|
-
|
117
|
-
if (this.controller != undefined) {
|
118
|
-
this.controller.on('delete', this.refreshStore, this);
|
119
|
-
}
|
120
|
-
},
|
121
|
-
|
122
|
-
//removes any controller listeners added by initListeners
|
123
|
-
destroy: function() {
|
124
|
-
if (this.controller != undefined) {
|
125
|
-
this.controller.un('delete', this.refreshStore, this);
|
126
|
-
}
|
127
|
-
|
128
|
-
Ext.grid.GridPanel.prototype.destroy.apply(this, arguments);
|
129
|
-
},
|
130
|
-
|
131
|
-
/**
|
132
|
-
* Calls reload on the grid's store
|
133
|
-
*/
|
134
|
-
refreshStore: function() {
|
135
|
-
//NOTE: For some reason this.store is undefined here, but getCmp on this.id works :/
|
136
|
-
var store = Ext.getCmp(this.id).store;
|
137
|
-
store.reload();
|
138
|
-
},
|
139
|
-
|
140
|
-
/**
|
141
|
-
* Returns the title to give to this grid. If this view is currently representing a model called User,
|
142
|
-
* this will return "All Users". Override to set your own grid title
|
143
|
-
* @return {String} The title to give the grid
|
144
|
-
*/
|
145
|
-
getTitle: function() {
|
146
|
-
return String.format("All {0}", this.model.prototype.pluralHumanName);
|
147
|
-
},
|
148
|
-
|
149
|
-
/**
|
150
|
-
* @property preferredColumns
|
151
|
-
* @type Array
|
152
|
-
* An array of columns to show first in the grid, if they exist
|
153
|
-
* Overwrite ExtMVC.view.scaffold.Index.preferredColumns if required
|
154
|
-
*/
|
155
|
-
preferredColumns: ['id', 'title', 'name', 'first_name', 'last_name', 'login', 'username', 'email', 'email_address', 'content', 'message', 'body'],
|
156
|
-
|
157
|
-
/**
|
158
|
-
* @property ignoreColumns
|
159
|
-
* @type Array
|
160
|
-
* An array of columns not to show in the grid (defaults to empty)
|
161
|
-
*/
|
162
|
-
ignoreColumns: ['password', 'password_confirmation'],
|
163
|
-
|
164
|
-
/**
|
165
|
-
* @property useColumns
|
166
|
-
* @type Array
|
167
|
-
* An array of fields to use to generate the column model. This defaults to undefined, but if added in a
|
168
|
-
* subclass then these fields are used to make the column model.
|
169
|
-
*/
|
170
|
-
useColumns: undefined,
|
171
|
-
|
172
|
-
/**
|
173
|
-
* @property narrowColumns
|
174
|
-
* @type Array
|
175
|
-
* An array of columns to render at half the average width
|
176
|
-
*/
|
177
|
-
narrowColumns: ['id'],
|
178
|
-
|
179
|
-
/**
|
180
|
-
* @property wideColumns
|
181
|
-
* @type Array
|
182
|
-
* An array of columns to render at double the average width
|
183
|
-
*/
|
184
|
-
wideColumns: ['message', 'content', 'description', 'bio', 'body'],
|
185
|
-
|
186
|
-
/**
|
187
|
-
* @property narrowColumnWidth
|
188
|
-
* @type Number
|
189
|
-
* The width to make columns in the narrowColumns array (defaults to 30)
|
190
|
-
*/
|
191
|
-
narrowColumnWidth: 30,
|
192
|
-
|
193
|
-
/**
|
194
|
-
* @property normalColumnWidth
|
195
|
-
* @type Number
|
196
|
-
* The width to make columns not marked as narrow or wide (defaults to 100)
|
197
|
-
*/
|
198
|
-
normalColumnWidth: 100,
|
199
|
-
|
200
|
-
/**
|
201
|
-
* @property wideColumnWidth
|
202
|
-
* @type Number
|
203
|
-
* The width to make wide columns (defaults to 200)
|
204
|
-
*/
|
205
|
-
wideColumnWidth: 200,
|
206
|
-
|
207
|
-
/**
|
208
|
-
* @property hasTopToolbar
|
209
|
-
* @type Boolean
|
210
|
-
* True to automatically include a default top toolbar (defaults to true)
|
211
|
-
*/
|
212
|
-
hasTopToolbar: true,
|
213
|
-
|
214
|
-
/**
|
215
|
-
* @property hasBottomToolbar
|
216
|
-
* @type Boolean
|
217
|
-
* True to automatically include a paging bottom toolbar (defaults to true)
|
218
|
-
*/
|
219
|
-
hasBottomToolbar: true,
|
220
|
-
|
221
|
-
/**
|
222
|
-
* Takes a model definition and returns a column array to use for a columnModel
|
223
|
-
*/
|
224
|
-
buildColumns: function(model) {
|
225
|
-
//check to see if GridColumns have been created for this model
|
226
|
-
//e.g. for a MyApp.models.User model, checks for existence of MyApp.views.users.GridColumns
|
227
|
-
if (this.viewsPackage && this.viewsPackage.GridColumns) {
|
228
|
-
var columns = this.viewsPackage.GridColumns;
|
229
|
-
} else {
|
230
|
-
var fields = this.getFields(),
|
231
|
-
columns = [];
|
232
|
-
wideColumns = [];
|
233
|
-
|
234
|
-
//put any preferred columns at the front
|
235
|
-
Ext.each(fields, function(field) {
|
236
|
-
if (this.preferredColumns.indexOf(field.name) > -1) {
|
237
|
-
columns.push(this.buildColumn(field.name));
|
238
|
-
}
|
239
|
-
}, this);
|
240
|
-
|
241
|
-
//add the rest of the columns to the end
|
242
|
-
Ext.each(fields, function(field) {
|
243
|
-
if (this.preferredColumns.indexOf(field.name) == -1 && this.ignoreColumns.indexOf(field.name) == -1) {
|
244
|
-
columns.push(this.buildColumn(field.name));
|
245
|
-
};
|
246
|
-
|
247
|
-
//if it's been declared as a wide column, add it to the wideColumns array
|
248
|
-
if (this.wideColumns.indexOf(field.name)) {
|
249
|
-
wideColumns.push(field.name);
|
250
|
-
}
|
251
|
-
}, this);
|
252
|
-
|
253
|
-
//add default widths to each
|
254
|
-
for (var i = columns.length - 1; i >= 0; i--){
|
255
|
-
var col = columns[i];
|
256
|
-
|
257
|
-
if (this.narrowColumns.indexOf(col.id) > -1) {
|
258
|
-
//id col is extra short
|
259
|
-
Ext.applyIf(col, { width: this.narrowColumnWidth });
|
260
|
-
} else if(this.wideColumns.indexOf(col.id) > -1) {
|
261
|
-
//we have a wide column
|
262
|
-
Ext.applyIf(col, { width: this.wideColumnWidth });
|
263
|
-
} else {
|
264
|
-
//we have a normal column
|
265
|
-
Ext.applyIf(col, { width: this.normalColumnWidth });
|
266
|
-
}
|
267
|
-
};
|
268
|
-
}
|
269
|
-
|
270
|
-
return columns;
|
271
|
-
},
|
272
|
-
|
273
|
-
/**
|
274
|
-
* Returns the array of field names the buildColumns() should use to generate the column model.
|
275
|
-
* This will return this.useColumns if defined, otherwise it will return all fields
|
276
|
-
* @return {Array} The array of field names to use to generate the column model
|
277
|
-
*/
|
278
|
-
getFields: function() {
|
279
|
-
if (this.useColumns === undefined) {
|
280
|
-
return this.model.prototype.fields.items;
|
281
|
-
} else {
|
282
|
-
var fields = [];
|
283
|
-
Ext.each(this.useColumns, function(column) {
|
284
|
-
fields.push({name: column});
|
285
|
-
}, this);
|
286
|
-
|
287
|
-
return fields;
|
288
|
-
}
|
289
|
-
},
|
290
|
-
|
291
|
-
/**
|
292
|
-
* Build a single column object based on a name, adds default properties
|
293
|
-
* @param {Object/String} cfg Column config object (can just include a 'name' property). Also accepts a string, which is translated into the name property
|
294
|
-
* @return {Object} A fully-formed column config with default properties set
|
295
|
-
*/
|
296
|
-
buildColumn: function(cfg) {
|
297
|
-
var cfg = cfg || {};
|
298
|
-
if (typeof(cfg) == 'string') {cfg = {name: cfg};}
|
299
|
-
|
300
|
-
return Ext.applyIf(cfg, {
|
301
|
-
id : cfg.name,
|
302
|
-
header : cfg.name.replace(/_/g, " ").titleize(),
|
303
|
-
sortable : true,
|
304
|
-
dataIndex: cfg.name
|
305
|
-
});
|
306
|
-
},
|
307
|
-
|
308
|
-
/**
|
309
|
-
* @property hasAddButton
|
310
|
-
* @type Boolean
|
311
|
-
* Defines whether or not there should be an 'Add' button on the top toolbar (defaults to true)
|
312
|
-
*/
|
313
|
-
hasAddButton: true,
|
314
|
-
|
315
|
-
/**
|
316
|
-
* @property hasEditButton
|
317
|
-
* @type Boolean
|
318
|
-
* Defines whether or not there should be a 'Edit' button on the top toolbar (defaults to true)
|
319
|
-
*/
|
320
|
-
hasEditButton: true,
|
321
|
-
|
322
|
-
/**
|
323
|
-
* @property hasDeleteButton
|
324
|
-
* @type Boolean
|
325
|
-
* Defines whether or not there should be a 'Delete' button on the top toolbar (defaults to true)
|
326
|
-
*/
|
327
|
-
hasDeleteButton: true,
|
328
|
-
|
329
|
-
/**
|
330
|
-
* Builds the Add button for the top toolbar. Override to create your own
|
331
|
-
* @param {Object} config An optional config object used to customise the button
|
332
|
-
* @return {Ext.Button} The Add Button
|
333
|
-
*/
|
334
|
-
buildAddButton: function(config) {
|
335
|
-
return new Ext.Button(
|
336
|
-
Ext.applyIf(config || {}, {
|
337
|
-
text: 'New ' + this.model.prototype.singularHumanName,
|
338
|
-
scope: this,
|
339
|
-
iconCls: 'add',
|
340
|
-
handler: this.onAdd
|
341
|
-
}
|
342
|
-
));
|
343
|
-
},
|
344
|
-
|
345
|
-
/**
|
346
|
-
* Builds the Edit button for the top toolbar. Override to create your own
|
347
|
-
* @param {Object} config An optional config object used to customise the button
|
348
|
-
* @return {Ext.Button} The Edit button
|
349
|
-
*/
|
350
|
-
buildEditButton: function(config) {
|
351
|
-
return new Ext.Button(
|
352
|
-
Ext.applyIf(config || {}, {
|
353
|
-
text: 'Edit selected',
|
354
|
-
scope: this,
|
355
|
-
iconCls: 'edit',
|
356
|
-
disabled: true,
|
357
|
-
handler: this.onEdit
|
358
|
-
}
|
359
|
-
));
|
360
|
-
},
|
361
|
-
|
362
|
-
/**
|
363
|
-
* Builds the Delete button for the top toolbar. Override to create your own
|
364
|
-
* @param {Object} config An optional config object used to customise the button
|
365
|
-
* @return {Ext.Button} The Delete button
|
366
|
-
*/
|
367
|
-
buildDeleteButton: function(config) {
|
368
|
-
return new Ext.Button(
|
369
|
-
Ext.applyIf(config || {}, {
|
370
|
-
text: 'Delete selected',
|
371
|
-
disabled: true,
|
372
|
-
scope: this,
|
373
|
-
iconCls: 'delete',
|
374
|
-
handler: this.onDelete
|
375
|
-
}
|
376
|
-
));
|
377
|
-
},
|
378
|
-
|
379
|
-
/**
|
380
|
-
* Creates Add, Edit and Delete buttons for the top toolbar and sets up listeners to
|
381
|
-
* activate/deactivate them as appropriate
|
382
|
-
* @return {Array} An array of buttons
|
383
|
-
*/
|
384
|
-
buildTopToolbar: function() {
|
385
|
-
var items = [];
|
386
|
-
|
387
|
-
if (this.hasAddButton === true) {
|
388
|
-
this.addButton = this.buildAddButton();
|
389
|
-
items.push(this.addButton, '-');
|
390
|
-
}
|
391
|
-
|
392
|
-
if (this.hasEditButton === true) {
|
393
|
-
this.editButton = this.buildEditButton();
|
394
|
-
items.push(this.editButton, '-');
|
395
|
-
}
|
396
|
-
|
397
|
-
if (this.hasDeleteButton === true) {
|
398
|
-
this.deleteButton = this.buildDeleteButton();
|
399
|
-
items.push(this.deleteButton, '-');
|
400
|
-
}
|
401
|
-
|
402
|
-
if (this.hasSearchField === true) {
|
403
|
-
this.searchField = this.buildSearchField();
|
404
|
-
items.push(this.searchField, '-');
|
405
|
-
}
|
406
|
-
|
407
|
-
this.getSelectionModel().on('selectionchange', function(selModel) {
|
408
|
-
if (selModel.getCount() > 0) {
|
409
|
-
if (this.deleteButton != undefined) this.deleteButton.enable();
|
410
|
-
if (this.editButton != undefined) this.editButton.enable();
|
411
|
-
} else {
|
412
|
-
if (this.deleteButton != undefined) this.deleteButton.disable();
|
413
|
-
if (this.editButton != undefined) this.editButton.disable();
|
414
|
-
};
|
415
|
-
}, this);
|
416
|
-
|
417
|
-
return items;
|
418
|
-
},
|
419
|
-
|
420
|
-
/**
|
421
|
-
* @property pageSize
|
422
|
-
* @type Number
|
423
|
-
* The pageSize to use in the PagingToolbar bottom Toolbar (defaults to 25)
|
424
|
-
*/
|
425
|
-
pageSize: 25,
|
426
|
-
|
427
|
-
/**
|
428
|
-
* Creates a paging toolbar to be placed at the bottom of this grid
|
429
|
-
* @param {Ext.data.Store} store The store to bind to this paging toolbar (should be the same as for the main grid)
|
430
|
-
* @return {Ext.PagingToolbar} The Paging Toolbar
|
431
|
-
*/
|
432
|
-
buildBottomToolbar: function(store) {
|
433
|
-
return new Ext.PagingToolbar({
|
434
|
-
store: store,
|
435
|
-
displayInfo: true,
|
436
|
-
pageSize: this.pageSize,
|
437
|
-
emptyMsg: String.format("No {0} to display", this.model.prototype.pluralHumanName)
|
438
|
-
});
|
439
|
-
},
|
440
|
-
|
441
|
-
/**
|
442
|
-
* @property hasSearchField
|
443
|
-
* @type Boolean
|
444
|
-
* True to add a search input box to the end of the top toolbar (defaults to false)
|
445
|
-
*/
|
446
|
-
hasSearchField: false,
|
447
|
-
|
448
|
-
/**
|
449
|
-
* @property searchParamName
|
450
|
-
* @type String
|
451
|
-
* The name of the param to send as the search variable in the GET request (defaults to 'q')
|
452
|
-
*/
|
453
|
-
searchParamName: 'q',
|
454
|
-
|
455
|
-
/**
|
456
|
-
* Builds the search field component which can be added to the top toolbar of a grid
|
457
|
-
* @return {Ext.form.TwinTriggerField} The search field object
|
458
|
-
*/
|
459
|
-
buildSearchField: function() {
|
460
|
-
/**
|
461
|
-
* @property searchField
|
462
|
-
* @type Ext.form.TwinTriggerField
|
463
|
-
* The search field that is added to the top toolbar
|
464
|
-
*/
|
465
|
-
this.searchField = new Ext.form.TwinTriggerField({
|
466
|
-
width : 200,
|
467
|
-
validationEvent : false,
|
468
|
-
validateOnBlur : false,
|
469
|
-
hideTrigger1 : true,
|
470
|
-
onTrigger1Click : this.clearSearchField.createDelegate(this, []),
|
471
|
-
onTrigger2Click : this.onSearch.createDelegate(this, []),
|
472
|
-
|
473
|
-
trigger1Class :'x-form-clear-trigger',
|
474
|
-
trigger2Class :'x-form-search-trigger'
|
475
|
-
});
|
476
|
-
|
477
|
-
this.searchField.on('specialkey', function(field, e) {
|
478
|
-
if (e.getKey() === e.ESC) this.clearSearchField(); e.stopEvent();
|
479
|
-
if (e.getKey() === e.ENTER) this.onSearch();
|
480
|
-
}, this);
|
481
|
-
|
482
|
-
return this.searchField;
|
483
|
-
},
|
484
|
-
|
485
|
-
/**
|
486
|
-
* Clears the search field in the top toolbar and hides the clear button
|
487
|
-
*/
|
488
|
-
clearSearchField: function() {
|
489
|
-
var f = this.searchField;
|
490
|
-
|
491
|
-
f.el.dom.value = '';
|
492
|
-
f.triggers[0].hide();
|
493
|
-
this.doSearch();
|
494
|
-
},
|
495
|
-
|
496
|
-
/**
|
497
|
-
* Attached to the search fields trigger2Click and Enter key events. Calls doSearch if the
|
498
|
-
* user has actually entered anything.
|
499
|
-
*/
|
500
|
-
onSearch: function() {
|
501
|
-
var f = this.searchField,
|
502
|
-
v = f.getRawValue();
|
503
|
-
|
504
|
-
if (v.length < 1) {
|
505
|
-
this.clearSearchField();
|
506
|
-
} else {
|
507
|
-
f.triggers[0].show();
|
508
|
-
this.doSearch(v);
|
509
|
-
}
|
510
|
-
},
|
511
|
-
|
512
|
-
/**
|
513
|
-
* Performs the actual search operation by updating the store bound to this grid
|
514
|
-
* TODO: Move this to the controller if possible (might not be...)
|
515
|
-
* @param {String} value The string to search for
|
516
|
-
*/
|
517
|
-
doSearch: function(value) {
|
518
|
-
value = value || this.searchField.getRawValue() || "";
|
519
|
-
|
520
|
-
var o = {start: 0};
|
521
|
-
this.store.baseParams = this.store.baseParams || {};
|
522
|
-
this.store.baseParams[this.searchParamName] = value;
|
523
|
-
this.store.reload({params:o});
|
524
|
-
},
|
525
|
-
|
526
|
-
/**
|
527
|
-
* Called when the add button is pressed, or when the 'a' key is pressed. By default this will simply fire the 'add' event
|
528
|
-
*/
|
529
|
-
onAdd: function() {
|
530
|
-
this.fireEvent('new');
|
531
|
-
},
|
532
|
-
|
533
|
-
/**
|
534
|
-
* Called when a row in this grid panel is double clicked. By default this will find the associated
|
535
|
-
* record and fire the 'edit' event. Override to provide your own logic
|
536
|
-
* @param {Ext.EventObject} e The Event object
|
537
|
-
*/
|
538
|
-
onEdit: function(e) {
|
539
|
-
var obj = this.getSelectionModel().getSelected();
|
540
|
-
|
541
|
-
if (obj) this.fireEvent('edit', obj);
|
542
|
-
},
|
543
|
-
|
544
|
-
/**
|
545
|
-
* Called when the delete button is pressed, or the delete key is pressed. By default this will ask the user to confirm,
|
546
|
-
* then fire the delete action with the selected record as the sole argument
|
547
|
-
*/
|
548
|
-
onDelete: function() {
|
549
|
-
Ext.Msg.confirm(
|
550
|
-
'Are you sure?',
|
551
|
-
String.format("Are you sure you want to delete this {0}? This cannot be undone.", this.model.prototype.modelName.humanize()),
|
552
|
-
function(btn) {
|
553
|
-
if (btn == 'yes') {
|
554
|
-
var selected = this.getSelectionModel().getSelected();
|
555
|
-
if (selected) this.fireEvent('delete', selected);
|
556
|
-
};
|
557
|
-
},
|
558
|
-
this
|
559
|
-
);
|
560
|
-
}
|
561
|
-
});
|