summaryrefslogtreecommitdiff
path: root/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/GridController.js
Unidiff
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.js374
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
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer 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
29Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
30
31Clipperz.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
47Clipperz.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 {
195Clipperz.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});