summaryrefslogtreecommitdiff
path: root/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/GridController.js
Side-by-side diff
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 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.GridController = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Controllers.GridController.superclass.constructor.call(this, args);
+
+ this._grid = null;
+ this._user = null;
+ this._sortedColumnManager = null;
+ this._cachedObjects = null;
+ this._filterController = args.filterController || null;
+
+ this._deferredDisplaySelectedRowsInvocation = null;
+
+ return this;
+};
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Controllers.GridController, Object, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.GridController";
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'createGrid': function () {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ 'setupWithGrid': function (aGrid) {
+ this._grid = aGrid;
+
+ if (this._grid != null) {
+ MochiKit.Iter.forEach(this.columnsManagers(), function (aColumnManager) {
+ if (aColumnManager.isSortable()) {
+ if (aColumnManager.isSorted()) {
+ this.setSortedColumnManager(aColumnManager);
+ }
+ MochiKit.Signal.connect(aColumnManager, 'sort', this, 'handleColumnManagerSort');
+ }
+ MochiKit.Signal.connect(aColumnManager, 'selectRow', this, 'handleColumnManagerSelectRow');
+ MochiKit.Signal.connect(aColumnManager, 'unselectRow', this, 'handleColumnManagerUnselectRow');
+ }, this);
+ }
+ },
+
+ 'grid': function() {
+ if (this._grid == null) {
+ this.setupWithGrid(this.createGrid());
+ }
+
+ return this._grid;
+ },
+
+ 'filterController': function () {
+//Clipperz.log('GridController.filterController >>>', this._filterController);
+ if (this._filterController == null) {
+ this._filterController = new Clipperz.PM.UI.Web.Controllers.FilterController();
+ }
+//Clipperz.log('GridController.filterController <<<', this._filterController);
+ return this._filterController;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'columnsManagers': function () {
+ return this.grid().columnsManagers();
+ },
+
+ 'columnManagerWithName': function (aName) {
+ var managers;
+ var result;
+
+ managers = MochiKit.Base.filter(function (aManager) { return aManager.name() == aName; } , this.columnsManagers());
+
+ if (managers.length == 1) {
+ result = managers[0];
+ } else if (managers.length == 0) {
+ result = null;
+ } else {
+ throw "WTF!!!";
+ }
+
+ return result;
+ },
+
+ 'sortedColumnManager': function () {
+ return this._sortedColumnManager;
+ },
+
+ 'setSortedColumnManager': function(aValue) {
+ if (aValue.sorted() != 'UNSORTED') {
+ this._sortedColumnManager = aValue;
+ } else {
+ this._sortedColumnManager = null;
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleColumnManagerSort': function(aSelectedColumnManager) {
+ MochiKit.Iter.forEach(this.columnsManagers(), function(aColumnManager) {
+ if (aSelectedColumnManager != aColumnManager) {
+ if (aColumnManager.isSortable()) {
+ aColumnManager.setSorted('UNSORTED');
+ }
+ }
+ });
+
+ aSelectedColumnManager.toggleSorting();
+ this.setSortedColumnManager(aSelectedColumnManager);
+
+ this.displaySelectedRows(this.filterController().getFilter());
+ },
+
+ 'handleColumnManagerSelectRow': function (aRowObject) {
+ this.grid().selectRow(aRowObject);
+ },
+
+ 'handleColumnManagerUnselectRow': function (aRowObject) {
+ this.grid().unselectRow(aRowObject);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleFilterUpdated': function (aFilter) {
+ if (this.grid().isActive()) {
+ this.displaySelectedRows(aFilter);
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+ // TODO: relying on user() in GridController, bad code smell :|
+ // mhh: a controller should have access to business logic object too. Otherwise it will fail its controller role. [Giulio Cesare]
+
+ 'setUser': function(anUser) {
+ this._user = anUser;
+ },
+
+ 'user': function() {
+ return this._user;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'run': function(args) {
+//Clipperz.log("=== GridController.run");
+ var deferredResult;
+
+ this.setUser(args.user);
+ args.slot.setContent(this.grid());
+ this.filterController().registerFilterElement(this.grid().filterElement());
+ MochiKit.Signal.connect(this.filterController(), 'filterUpdated', this, 'handleFilterUpdated');
+
+ return this.displaySelectedRows();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleGenericError': function(anError) {
+ var result;
+
+ if (anError instanceof MochiKit.Async.CancelledError) {
+ result = anError;
+ } else {
+Clipperz.log("## GridController - GENERIC ERROR" + "\n" + "==>> " + anError + " <<==\n" + anError.stack);
+ result = new MochiKit.Async.CancelledError(anError);
+ }
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'getRows': function () {
+ throw Clipperz.Base.AbstractMethod;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'setDeferredDisplaySelectedRowsInvocation': function (aDeferred) {
+ if (this._deferredDisplaySelectedRowsInvocation != null) {
+ this._deferredDisplaySelectedRowsInvocation.cancel();
+ }
+
+ this._deferredDisplaySelectedRowsInvocation = aDeferred;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'resetDeferredDisplaySelectedRowsInvocation': function () {
+ if (this._deferredDisplaySelectedRowsInvocation != null) {
+ this._deferredDisplaySelectedRowsInvocation.cancel();
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+
+ '_displaySelectedRows': function (aFilter, someRows) {
+ var result;
+ var delay;
+
+ if ((aFilter != null) && (aFilter != '')) {
+ var filter;
+ var filterRegExp;
+
+ filter = aFilter.replace(/[^A-Za-z0-9]/g, "\\$&");
+ filterRegExp = new RegExp(filter, "i");
+ result = MochiKit.Base.filter(function (aCachedResult) { return filterRegExp.test(aCachedResult['_searchableContent'])}, someRows);
+ delay = 0.002*result.length;
+
+ this.setDeferredDisplaySelectedRowsInvocation(MochiKit.Async.callLater(delay, MochiKit.Base.method(this, "deferredDisplaySelectedRows", result)));
+ } else {
+ result = someRows;
+
+ this.resetDeferredDisplaySelectedRowsInvocation();
+ this.deferredDisplaySelectedRows(result);
+ }
+
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'deferredDisplaySelectedRows': function (someRows) {
+ if (this.sortedColumnManager() != null) {
+ var comparator;
+ var fieldName;
+
+ fieldName = this.sortedColumnManager().name();
+ comparator = this.sortedColumnManager().comparator();
+ if (this.sortedColumnManager().sorted() == 'DESCENDING') {
+ comparator = Clipperz.Base.reverseComparator(comparator);
+ }
+
+ someRows.sort(MochiKit.Base.partial(function(aKey, aComparator, aObject, bObject){
+ return comparator(aObject[aKey], bObject[aKey]);
+ }, this.sortedColumnManager().name(), comparator));
+ }
+
+ this.grid().update(someRows);
+ this.grid().endSearch();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'getCachedValues': function () {
+ var deferredResult;
+
+ if (this._cachedObjects != null) {
+ deferredResult = MochiKit.Async.succeed(this._cachedObjects);
+ } else {
+ var objectCollectResultsConfiguration;
+
+ objectCollectResultsConfiguration = {
+ '_rowObject': MochiKit.Async.succeed,
+ '_reference': MochiKit.Base.methodcaller('reference'),
+ '_searchableContent': MochiKit.Base.methodcaller('searchableContent')
+ };
+
+ MochiKit.Base.map(function (aColumnManager) {
+ objectCollectResultsConfiguration[aColumnManager.name()] = aColumnManager.selector();
+ }, this.columnsManagers());
+
+ deferredResult = new Clipperz.Async.Deferred("GridController.getCachedValues", {trace:false});
+ deferredResult.addMethod(this, 'getRows');
+ deferredResult.addCallback(MochiKit.Base.map, Clipperz.Async.collectResults("GridController.getCachedValues - collectResults", objectCollectResultsConfiguration, {trace:false}));
+ deferredResult.addCallback(Clipperz.Async.collectAll);
+ deferredResult.addCallback(MochiKit.Base.bind(function (someRows) {
+ this._cachedObjects = someRows;
+ return this._cachedObjects;
+ }, this));
+ deferredResult.callback();
+ }
+
+ return deferredResult;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'hasPendingChanges': function () {
+ return this.user().hasPendingChanges();
+ },
+
+ 'saveChanges': function () {
+ this._cachedObjects = null;
+
+ return Clipperz.Async.callbacks("GridController.saveChanges", [
+ MochiKit.Base.method(this.user(), 'saveChanges'),
+ MochiKit.Base.method(this, 'focus')
+ ], {trace:false});
+ },
+
+ 'revertChanges': function () {
+ return this.user().revertChanges();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'displayEmptyContent': function () {
+ },
+
+ 'hideEmptyContent': function () {
+ this.grid().removeNoRowsGridComponent();
+ },
+
+ 'displaySelectedRows': function (aFilter) {
+ if ((aFilter != null) && (aFilter != '')){
+ this.grid().startSearch();
+ }
+
+ return Clipperz.Async.callbacks("GridController.displaySelectedrows", [
+ MochiKit.Base.method(this, 'getCachedValues'),
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.deferredIf("There are some items to show in the grid", [
+ MochiKit.Base.method(this, 'hideEmptyContent'),
+ MochiKit.Base.method(this, 'getCachedValues'),
+ MochiKit.Base.method(this, '_displaySelectedRows', aFilter)
+ ], [
+ MochiKit.Base.method(this, 'displayEmptyContent'),
+ MochiKit.Base.method(this.grid(), 'endSearch')
+ ])
+ ], {trace:false});
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'focus': function () {
+ return Clipperz.Async.callbacks("GridController.focus", [
+ MochiKit.Base.method(this, 'displaySelectedRows', this.filterController().getFilter()),
+ MochiKit.Base.method(this.grid(), 'focus')
+ ], {trace:false})
+//*##*/ this.displaySelectedRows(this.filterController().getFilter());
+// this.grid().focus();
+ },
+
+ //=============================================================================
+
+ 'deleteAllCleanTextData': function () {
+ this._cachedObjects = null;
+ this.grid().drawEmpty();
+ },
+
+ //=============================================================================
+ __syntaxFix__: "syntax fix"
+});