author | Giulio Cesare Solaroli <giulio.cesare@clipperz.com> | 2011-10-02 23:56:18 (UTC) |
---|---|---|
committer | Giulio Cesare Solaroli <giulio.cesare@clipperz.com> | 2011-10-02 23:56:18 (UTC) |
commit | ef68436ac04da078ffdcacd7e1f785473a303d45 (patch) (unidiff) | |
tree | c403752d66a2c4775f00affd4fa8431b29c5b68c /frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/GridController.js | |
parent | 597ecfbc0249d83e1b856cbd558340c01237a360 (diff) | |
download | clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.zip clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.gz clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.bz2 |
First version of the newly restructured repository
Diffstat (limited to 'frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/GridController.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/GridController.js | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/GridController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/GridController.js new file mode 100644 index 0000000..740a091 --- a/dev/null +++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/GridController.js | |||
@@ -0,0 +1,374 @@ | |||
1 | /* | ||
2 | |||
3 | Copyright 2008-2011 Clipperz Srl | ||
4 | |||
5 | This file is part of Clipperz's Javascript Crypto Library. | ||
6 | Javascript Crypto Library provides web developers with an extensive | ||
7 | and efficient set of cryptographic functions. The library aims to | ||
8 | obtain maximum execution speed while preserving modularity and | ||
9 | reusability. | ||
10 | For further information about its features and functionalities please | ||
11 | refer to http://www.clipperz.com | ||
12 | |||
13 | * Javascript Crypto Library is free software: you can redistribute | ||
14 | it and/or modify it under the terms of the GNU Affero General Public | ||
15 | License as published by the Free Software Foundation, either version | ||
16 | 3 of the License, or (at your option) any later version. | ||
17 | |||
18 | * Javascript Crypto Library is distributed in the hope that it will | ||
19 | be useful, but WITHOUT ANY WARRANTY; without even the implied | ||
20 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
21 | See the GNU Affero General Public License for more details. | ||
22 | |||
23 | * You should have received a copy of the GNU Affero General Public | ||
24 | License along with Javascript Crypto Library. If not, see | ||
25 | <http://www.gnu.org/licenses/>. | ||
26 | |||
27 | */ | ||
28 | |||
29 | Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers'); | ||
30 | |||
31 | Clipperz.PM.UI.Web.Controllers.GridController = function(args) { | ||
32 | args = args || {}; | ||
33 | |||
34 | Clipperz.PM.UI.Web.Controllers.GridController.superclass.constructor.call(this, args); | ||
35 | |||
36 | this._grid = null; | ||
37 | this._user = null; | ||
38 | this._sortedColumnManager = null; | ||
39 | this._cachedObjects = null; | ||
40 | this._filterController = args.filterController || null; | ||
41 | |||
42 | this._deferredDisplaySelectedRowsInvocation = null; | ||
43 | |||
44 | return this; | ||
45 | }; | ||
46 | |||
47 | Clipperz.Base.extend(Clipperz.PM.UI.Web.Controllers.GridController, Object, { | ||
48 | |||
49 | 'toString': function() { | ||
50 | return "Clipperz.PM.UI.Web.Controllers.GridController"; | ||
51 | }, | ||
52 | |||
53 | //----------------------------------------------------------------------------- | ||
54 | |||
55 | 'createGrid': function () { | ||
56 | throw Clipperz.Base.exception.AbstractMethod; | ||
57 | }, | ||
58 | |||
59 | 'setupWithGrid': function (aGrid) { | ||
60 | this._grid = aGrid; | ||
61 | |||
62 | if (this._grid != null) { | ||
63 | MochiKit.Iter.forEach(this.columnsManagers(), function (aColumnManager) { | ||
64 | if (aColumnManager.isSortable()) { | ||
65 | if (aColumnManager.isSorted()) { | ||
66 | this.setSortedColumnManager(aColumnManager); | ||
67 | } | ||
68 | MochiKit.Signal.connect(aColumnManager, 'sort', this, 'handleColumnManagerSort'); | ||
69 | } | ||
70 | MochiKit.Signal.connect(aColumnManager, 'selectRow', this, 'handleColumnManagerSelectRow'); | ||
71 | MochiKit.Signal.connect(aColumnManager, 'unselectRow', this, 'handleColumnManagerUnselectRow'); | ||
72 | }, this); | ||
73 | } | ||
74 | }, | ||
75 | |||
76 | 'grid': function() { | ||
77 | if (this._grid == null) { | ||
78 | this.setupWithGrid(this.createGrid()); | ||
79 | } | ||
80 | |||
81 | return this._grid; | ||
82 | }, | ||
83 | |||
84 | 'filterController': function () { | ||
85 | //Clipperz.log('GridController.filterController >>>', this._filterController); | ||
86 | if (this._filterController == null) { | ||
87 | this._filterController = new Clipperz.PM.UI.Web.Controllers.FilterController(); | ||
88 | } | ||
89 | //Clipperz.log('GridController.filterController <<<', this._filterController); | ||
90 | return this._filterController; | ||
91 | }, | ||
92 | |||
93 | //----------------------------------------------------------------------------- | ||
94 | |||
95 | 'columnsManagers': function () { | ||
96 | return this.grid().columnsManagers(); | ||
97 | }, | ||
98 | |||
99 | 'columnManagerWithName': function (aName) { | ||
100 | varmanagers; | ||
101 | var result; | ||
102 | |||
103 | managers = MochiKit.Base.filter(function (aManager) { return aManager.name() == aName; } , this.columnsManagers()); | ||
104 | |||
105 | if (managers.length == 1) { | ||
106 | result = managers[0]; | ||
107 | } else if (managers.length == 0) { | ||
108 | result = null; | ||
109 | } else { | ||
110 | throw "WTF!!!"; | ||
111 | } | ||
112 | |||
113 | return result; | ||
114 | }, | ||
115 | |||
116 | 'sortedColumnManager': function () { | ||
117 | return this._sortedColumnManager; | ||
118 | }, | ||
119 | |||
120 | 'setSortedColumnManager': function(aValue) { | ||
121 | if (aValue.sorted() != 'UNSORTED') { | ||
122 | this._sortedColumnManager = aValue; | ||
123 | } else { | ||
124 | this._sortedColumnManager = null; | ||
125 | } | ||
126 | }, | ||
127 | |||
128 | //----------------------------------------------------------------------------- | ||
129 | |||
130 | 'handleColumnManagerSort': function(aSelectedColumnManager) { | ||
131 | MochiKit.Iter.forEach(this.columnsManagers(), function(aColumnManager) { | ||
132 | if (aSelectedColumnManager != aColumnManager) { | ||
133 | if (aColumnManager.isSortable()) { | ||
134 | aColumnManager.setSorted('UNSORTED'); | ||
135 | } | ||
136 | } | ||
137 | }); | ||
138 | |||
139 | aSelectedColumnManager.toggleSorting(); | ||
140 | this.setSortedColumnManager(aSelectedColumnManager); | ||
141 | |||
142 | this.displaySelectedRows(this.filterController().getFilter()); | ||
143 | }, | ||
144 | |||
145 | 'handleColumnManagerSelectRow': function (aRowObject) { | ||
146 | this.grid().selectRow(aRowObject); | ||
147 | }, | ||
148 | |||
149 | 'handleColumnManagerUnselectRow': function (aRowObject) { | ||
150 | this.grid().unselectRow(aRowObject); | ||
151 | }, | ||
152 | |||
153 | //----------------------------------------------------------------------------- | ||
154 | |||
155 | 'handleFilterUpdated': function (aFilter) { | ||
156 | if (this.grid().isActive()) { | ||
157 | this.displaySelectedRows(aFilter); | ||
158 | } | ||
159 | }, | ||
160 | |||
161 | //----------------------------------------------------------------------------- | ||
162 | //TODO: relying on user() in GridController, bad code smell :| | ||
163 | //mhh: a controller should have access to business logic object too. Otherwise it will fail its controller role. [Giulio Cesare] | ||
164 | |||
165 | 'setUser': function(anUser) { | ||
166 | this._user = anUser; | ||
167 | }, | ||
168 | |||
169 | 'user': function() { | ||
170 | return this._user; | ||
171 | }, | ||
172 | |||
173 | //----------------------------------------------------------------------------- | ||
174 | |||
175 | 'run': function(args) { | ||
176 | //Clipperz.log("=== GridController.run"); | ||
177 | var deferredResult; | ||
178 | |||
179 | this.setUser(args.user); | ||
180 | args.slot.setContent(this.grid()); | ||
181 | this.filterController().registerFilterElement(this.grid().filterElement()); | ||
182 | MochiKit.Signal.connect(this.filterController(), 'filterUpdated', this, 'handleFilterUpdated'); | ||
183 | |||
184 | return this.displaySelectedRows(); | ||
185 | }, | ||
186 | |||
187 | //----------------------------------------------------------------------------- | ||
188 | |||
189 | 'handleGenericError': function(anError) { | ||
190 | var result; | ||
191 | |||
192 | if (anError instanceof MochiKit.Async.CancelledError) { | ||
193 | result = anError; | ||
194 | } else { | ||
195 | Clipperz.log("## GridController - GENERIC ERROR" + "\n" + "==>> " + anError + " <<==\n" + anError.stack); | ||
196 | result = new MochiKit.Async.CancelledError(anError); | ||
197 | } | ||
198 | |||
199 | return result; | ||
200 | }, | ||
201 | |||
202 | //----------------------------------------------------------------------------- | ||
203 | |||
204 | 'getRows': function () { | ||
205 | throw Clipperz.Base.AbstractMethod; | ||
206 | }, | ||
207 | |||
208 | //----------------------------------------------------------------------------- | ||
209 | |||
210 | 'setDeferredDisplaySelectedRowsInvocation': function (aDeferred) { | ||
211 | if (this._deferredDisplaySelectedRowsInvocation != null) { | ||
212 | this._deferredDisplaySelectedRowsInvocation.cancel(); | ||
213 | } | ||
214 | |||
215 | this._deferredDisplaySelectedRowsInvocation = aDeferred; | ||
216 | }, | ||
217 | |||
218 | //----------------------------------------------------------------------------- | ||
219 | |||
220 | 'resetDeferredDisplaySelectedRowsInvocation': function () { | ||
221 | if (this._deferredDisplaySelectedRowsInvocation != null) { | ||
222 | this._deferredDisplaySelectedRowsInvocation.cancel(); | ||
223 | } | ||
224 | }, | ||
225 | |||
226 | //----------------------------------------------------------------------------- | ||
227 | |||
228 | '_displaySelectedRows': function (aFilter, someRows) { | ||
229 | var result; | ||
230 | var delay; | ||
231 | |||
232 | if ((aFilter != null) && (aFilter != '')) { | ||
233 | var filter; | ||
234 | varfilterRegExp; | ||
235 | |||
236 | filter = aFilter.replace(/[^A-Za-z0-9]/g, "\\$&"); | ||
237 | filterRegExp = new RegExp(filter, "i"); | ||
238 | result = MochiKit.Base.filter(function (aCachedResult) { return filterRegExp.test(aCachedResult['_searchableContent'])}, someRows); | ||
239 | delay = 0.002*result.length; | ||
240 | |||
241 | this.setDeferredDisplaySelectedRowsInvocation(MochiKit.Async.callLater(delay, MochiKit.Base.method(this, "deferredDisplaySelectedRows", result))); | ||
242 | } else { | ||
243 | result = someRows; | ||
244 | |||
245 | this.resetDeferredDisplaySelectedRowsInvocation(); | ||
246 | this.deferredDisplaySelectedRows(result); | ||
247 | } | ||
248 | |||
249 | }, | ||
250 | |||
251 | //----------------------------------------------------------------------------- | ||
252 | |||
253 | 'deferredDisplaySelectedRows': function (someRows) { | ||
254 | if (this.sortedColumnManager() != null) { | ||
255 | var comparator; | ||
256 | var fieldName; | ||
257 | |||
258 | fieldName = this.sortedColumnManager().name(); | ||
259 | comparator = this.sortedColumnManager().comparator(); | ||
260 | if (this.sortedColumnManager().sorted() == 'DESCENDING') { | ||
261 | comparator = Clipperz.Base.reverseComparator(comparator); | ||
262 | } | ||
263 | |||
264 | someRows.sort(MochiKit.Base.partial(function(aKey, aComparator, aObject, bObject){ | ||
265 | return comparator(aObject[aKey], bObject[aKey]); | ||
266 | }, this.sortedColumnManager().name(), comparator)); | ||
267 | } | ||
268 | |||
269 | this.grid().update(someRows); | ||
270 | this.grid().endSearch(); | ||
271 | }, | ||
272 | |||
273 | //----------------------------------------------------------------------------- | ||
274 | |||
275 | 'getCachedValues': function () { | ||
276 | var deferredResult; | ||
277 | |||
278 | if (this._cachedObjects != null) { | ||
279 | deferredResult = MochiKit.Async.succeed(this._cachedObjects); | ||
280 | } else { | ||
281 | var objectCollectResultsConfiguration; | ||
282 | |||
283 | objectCollectResultsConfiguration = { | ||
284 | '_rowObject': MochiKit.Async.succeed, | ||
285 | '_reference': MochiKit.Base.methodcaller('reference'), | ||
286 | '_searchableContent':MochiKit.Base.methodcaller('searchableContent') | ||
287 | }; | ||
288 | |||
289 | MochiKit.Base.map(function (aColumnManager) { | ||
290 | objectCollectResultsConfiguration[aColumnManager.name()] = aColumnManager.selector(); | ||
291 | }, this.columnsManagers()); | ||
292 | |||
293 | deferredResult = new Clipperz.Async.Deferred("GridController.getCachedValues", {trace:false}); | ||
294 | deferredResult.addMethod(this, 'getRows'); | ||
295 | deferredResult.addCallback(MochiKit.Base.map, Clipperz.Async.collectResults("GridController.getCachedValues - collectResults", objectCollectResultsConfiguration, {trace:false})); | ||
296 | deferredResult.addCallback(Clipperz.Async.collectAll); | ||
297 | deferredResult.addCallback(MochiKit.Base.bind(function (someRows) { | ||
298 | this._cachedObjects = someRows; | ||
299 | return this._cachedObjects; | ||
300 | }, this)); | ||
301 | deferredResult.callback(); | ||
302 | } | ||
303 | |||
304 | return deferredResult; | ||
305 | }, | ||
306 | |||
307 | //----------------------------------------------------------------------------- | ||
308 | |||
309 | 'hasPendingChanges': function () { | ||
310 | return this.user().hasPendingChanges(); | ||
311 | }, | ||
312 | |||
313 | 'saveChanges': function () { | ||
314 | this._cachedObjects = null; | ||
315 | |||
316 | return Clipperz.Async.callbacks("GridController.saveChanges", [ | ||
317 | MochiKit.Base.method(this.user(), 'saveChanges'), | ||
318 | MochiKit.Base.method(this, 'focus') | ||
319 | ], {trace:false}); | ||
320 | }, | ||
321 | |||
322 | 'revertChanges': function () { | ||
323 | return this.user().revertChanges(); | ||
324 | }, | ||
325 | |||
326 | //----------------------------------------------------------------------------- | ||
327 | |||
328 | 'displayEmptyContent': function () { | ||
329 | }, | ||
330 | |||
331 | 'hideEmptyContent': function () { | ||
332 | this.grid().removeNoRowsGridComponent(); | ||
333 | }, | ||
334 | |||
335 | 'displaySelectedRows': function (aFilter) { | ||
336 | if ((aFilter != null) && (aFilter != '')){ | ||
337 | this.grid().startSearch(); | ||
338 | } | ||
339 | |||
340 | return Clipperz.Async.callbacks("GridController.displaySelectedrows", [ | ||
341 | MochiKit.Base.method(this, 'getCachedValues'), | ||
342 | MochiKit.Base.itemgetter('length'), | ||
343 | Clipperz.Async.deferredIf("There are some items to show in the grid", [ | ||
344 | MochiKit.Base.method(this, 'hideEmptyContent'), | ||
345 | MochiKit.Base.method(this, 'getCachedValues'), | ||
346 | MochiKit.Base.method(this, '_displaySelectedRows', aFilter) | ||
347 | ], [ | ||
348 | MochiKit.Base.method(this, 'displayEmptyContent'), | ||
349 | MochiKit.Base.method(this.grid(), 'endSearch') | ||
350 | ]) | ||
351 | ], {trace:false}); | ||
352 | }, | ||
353 | |||
354 | //----------------------------------------------------------------------------- | ||
355 | |||
356 | 'focus': function () { | ||
357 | return Clipperz.Async.callbacks("GridController.focus", [ | ||
358 | MochiKit.Base.method(this, 'displaySelectedRows', this.filterController().getFilter()), | ||
359 | MochiKit.Base.method(this.grid(), 'focus') | ||
360 | ], {trace:false}) | ||
361 | //*##*/this.displaySelectedRows(this.filterController().getFilter()); | ||
362 | // this.grid().focus(); | ||
363 | }, | ||
364 | |||
365 | //============================================================================= | ||
366 | |||
367 | 'deleteAllCleanTextData': function () { | ||
368 | this._cachedObjects = null; | ||
369 | this.grid().drawEmpty(); | ||
370 | }, | ||
371 | |||
372 | //============================================================================= | ||
373 | __syntaxFix__: "syntax fix" | ||
374 | }); | ||