extjs-mvc 0.4.0.j → 0.4.0.k

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. data/Rakefile +1 -1
  2. data/VERSION +1 -1
  3. data/lib/extjs-mvc.rb +0 -14
  4. data/lib/extjs-mvc/api.rb +14 -27
  5. data/lib/extjs-mvc/src/App.js +219 -0
  6. data/lib/extjs-mvc/src/MVC.js +260 -0
  7. data/lib/extjs-mvc/src/Presenter.js +52 -0
  8. data/lib/extjs-mvc/src/README.rdoc +69 -0
  9. data/lib/extjs-mvc/src/controller/Controller.js +278 -0
  10. data/lib/extjs-mvc/src/controller/CrudController.js +460 -0
  11. data/lib/extjs-mvc/src/lib/Array.js +26 -0
  12. data/lib/extjs-mvc/src/lib/Booter.js +417 -0
  13. data/lib/extjs-mvc/src/lib/ClassManager.js +191 -0
  14. data/lib/extjs-mvc/src/lib/ControllerClassManager.js +95 -0
  15. data/lib/extjs-mvc/src/lib/Dependencies.js +44 -0
  16. data/lib/extjs-mvc/src/lib/DispatchMatcher.js +98 -0
  17. data/lib/extjs-mvc/src/lib/Dispatcher.js +129 -0
  18. data/lib/extjs-mvc/src/lib/Environment.js +43 -0
  19. data/lib/extjs-mvc/src/lib/Inflector.js +155 -0
  20. data/lib/extjs-mvc/src/lib/ModelClassManager.js +19 -0
  21. data/lib/extjs-mvc/src/lib/Route.js +139 -0
  22. data/lib/extjs-mvc/src/lib/Router.js +282 -0
  23. data/lib/extjs-mvc/src/lib/String.js +94 -0
  24. data/lib/extjs-mvc/src/lib/ViewClassManager.js +229 -0
  25. data/lib/extjs-mvc/src/lib/notes.txt +32 -0
  26. data/lib/extjs-mvc/src/model/AdapterManager.js +30 -0
  27. data/lib/extjs-mvc/src/model/Association.js +26 -0
  28. data/lib/extjs-mvc/src/model/Base.js +63 -0
  29. data/lib/extjs-mvc/src/model/BelongsToAssociation.js +116 -0
  30. data/lib/extjs-mvc/src/model/Cache.js +131 -0
  31. data/lib/extjs-mvc/src/model/HasManyAssociation.js +160 -0
  32. data/lib/extjs-mvc/src/model/Model.js +331 -0
  33. data/lib/extjs-mvc/src/model/UrlBuilder.js +106 -0
  34. data/lib/extjs-mvc/src/model/adapters/AbstractAdapter.js +296 -0
  35. data/lib/extjs-mvc/src/model/adapters/MemoryAdapter.js +103 -0
  36. data/lib/extjs-mvc/src/model/adapters/RESTAdapter.js +345 -0
  37. data/lib/extjs-mvc/src/model/adapters/RESTJSONAdapter.js +68 -0
  38. data/lib/extjs-mvc/src/model/adapters/notes.txt +42 -0
  39. data/lib/extjs-mvc/src/model/associations/Association.js +192 -0
  40. data/lib/extjs-mvc/src/model/associations/notes.txt +87 -0
  41. data/lib/extjs-mvc/src/model/validations/Errors.js +136 -0
  42. data/lib/extjs-mvc/src/model/validations/Plugin.js +139 -0
  43. data/lib/extjs-mvc/src/model/validations/Validations.js +276 -0
  44. data/lib/extjs-mvc/src/notes/Charts.graffle +0 -0
  45. data/lib/extjs-mvc/src/overrides/Ext.Component.js +21 -0
  46. data/lib/extjs-mvc/src/overrides/Ext.extend.js +142 -0
  47. data/lib/extjs-mvc/src/spec/Array.spec.js +15 -0
  48. data/lib/extjs-mvc/src/spec/ExtMVC.spec.js +65 -0
  49. data/lib/extjs-mvc/src/spec/Model.spec.js +370 -0
  50. data/lib/extjs-mvc/src/spec/OS.spec.js +83 -0
  51. data/lib/extjs-mvc/src/spec/Router.spec.js +99 -0
  52. data/lib/extjs-mvc/src/spec/SpecHelper.js +106 -0
  53. data/lib/extjs-mvc/src/spec/String.spec.js +83 -0
  54. data/lib/extjs-mvc/src/spec/model/AbstractAdapter.spec.js +49 -0
  55. data/lib/extjs-mvc/src/spec/model/Associations.spec.js +99 -0
  56. data/lib/extjs-mvc/src/spec/model/Cache.spec.js +5 -0
  57. data/lib/extjs-mvc/src/spec/model/RESTAdapter.spec.js +19 -0
  58. data/lib/extjs-mvc/src/spec/model/ValidationErrors.spec.js +64 -0
  59. data/lib/extjs-mvc/src/spec/model/Validations.spec.js +166 -0
  60. data/lib/extjs-mvc/src/spec/model/ValidationsPlugin.spec.js +108 -0
  61. data/lib/extjs-mvc/src/spec/suite.html +60 -0
  62. data/lib/extjs-mvc/src/specs-old/JSSpec.css +216 -0
  63. data/lib/extjs-mvc/src/specs-old/JSSpec.js +1512 -0
  64. data/lib/extjs-mvc/src/specs-old/all.html +66 -0
  65. data/lib/extjs-mvc/src/specs-old/base.js +14 -0
  66. data/lib/extjs-mvc/src/specs-old/controller.js +17 -0
  67. data/lib/extjs-mvc/src/specs-old/diff_match_patch.js +1 -0
  68. data/lib/extjs-mvc/src/specs-old/model.js +70 -0
  69. data/lib/extjs-mvc/src/specs-old/route.js +38 -0
  70. data/lib/extjs-mvc/src/specs-old/router.js +59 -0
  71. data/lib/extjs-mvc/src/specs-old/string.js +22 -0
  72. data/lib/extjs-mvc/src/testrunner/JSpecFormatter.js +111 -0
  73. data/lib/extjs-mvc/src/testrunner/TestClient.js +181 -0
  74. data/lib/extjs-mvc/src/testrunner/TestGrid.js +351 -0
  75. data/lib/extjs-mvc/src/testrunner/TestRunner.js +110 -0
  76. data/lib/extjs-mvc/src/testrunner/TestViewport.js +94 -0
  77. data/lib/extjs-mvc/src/vendor.yml +30 -0
  78. data/lib/extjs-mvc/src/vendor/ext-3.1.1/vendor.yml +16 -0
  79. data/lib/extjs-mvc/src/view/FormWindow.js +184 -0
  80. data/lib/extjs-mvc/src/view/HasManyEditorGridPanel.js +211 -0
  81. data/lib/extjs-mvc/src/view/scaffold/Edit.js +46 -0
  82. data/lib/extjs-mvc/src/view/scaffold/Index.js +561 -0
  83. data/lib/extjs-mvc/src/view/scaffold/New.js +20 -0
  84. data/lib/extjs-mvc/src/view/scaffold/ScaffoldFormPanel.js +255 -0
  85. data/lib/{vendor.yml → extjs-mvc/vendor.yml} +0 -0
  86. data/test/app/vendor/extjs-mvc/App.js +219 -0
  87. data/test/app/vendor/extjs-mvc/MVC.js +260 -0
  88. data/test/app/vendor/extjs-mvc/Presenter.js +52 -0
  89. data/test/app/vendor/extjs-mvc/README.rdoc +69 -0
  90. data/test/app/vendor/extjs-mvc/controller/Controller.js +278 -0
  91. data/test/app/vendor/extjs-mvc/controller/CrudController.js +460 -0
  92. data/test/app/vendor/extjs-mvc/lib/Array.js +26 -0
  93. data/test/app/vendor/extjs-mvc/lib/Booter.js +417 -0
  94. data/test/app/vendor/extjs-mvc/lib/ClassManager.js +191 -0
  95. data/test/app/vendor/extjs-mvc/lib/ControllerClassManager.js +95 -0
  96. data/test/app/vendor/extjs-mvc/lib/Dependencies.js +44 -0
  97. data/test/app/vendor/extjs-mvc/lib/DispatchMatcher.js +98 -0
  98. data/test/app/vendor/extjs-mvc/lib/Dispatcher.js +129 -0
  99. data/test/app/vendor/extjs-mvc/lib/Environment.js +43 -0
  100. data/test/app/vendor/extjs-mvc/lib/Inflector.js +155 -0
  101. data/test/app/vendor/extjs-mvc/lib/ModelClassManager.js +19 -0
  102. data/test/app/vendor/extjs-mvc/lib/Route.js +139 -0
  103. data/test/app/vendor/extjs-mvc/lib/Router.js +282 -0
  104. data/test/app/vendor/extjs-mvc/lib/String.js +94 -0
  105. data/test/app/vendor/extjs-mvc/lib/ViewClassManager.js +229 -0
  106. data/test/app/vendor/extjs-mvc/lib/notes.txt +32 -0
  107. data/test/app/vendor/extjs-mvc/model/AdapterManager.js +30 -0
  108. data/test/app/vendor/extjs-mvc/model/Association.js +26 -0
  109. data/test/app/vendor/extjs-mvc/model/Base.js +63 -0
  110. data/test/app/vendor/extjs-mvc/model/BelongsToAssociation.js +116 -0
  111. data/test/app/vendor/extjs-mvc/model/Cache.js +131 -0
  112. data/test/app/vendor/extjs-mvc/model/HasManyAssociation.js +160 -0
  113. data/test/app/vendor/extjs-mvc/model/Model.js +331 -0
  114. data/test/app/vendor/extjs-mvc/model/UrlBuilder.js +106 -0
  115. data/test/app/vendor/extjs-mvc/model/adapters/AbstractAdapter.js +296 -0
  116. data/test/app/vendor/extjs-mvc/model/adapters/MemoryAdapter.js +103 -0
  117. data/test/app/vendor/extjs-mvc/model/adapters/RESTAdapter.js +345 -0
  118. data/test/app/vendor/extjs-mvc/model/adapters/RESTJSONAdapter.js +68 -0
  119. data/test/app/vendor/extjs-mvc/model/adapters/notes.txt +42 -0
  120. data/test/app/vendor/extjs-mvc/model/associations/Association.js +192 -0
  121. data/test/app/vendor/extjs-mvc/model/associations/notes.txt +87 -0
  122. data/test/app/vendor/extjs-mvc/model/validations/Errors.js +136 -0
  123. data/test/app/vendor/extjs-mvc/model/validations/Plugin.js +139 -0
  124. data/test/app/vendor/extjs-mvc/model/validations/Validations.js +276 -0
  125. data/test/app/vendor/extjs-mvc/notes/Charts.graffle +0 -0
  126. data/test/app/vendor/extjs-mvc/overrides/Ext.Component.js +21 -0
  127. data/test/app/vendor/extjs-mvc/overrides/Ext.extend.js +142 -0
  128. data/test/app/vendor/extjs-mvc/spec/Array.spec.js +15 -0
  129. data/test/app/vendor/extjs-mvc/spec/ExtMVC.spec.js +65 -0
  130. data/test/app/vendor/extjs-mvc/spec/Model.spec.js +370 -0
  131. data/test/app/vendor/extjs-mvc/spec/OS.spec.js +83 -0
  132. data/test/app/vendor/extjs-mvc/spec/Router.spec.js +99 -0
  133. data/test/app/vendor/extjs-mvc/spec/SpecHelper.js +106 -0
  134. data/test/app/vendor/extjs-mvc/spec/String.spec.js +83 -0
  135. data/test/app/vendor/extjs-mvc/spec/model/AbstractAdapter.spec.js +49 -0
  136. data/test/app/vendor/extjs-mvc/spec/model/Associations.spec.js +99 -0
  137. data/test/app/vendor/extjs-mvc/spec/model/Cache.spec.js +5 -0
  138. data/test/app/vendor/extjs-mvc/spec/model/RESTAdapter.spec.js +19 -0
  139. data/test/app/vendor/extjs-mvc/spec/model/ValidationErrors.spec.js +64 -0
  140. data/test/app/vendor/extjs-mvc/spec/model/Validations.spec.js +166 -0
  141. data/test/app/vendor/extjs-mvc/spec/model/ValidationsPlugin.spec.js +108 -0
  142. data/test/app/vendor/extjs-mvc/spec/suite.html +60 -0
  143. data/test/app/vendor/extjs-mvc/specs-old/JSSpec.css +216 -0
  144. data/test/app/vendor/extjs-mvc/specs-old/JSSpec.js +1512 -0
  145. data/test/app/vendor/extjs-mvc/specs-old/all.html +66 -0
  146. data/test/app/vendor/extjs-mvc/specs-old/base.js +14 -0
  147. data/test/app/vendor/extjs-mvc/specs-old/controller.js +17 -0
  148. data/test/app/vendor/extjs-mvc/specs-old/diff_match_patch.js +1 -0
  149. data/test/app/vendor/extjs-mvc/specs-old/model.js +70 -0
  150. data/test/app/vendor/extjs-mvc/specs-old/route.js +38 -0
  151. data/test/app/vendor/extjs-mvc/specs-old/router.js +59 -0
  152. data/test/app/vendor/extjs-mvc/specs-old/string.js +22 -0
  153. data/test/app/vendor/extjs-mvc/testrunner/JSpecFormatter.js +111 -0
  154. data/test/app/vendor/extjs-mvc/testrunner/TestClient.js +181 -0
  155. data/test/app/vendor/extjs-mvc/testrunner/TestGrid.js +351 -0
  156. data/test/app/vendor/extjs-mvc/testrunner/TestRunner.js +110 -0
  157. data/test/app/vendor/extjs-mvc/testrunner/TestViewport.js +94 -0
  158. data/test/app/vendor/extjs-mvc/vendor.yml +30 -0
  159. data/test/app/vendor/extjs-mvc/vendor/ext-3.1.1/vendor.yml +16 -0
  160. data/test/app/vendor/extjs-mvc/view/FormWindow.js +184 -0
  161. data/test/app/vendor/extjs-mvc/view/HasManyEditorGridPanel.js +211 -0
  162. data/test/app/vendor/extjs-mvc/view/scaffold/Edit.js +46 -0
  163. data/test/app/vendor/extjs-mvc/view/scaffold/Index.js +561 -0
  164. data/test/app/vendor/extjs-mvc/view/scaffold/New.js +20 -0
  165. data/test/app/vendor/extjs-mvc/view/scaffold/ScaffoldFormPanel.js +255 -0
  166. data/test/helper.rb +7 -1
  167. data/test/test_extjs-mvc.rb +46 -0
  168. metadata +167 -7
  169. data/test/test_extjs-mvc-gem.rb +0 -7
@@ -0,0 +1,460 @@
1
+ /**
2
+ * @class ExtMVC.controller.CrudController
3
+ * @extends ExtMVC.controller.Controller
4
+ * <h1>CRUD Controller</h1>
5
+ * <p>The CRUD Controller is an extension of Controller which provides the generic CRUD actions (Create, Read, Update and Delete).
6
+ * Although CRUD Controller provides sensible default options for most cases, it is also highly extensible. Here's an example for
7
+ * managing CRUD operations on a fictional 'Page' model in our app. Note that the name and model are the only required properties
8
+ * for a CRUD controller with default behaviour:</p>
9
+ <pre><code>
10
+ MyApp.controllers.PagesController = Ext.extend(ExtMVC.controller.CrudController, {
11
+ //the name of the controller (see {@link ExtMVC.controller.Controller})
12
+ name : 'pages',
13
+
14
+ //The model that this controller will be providing CRUD services for
15
+ model: MyApp.models.Page,
16
+
17
+ //override the default behaviour that occurs when the 'create' action was successfully completed
18
+ onCreateSuccess: function(instance) {
19
+ alert('new Page successfully created!');
20
+ },
21
+
22
+ //override the listeners that are attached to the Index view. The Index view is usually an instance of
23
+ //{@link ExtMVC.view.scaffold.Index} or a subclass of it.
24
+ getIndexViewListeners: function() {
25
+ return {
26
+ scope : this,
27
+ 'edit': function(instance) {
28
+ alert('inside the Index view (usually a scaffold grid), the user wants to edit an instance');
29
+ }
30
+ };
31
+ },
32
+
33
+ //provide our own implementation for destroy
34
+ destroy: function(instance) {
35
+ alert('user wants to destroy an instance');
36
+ }
37
+ });
38
+ </code></pre>
39
+ *
40
+ * <p>The 3 CRUD Controller methods that take action are create, update and destroy<p>
41
+ * <p>The 3 CRUD Controller methods that render views are index, new and edit</p>
42
+ * <p>By default, CRUD Controllers render the scaffolding views, which provide sensible default views.
43
+ * The index action renders a {@link ExtMVC.view.scaffold.Index Scaffold Grid}, edit renders a
44
+ * {@link ExtMVC.view.scaffold.Edit Scaffold Edit Form} and new renders a {@link ExtMVC.view.scaffold.New Scaffold New Form}</p>
45
+ * <p>To make CRUD controller render a customised view instead of the scaffold, simply define the relevant view and ensure it is
46
+ * available within your code. For example, if you want to show a customised Ext.Panel instead of the Scaffold Grid on index,
47
+ * simply define:</p>
48
+ <pre><code>
49
+ MyApp.views.pages.Index = Ext.extend(Ext.Panel, {
50
+ title: 'My Specialised Index view - replaces the scaffold grid'
51
+ });
52
+ </code></pre>
53
+ * <p>The same applies with Edit and New classes within the appropriate views namespace. See more on view namespaces in
54
+ * {@link ExtMVC.controller.Controller Controller}.</p>
55
+ */
56
+ ExtMVC.registerController('crud', {
57
+ extend: "controller",
58
+
59
+ /**
60
+ * @property model
61
+ * @type Function/Null
62
+ * Defaults to null. If set to a reference to an ExtMVC.model subclass, renderView will attempt to dynamically
63
+ * scaffold any missing views, if the corresponding view is defined in the ExtMVC.view.scaffold package
64
+ */
65
+ model: null,
66
+
67
+ /**
68
+ * Attempts to create a new instance of this controller's associated model
69
+ * @param {Object} data A fields object (e.g. {title: 'My instance'})
70
+ */
71
+ create: function create(data, form) {
72
+ var instance = new this.model(data);
73
+
74
+ instance.save({
75
+ scope: this,
76
+ success: this.onCreateSuccess,
77
+ failure: this.onCreateFailure
78
+ });
79
+ },
80
+
81
+ /**
82
+ * Attempts to find (read) a single model instance by ID
83
+ * @param {Number} id The Id of the instance to read
84
+ */
85
+ read: function read(id) {
86
+ this.model.findById(id, {
87
+ scope: this,
88
+ success: function(instance) {
89
+ this.fireEvent('read', instance);
90
+ },
91
+ failure: function() {
92
+ this.fireEvent('read-failed', id);
93
+ }
94
+ });
95
+ },
96
+
97
+ /**
98
+ * Attempts to update an existing instance with new values. If the update was successful the controller fires
99
+ * the 'update' event and then shows a default notice to the user (this.showUpdatedNotice()) and calls this.index().
100
+ * To cancel this default behaviour, return false from any listener on the 'update' event.
101
+ * @param {ExtMVC.model.Base} instance The existing instance object
102
+ * @param {Object} updates An object containing updates to apply to the instance
103
+ */
104
+ update: function update(instance, updates) {
105
+ for (var key in updates) {
106
+ instance.set(key, updates[key]);
107
+ }
108
+
109
+ instance.save({
110
+ scope: this,
111
+ success: function(instance) {
112
+ this.onUpdateSuccess(instance, updates);
113
+ },
114
+ failure: function() {
115
+ this.onUpdateFailure(instance, updates);
116
+ }
117
+ });
118
+ },
119
+
120
+ /**
121
+ * Attempts to delete an existing instance
122
+ * @param {Mixed} instance The ExtMVC.model.Base subclass instance to delete. Will also accept a string/number ID
123
+ */
124
+ destroy: function destroy(instance) {
125
+ if (instance.destroy == undefined) {
126
+ //if we're passed an ID instead of an instance, make a fake model instance
127
+ var config = {};
128
+ config[this.model.prototype.primaryKey] = parseInt(instance, 10);
129
+ var instance = new (this.model)(config);
130
+ }
131
+
132
+ instance.destroy({
133
+ scope: this,
134
+ success: this.onDestroySuccess,
135
+ failure: this.onDestroyFailure
136
+ });
137
+ },
138
+
139
+ /**
140
+ * Renders the custom Index view if present, otherwise falls back to the default scaffold grid
141
+ * @param {Object} config Optional config object to be passed to the view's constructor
142
+ */
143
+ index: function index(config) {
144
+ config = config || {};
145
+
146
+ Ext.applyIf(config, {
147
+ model : this.model,
148
+ controller : this,
149
+ listeners : this.getIndexViewListeners(),
150
+ viewsPackage: this.viewsPackage
151
+ });
152
+
153
+ var index = this.render('index', config);
154
+
155
+ this.fireEvent('index');
156
+
157
+ return index;
158
+ },
159
+
160
+ /**
161
+ * Renders the custom New view if present, otherwise falls back to the default scaffold New form
162
+ */
163
+ build: function build() {
164
+ var buildView = this.render('new', {
165
+ model : this.model,
166
+ controller : this,
167
+ listeners : this.getBuildViewListeners()
168
+ // items : ExtMVC.getFields(this.name)
169
+ });
170
+
171
+ this.onBuild(buildView);
172
+
173
+ return buildView;
174
+ },
175
+
176
+ /**
177
+ * Renders the custom Edit view if present, otherwise falls back to the default scaffold Edit form
178
+ * @param {Mixed} instance The model instance to edit. If not given an ExtMVC.model.Base
179
+ * instance, a findById() will be called on this controller's associated model
180
+ * @param {Object} viewConfig Optional config object to pass to the view class constructor
181
+ */
182
+ edit: function edit(instance, viewConfig) {
183
+ viewConfig = viewConfig || {};
184
+
185
+ if (instance instanceof Ext.data.Record) {
186
+ Ext.applyIf(viewConfig, {
187
+ model : this.model,
188
+ controller : this,
189
+ listeners : this.getEditViewListeners(),
190
+ // items : ExtMVC.getFields(this.name),
191
+ id : String.format("{0}_edit_{1}", this.name, instance.get(instance.primaryKey))
192
+ });
193
+
194
+ var editView = this.render('edit', viewConfig);
195
+
196
+ editView.loadRecord(instance);
197
+
198
+ this.onEdit(editView, instance);
199
+ this.fireEvent('edit', instance);
200
+
201
+ return editView;
202
+ } else {
203
+ var id = instance;
204
+
205
+ this.model.find(parseInt(id, 10), {
206
+ scope : this,
207
+ success: function(instance) {
208
+ this.edit(instance);
209
+ }
210
+ });
211
+ }
212
+ },
213
+
214
+ /**
215
+ * Returns a listeners object passed to the Index view when rendered inside the index action. This contains
216
+ * default listeners, but can be overridden in subclasses to provide custom behaviour
217
+ * @return {Object} The listeners object
218
+ */
219
+ getIndexViewListeners: function getIndexViewListeners() {
220
+ return {
221
+ scope : this,
222
+ 'delete': this.destroy,
223
+ 'new' : this.build,
224
+ 'edit' : this.edit
225
+ };
226
+ },
227
+
228
+ /**
229
+ * Returns a listeners object passed to the Edit view when rendered inside the edit action. This contains
230
+ * default listeners, but can be overridden in subclasses to provide custom behaviour
231
+ * @return {Object} The listeners object
232
+ */
233
+ getEditViewListeners: function getEditViewListeners() {
234
+ return {
235
+ scope : this,
236
+ cancel: this.index,
237
+ save : this.update
238
+ };
239
+ },
240
+
241
+ /**
242
+ * Returns a listeners object passed to the New view when rendered inside the build action. This contains
243
+ * default listeners, but can be overridden in subclasses to provide custom behaviour
244
+ * @return {Object} The listeners object
245
+ */
246
+ getBuildViewListeners: function getBuildViewListeners() {
247
+ return {
248
+ scope : this,
249
+ cancel: this.index,
250
+ save : this.create
251
+ };
252
+ },
253
+
254
+ /**
255
+ * Called when an instance has been successfully created. This just calls this.showNotice
256
+ * with a default message for this model. Overwrite to provide your own implementation
257
+ */
258
+ showCreatedNotice: function() {
259
+ this.showNotice(String.format("{0} successfully created", this.model.prototype.singularHumanName));
260
+ },
261
+
262
+ /**
263
+ * Called when an instance has been successfully updated. This just calls this.showNotice
264
+ * with a default message for this model. Overwrite to provide your own implementation
265
+ */
266
+ showUpdatedNotice: function() {
267
+ this.showNotice(String.format("{0} successfully updated", this.model.prototype.singularHumanName));
268
+ },
269
+
270
+ /**
271
+ * Called when an instance has been successfully destroyed. This just calls this.showNotice
272
+ * with a default message for this model. Overwrite to provide your own implementation
273
+ */
274
+ showDestroyedNotice: function() {
275
+ this.showNotice(String.format("{0} successfully deleted", this.model.prototype.singularHumanName));
276
+ },
277
+
278
+ /**
279
+ * Called after a successful update. By default this calls showUpdatedNotice and then this.index()
280
+ * @param {ExtMVC.model.Base} instance The newly updated instance
281
+ * @param {Object} updates The updates that were made
282
+ */
283
+ onCreateSuccess: function(instance) {
284
+ if(this.fireEvent('create', instance) !== false) {
285
+ this.showCreatedNotice();
286
+ this.index();
287
+ }
288
+ },
289
+
290
+ /**
291
+ * Called after an unsuccessful update. By default this simply fires the 'update-failed' event
292
+ * @param {ExtMVC.model.Base} instance The instance that could not be updated
293
+ * @param {Object} updates The updates that were attempted to be made
294
+ */
295
+ onCreateFailure: function(instance) {
296
+ this.fireEvent('create-failed', instance);
297
+ },
298
+
299
+ /**
300
+ * Called after a successful update. By default this calls showUpdatedNotice and then this.index()
301
+ * @param {ExtMVC.model.Base} instance The newly updated instance
302
+ * @param {Object} updates The updates that were made
303
+ */
304
+ onUpdateSuccess: function(instance, updates) {
305
+ if (this.fireEvent('update', instance, updates) !== false) {
306
+ this.showUpdatedNotice();
307
+ this.index();
308
+ }
309
+ },
310
+
311
+ /**
312
+ * Called after an unsuccessful update. By default this simply fires the 'update-failed' event
313
+ * @param {ExtMVC.model.Base} instance The instance that could not be updated
314
+ * @param {Object} updates The updates that were attempted to be made
315
+ */
316
+ onUpdateFailure: function(instance, updates) {
317
+ this.fireEvent('update-failed', instance, updates);
318
+ },
319
+
320
+ /**
321
+ * Called after successful destruction of a model instance. By default simply fires the 'delete' event
322
+ * with the instance as a single argument
323
+ * @param {ExtMVC.model.Base} instance The instane that was just destroyed
324
+ */
325
+ onDestroySuccess: function(instance) {
326
+ this.fireEvent('delete', instance);
327
+
328
+ this.showDestroyedNotice();
329
+ },
330
+
331
+ /**
332
+ * Called after unsuccessful destruction of a model instance. By default simply fires the 'delete-failed' event
333
+ * with the instance as a single argument
334
+ * @param {ExtMVC.model.Base} instance The instance that could not be destroyed
335
+ */
336
+ onDestroyFailure: function(instance) {
337
+ this.fireEvent('delete-failed', instance);
338
+ },
339
+
340
+ /**
341
+ * Called whenever the 'New' form has been rendered for a given instance. This is an empty function by default,
342
+ * which you can override to provide your own logic if needed
343
+ * @param {Ext.Component} form The rendered 'New' form
344
+ */
345
+ onBuild: function(form) {},
346
+
347
+ /**
348
+ * Called whenever the Edit form has been rendered for a given instance. This is an empty function by default,
349
+ * which you can override to provide your own logic if needed
350
+ * @param {Ext.Component} form The rendered Edit form
351
+ * @param {ExtMVC.model.Base} instance The instance loaded into the form
352
+ */
353
+ onEdit: function(form) {},
354
+
355
+ /**
356
+ * Sets up events emitted by the CRUD Controller's actions
357
+ */
358
+ initEvents: function() {
359
+ this.addEvents(
360
+ /**
361
+ * @event create
362
+ * Fired when a new instance has been successfully created
363
+ * @param {ExtMVC.model.Base} instance The newly created model instance
364
+ */
365
+ 'create',
366
+
367
+ /**
368
+ * @event create-failed
369
+ * Fired when an attempt to create a new instance failed
370
+ * @param {ExtMVC.model.Base} instance The instance object which couldn't be saved
371
+ */
372
+ 'create-failed',
373
+
374
+ /**
375
+ * @event read
376
+ * Fired when a single instance has been loaded from the database
377
+ * @param {ExtMVC.model.Base} instance The instance instance that was loaded
378
+ */
379
+ 'read',
380
+
381
+ /**
382
+ * @event read-failed
383
+ * Fired when an attempt to load a single instance failed
384
+ * @param {Number} id The ID of the instance we were attempting to find
385
+ */
386
+ 'read-failed',
387
+
388
+ /**
389
+ * @event update
390
+ * Fired when an existing instance has been successfully created
391
+ * @param {ExtMVC.model.Base} instance The updated instance
392
+ * @param {Object} updates The updates object that was supplied
393
+ */
394
+ 'update',
395
+
396
+ /**
397
+ * @event update-failed
398
+ * Fired when an attempty to update an existing instance failed
399
+ * @param {ExtMVC.model.Base} instance The instance we were attempting to update
400
+ * @param {Object} updates The object of updates we were trying to apply
401
+ */
402
+ 'update-failed',
403
+
404
+ /**
405
+ * @event delete
406
+ * Fired when an existing instance has been successfully deleteed
407
+ * @param {ExtMVC.model.Base} instance The instance that was deleteed
408
+ */
409
+ 'delete',
410
+
411
+ /**
412
+ * @event delete-failed
413
+ * Fired when an attempt to delete an existing instance failed
414
+ * @param {ExtMVC.model.Base} instance The instance we were trying to delete
415
+ */
416
+ 'delete-failed',
417
+
418
+ /**
419
+ * @event index
420
+ * Fired when an instances collection has been loaded from the database
421
+ */
422
+ 'index',
423
+
424
+ /**
425
+ * @event edit
426
+ * Fired when an instance is being edited
427
+ * @param {ExtMVC.model.Base} instance The instance being edited
428
+ */
429
+ 'edit'
430
+ );
431
+ },
432
+
433
+ /**
434
+ * If a view of the given viewName is defined in this controllers viewPackage, a reference to its
435
+ * constructor is defined. If not, a reference to the default scaffold for the viewName is returned
436
+ * @param {String} namespace The view namesapce
437
+ * @param {String} name The name of the view to return a constructor function for
438
+ * @return {Function} A reference to the custom view, or the scaffold fallback
439
+ */
440
+ getView: function getView(namespace, name) {
441
+ var view;
442
+
443
+ try {
444
+ view = ExtMVC.getController("controller").getView.apply(this, arguments);
445
+ } catch(e) {
446
+ view = this.scaffoldViewName(name);
447
+ }
448
+
449
+ return view;
450
+ },
451
+
452
+ /**
453
+ * Returns a reference to the Scaffold view class for a given viewName
454
+ * @param {String} viewName The name of the view to return a class for (index, new, edit or show)
455
+ * @return {Function} A reference to the view class to instantiate to render this scaffold view
456
+ */
457
+ scaffoldViewName: function scaffoldViewName(viewName) {
458
+ return ExtMVC.getView('scaffold', viewName);
459
+ }
460
+ });