Get nextmatch rendering, sort of

This commit is contained in:
nathangray 2020-01-31 13:07:27 -07:00
parent 4eca12001a
commit 3f8bd1b494
33 changed files with 7070 additions and 3795 deletions

View File

@ -416,4 +416,5 @@ function et2_arrayMgrs_expand(_owner, _mgrs, _data, _row) {
// Return the resulting managers object
return result;
}
exports.et2_arrayMgrs_expand = et2_arrayMgrs_expand;
//# sourceMappingURL=et2_core_arrayMgr.js.map

View File

@ -432,7 +432,7 @@ export class et2_readonlysArrayMgr extends et2_arrayMgr {
* existing array managers.
* @param _row is the row for which the array managers will be opened.
*/
function et2_arrayMgrs_expand(_owner: et2_widget, _mgrs: object, _data: object, _row: number) {
export function et2_arrayMgrs_expand(_owner: et2_widget, _mgrs: object, _data: object, _row: number) {
// Create a copy of the given _mgrs associative array
let result = {};

View File

@ -9,19 +9,22 @@
* @author Andreas Stöckel
* @copyright Stylite 2011-2012
* @version $Id$
*/
Object.defineProperty(exports, "__esModule", { value: true });
*
/*egw:uses
/vendor/bower-asset/jquery/dist/jquery.js;
et2_core_common;
et2_dataview_model_columns;
et2_dataview_view_rowProvider;
et2_dataview_view_grid;
et2_dataview_view_rowProvider;
et2_dataview_view_resizeable;
*/
Object.defineProperty(exports, "__esModule", { value: true });
var et2_dataview_model_columns_1 = require("./et2_dataview_model_columns");
var et2_dataview_view_resizeable_1 = require("./et2_dataview_view_resizeable");
var et2_dataview_view_grid_1 = require("./et2_dataview_view_grid");
var et2_dataview_view_rowProvider_1 = require("./et2_dataview_view_rowProvider");
/**
* The et2_dataview class is the main class for displaying a dataview. The
* dataview class manages the creation of the outer html nodes (like the table,
@ -64,11 +67,11 @@ var et2_dataview = /** @class */ (function () {
this._clearHeader();
// Free the grid
if (this.grid) {
this.grid.free();
this.grid.destroy();
}
// Free the row provider
if (this.rowProvider) {
this.rowProvider.free();
this.rowProvider.destroy();
}
// Detatch the outer element
this.table.remove();
@ -323,13 +326,13 @@ var et2_dataview = /** @class */ (function () {
if (this.relativeWidth) {
// Set to selected width
this.set_width(_w + "px");
self.columnMgr.updated = true;
self.columnMgr.updated();
// Just triggers recalculation
self.columnMgr.getColumnWidth(0);
// Set relative widths to match
var relative = self.columnMgr.totalWidth - self.columnMgr.totalFixed + _w;
this.set_width(_w / relative);
for (var i = 0; i < self.columnMgr.columns.length; i++) {
for (var i = 0; i < self.columnMgr.columnCount(); i++) {
var col = self.columnMgr.getColumnById(i);
if (col == this || col.fixedWidth)
continue;
@ -340,7 +343,7 @@ var et2_dataview = /** @class */ (function () {
}
else {
this.set_width(this.relativeWidth ? (_w / self.columnMgr.totalWidth) : _w + "px");
self.columnMgr.updated = true;
self.columnMgr.updated();
self.updateColumns();
}
}, enc_column);
@ -383,13 +386,13 @@ var et2_dataview = /** @class */ (function () {
}
// Create the row provider
if (this.rowProvider) {
this.rowProvider.free();
this.rowProvider.destroy();
}
this.rowProvider = new et2_dataview_rowProvider(this.uniqueId, colIds);
this.rowProvider = new et2_dataview_view_rowProvider_1.et2_dataview_rowProvider(this.uniqueId, colIds);
// Create the grid class and pass "19" as the starting average row height
this.grid = new et2_dataview_grid(null, null, this.egw, this.rowProvider, 19);
this.grid = new et2_dataview_view_grid_1.et2_dataview_grid(null, null, this.egw, this.rowProvider, 19);
// Insert the grid into the DOM-Tree
var tr = jQuery(this.grid._nodes[0]);
var tr = jQuery(this.grid.getFirstNode());
this.containerTr.replaceWith(tr);
this.containerTr = tr;
};

View File

@ -8,20 +8,22 @@
* @author Andreas Stöckel
* @copyright Stylite 2011-2012
* @version $Id$
*/
*
/*egw:uses
/vendor/bower-asset/jquery/dist/jquery.js;
et2_core_common;
et2_dataview_model_columns;
et2_dataview_view_rowProvider;
et2_dataview_view_grid;
et2_dataview_view_rowProvider;
et2_dataview_view_resizeable;
*/
import {et2_dataview_columns} from './et2_dataview_model_columns';
import {et2_dataview_view_resizable} from "./et2_dataview_view_resizeable";
import {et2_dataview_grid} from "./et2_dataview_view_grid";
import {et2_dataview_rowProvider} from "./et2_dataview_view_rowProvider"
/**
* The et2_dataview class is the main class for displaying a dataview. The
@ -122,13 +124,13 @@ export class et2_dataview
// Free the grid
if (this.grid)
{
this.grid.free();
this.grid.destroy();
}
// Free the row provider
if (this.rowProvider)
{
this.rowProvider.free();
this.rowProvider.destroy();
}
// Detatch the outer element
@ -468,14 +470,14 @@ export class et2_dataview
{
// Set to selected width
this.set_width(_w + "px");
self.columnMgr.updated = true;
self.columnMgr.updated();
// Just triggers recalculation
self.columnMgr.getColumnWidth(0);
// Set relative widths to match
var relative = self.columnMgr.totalWidth - self.columnMgr.totalFixed + _w;
this.set_width(_w / relative);
for(var i = 0; i < self.columnMgr.columns.length; i++)
for(var i = 0; i < self.columnMgr.columnCount(); i++)
{
var col = self.columnMgr.getColumnById(i);
if(col == this || col.fixedWidth) continue;
@ -487,7 +489,7 @@ export class et2_dataview
else
{
this.set_width(this.relativeWidth ? (_w / self.columnMgr.totalWidth) : _w + "px");
self.columnMgr.updated = true;
self.columnMgr.updated();
self.updateColumns();
}
@ -541,7 +543,7 @@ export class et2_dataview
// Create the row provider
if (this.rowProvider)
{
this.rowProvider.free();
this.rowProvider.destroy();
}
this.rowProvider = new et2_dataview_rowProvider(this.uniqueId, colIds);
@ -550,7 +552,7 @@ export class et2_dataview
this.grid = new et2_dataview_grid(null, null, this.egw, this.rowProvider, 19);
// Insert the grid into the DOM-Tree
var tr = jQuery(this.grid._nodes[0]);
var tr = jQuery(this.grid.getFirstNode());
this.containerTr.replaceWith(tr);
this.containerTr = tr;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,4 @@
"use strict";
/**
* EGroupware eTemplate2
*
@ -7,15 +8,14 @@
* @link http://www.egroupware.org
* @author Andreas Stöckel
* @copyright Stylite 2011-2012
* @version $Id$
*/
*
/*egw:uses
et2_dataview_view_aoi;
egw_action.egw_keymanager;
*/
Object.defineProperty(exports, "__esModule", { value: true });
/**
* The selectioManager is internally used by the et2_dataview_controller class
* to manage the row selection.
@ -27,13 +27,7 @@
*
* @augments Class
*/
var et2_dataview_selectionManager = (function(){ "use strict"; return Class.extend(
{
// Maximum number of rows we can safely fetch for selection
// Actual selection may have more rows if we already have some
MAX_SELECTION: 1000,
var et2_dataview_selectionManager = /** @class */ (function () {
/**
* Constructor
*
@ -45,9 +39,7 @@ var et2_dataview_selectionManager = (function(){ "use strict"; return Class.exte
* @param _context
* @memberOf et2_dataview_selectionManager
*/
init: function (_parent, _indexMap, _actionObjectManager,
_queryRangeCallback, _makeVisibleCallback, _context) {
function et2_dataview_selectionManager(_parent, _indexMap, _actionObjectManager, _queryRangeCallback, _makeVisibleCallback, _context) {
// Copy the arguments
this._parent = _parent;
this._indexMap = _indexMap;
@ -55,21 +47,14 @@ var et2_dataview_selectionManager = (function(){ "use strict"; return Class.exte
this._queryRangeCallback = _queryRangeCallback;
this._makeVisibleCallback = _makeVisibleCallback;
this._context = _context;
// Attach this manager to the parent manager if one is given
if (this._parent)
{
if (this._parent) {
this._parent._children.push(this);
}
// Use our selection instead of object manager's to handle not-loaded rows
if(_actionObjectManager)
{
this._actionObjectManager.getAllSelected = jQuery.proxy(
this.getAllSelected, this
);
if (_actionObjectManager) {
this._actionObjectManager.getAllSelected = jQuery.proxy(this.getAllSelected, this);
}
// Internal map which contains all curently selected uids and their
// state
this._registeredRows = {};
@ -79,42 +64,31 @@ var et2_dataview_selectionManager = (function(){ "use strict"; return Class.exte
this._inUpdate = false;
this._total = 0;
this._children = [];
// Callback for when the selection changes
this.select_callback = null;
},
destroy: function () {
}
et2_dataview_selectionManager.prototype.destroy = function () {
// If we have a parent, unregister from that
if (this._parent)
{
if (this._parent) {
var idx = this._parent._children.indexOf(this);
this._parent._children.splice(idx, 1);
}
// Destroy all children
for (var i = this._children.length - 1; i >= 0; i--)
{
this._children[i].free();
for (var i = this._children.length - 1; i >= 0; i--) {
this._children[i].destroy();
}
// Delete all still registered rows
for (var key in this._registeredRows)
{
for (var key in this._registeredRows) {
this.unregisterRow(key, this._registeredRows[key].tr);
}
this.select_callback = null;
},
clear: function() {
for (var key in this._registeredRows)
{
};
et2_dataview_selectionManager.prototype.clear = function () {
for (var key in this._registeredRows) {
this.unregisterRow(key, this._registeredRows[key].tr);
delete this._registeredRows[key];
}
if(this._actionObjectManager)
{
if (this._actionObjectManager) {
this._actionObjectManager.clear();
}
for (key in this._indexMap) {
@ -125,163 +99,117 @@ var et2_dataview_selectionManager = (function(){ "use strict"; return Class.exte
this._invertSelection = false;
this._selectAll = false;
this._inUpdate = false;
},
setIndexMap: function (_indexMap) {
};
et2_dataview_selectionManager.prototype.setIndexMap = function (_indexMap) {
this._indexMap = _indexMap;
},
setTotalCount: function (_total) {
};
et2_dataview_selectionManager.prototype.setTotalCount = function (_total) {
this._total = _total;
},
registerRow: function (_uid, _idx, _tr, _links) {
};
et2_dataview_selectionManager.prototype.registerRow = function (_uid, _idx, _tr, _links) {
// Get the corresponding entry from the registered rows array
var entry = this._getRegisteredRowsEntry(_uid);
// If the row has changed unregister the old one and do not delete
// entry from the entry map
if (entry.tr && entry.tr !== _tr) {
this.unregisterRow(_uid, entry.tr, true);
}
// Create the AOI for the tr
if (!entry.tr && _links)
{
if (!entry.tr && _links) {
this._attachActionObjectInterface(entry, _tr, _uid);
this._attachActionObject(entry, _tr, _uid, _links, _idx);
}
// Update the entry
if(entry.ao) entry.ao._index;
if (entry.ao)
entry.ao._index;
entry.idx = _idx;
entry.tr = _tr;
// Update the visible state of the _tr
this._updateEntryState(entry, entry.state);
},
unregisterRow: function (_uid, _tr, _noDelete) {
};
et2_dataview_selectionManager.prototype.unregisterRow = function (_uid, _tr, _noDelete) {
// _noDelete defaults to false
_noDelete = _noDelete ? true : false;
if (typeof this._registeredRows[_uid] !== "undefined"
&& this._registeredRows[_uid].tr === _tr)
{
&& this._registeredRows[_uid].tr === _tr) {
this._inUpdate = true;
this._registeredRows[_uid].tr = null;
this._registeredRows[_uid].aoi = null;
// Remove the action object from its container
if (this._registeredRows[_uid].ao)
{
if (this._registeredRows[_uid].ao) {
this._registeredRows[_uid].ao.remove();
this._registeredRows[_uid].ao = null;
}
if (!_noDelete
&& this._registeredRows[_uid].state === EGW_AO_STATE_NORMAL)
{
&& this._registeredRows[_uid].state === EGW_AO_STATE_NORMAL) {
delete this._registeredRows[_uid];
}
this._inUpdate = false;
}
},
resetSelection: function () {
};
et2_dataview_selectionManager.prototype.resetSelection = function () {
this._invertSelection = false;
this._selectAll = false;
this._actionObjectManager.setAllSelected(false);
for (var key in this._registeredRows)
{
for (var key in this._registeredRows) {
this.setSelected(key, false);
}
for(var i = 0; i < this._children.length; i++)
{
for (var i = 0; i < this._children.length; i++) {
this._children[i].resetSelection();
}
},
setSelected: function (_uid, _selected) {
};
et2_dataview_selectionManager.prototype.setSelected = function (_uid, _selected) {
this._selectAll = false;
var entry = this._getRegisteredRowsEntry(_uid);
this._updateEntryState(entry,
egwSetBit(entry.state, EGW_AO_STATE_SELECTED, _selected));
},
getAllSelected: function()
{
this._updateEntryState(entry, egwSetBit(entry.state, EGW_AO_STATE_SELECTED, _selected));
};
et2_dataview_selectionManager.prototype.getAllSelected = function () {
var selected = this.getSelected();
return selected.all || (selected.ids.length === this._total);
},
setFocused: function (_uid, _focused) {
};
et2_dataview_selectionManager.prototype.setFocused = function (_uid, _focused) {
// Reset the state of the currently focused entry
if (this._focusedEntry)
{
this._updateEntryState(this._focusedEntry,
egwSetBit(this._focusedEntry.state, EGW_AO_STATE_FOCUSED,
false));
if (this._focusedEntry) {
this._updateEntryState(this._focusedEntry, egwSetBit(this._focusedEntry.state, EGW_AO_STATE_FOCUSED, false));
this._focusedEntry = null;
}
// Mark the new given uid as focused
if (_focused)
{
if (_focused) {
//console.log('et2_dataview_controller_selection::setFocused -> UID:'+_uid+' is focused by:'+this._actionObjectManager.name);
var entry = this._focusedEntry = this._getRegisteredRowsEntry(_uid);
this._updateEntryState(entry,
egwSetBit(entry.state, EGW_AO_STATE_FOCUSED, true));
this._updateEntryState(entry, egwSetBit(entry.state, EGW_AO_STATE_FOCUSED, true));
}
},
selectAll: function () {
};
et2_dataview_selectionManager.prototype.selectAll = function () {
// Reset the selection
this.resetSelection();
this._selectAll = true;
// Run as a range if there's less then the max
if(egw.dataKnownUIDs(this._context._dataProvider.dataStorePrefix).length !== this._total &&
this._total <= this.MAX_SELECTION
)
{
if (egw.dataKnownUIDs(this._context._dataProvider.dataStorePrefix).length !== this._total &&
this._total <= et2_dataview_selectionManager.MAX_SELECTION) {
this._selectRange(0, this._total);
}
// Tell action manager to do all
this._actionObjectManager.setAllSelected(true);
// Update the selection
for (var key in this._registeredRows)
{
for (var key in this._registeredRows) {
var entry = this._registeredRows[key];
this._updateEntryState(entry, entry.state);
}
this._selectAll = true;
},
getSelected: function () {
};
et2_dataview_selectionManager.prototype.getSelected = function () {
// Collect all currently selected ids
var ids = [];
for (var key in this._registeredRows)
{
if (egwBitIsSet(this._registeredRows[key].state, EGW_AO_STATE_SELECTED))
{
for (var key in this._registeredRows) {
if (egwBitIsSet(this._registeredRows[key].state, EGW_AO_STATE_SELECTED)) {
ids.push(key);
}
}
// Push all events of the child managers onto the list
for (var i = 0; i < this._children.length; i++)
{
for (var i = 0; i < this._children.length; i++) {
ids = ids.concat(this._children[i].getSelected().ids);
}
// Return an array containing those ids
// RB: we are currently NOT using "inverted"
return {
@ -289,221 +217,158 @@ var et2_dataview_selectionManager = (function(){ "use strict"; return Class.exte
"all": this._selectAll,
"ids": ids
};
},
};
/** -- PRIVATE FUNCTIONS -- **/
_attachActionObjectInterface: function (_entry, _tr, _uid) {
et2_dataview_selectionManager.prototype._attachActionObjectInterface = function (_entry, _tr, _uid) {
// Create the AOI which is used internally in the selection manager
// this AOI is not connected to the AO, as the selection manager
// cares about selection etc.
_entry.aoi = new et2_dataview_rowAOI(_tr);
_entry.aoi.setStateChangeCallback(
function (_newState, _changedBit, _shiftState) {
if (_changedBit === EGW_AO_STATE_SELECTED)
{
_entry.aoi.setStateChangeCallback(function (_newState, _changedBit, _shiftState) {
if (_changedBit === EGW_AO_STATE_SELECTED) {
// Call the select handler
this._handleSelect(
_uid,
_entry,
egwBitIsSet(_shiftState, EGW_AO_SHIFT_STATE_BLOCK),
egwBitIsSet(_shiftState, EGW_AO_SHIFT_STATE_MULTI)
);
this._handleSelect(_uid, _entry, egwBitIsSet(_shiftState, EGW_AO_SHIFT_STATE_BLOCK), egwBitIsSet(_shiftState, EGW_AO_SHIFT_STATE_MULTI));
}
}, this);
},
_getDummyAOI: function (_entry, _tr, _uid, _idx) {
};
et2_dataview_selectionManager.prototype._getDummyAOI = function (_entry, _tr, _uid, _idx) {
// Create AOI
var dummyAOI = new egwActionObjectInterface();
var self = this;
// Handling for Action Implementations updating the state
dummyAOI.doSetState = function (_state) {
if (!self._inUpdate)
{
if (!self._inUpdate) {
// Update the "focused" flag
self.setFocused(_uid, egwBitIsSet(_state, EGW_AO_STATE_FOCUSED));
// Generally update the state
self._updateState(_uid, _state);
}
};
// Handle the "make visible" event, pass the request to the parent
// controller
dummyAOI.doMakeVisible = function () {
self._makeVisibleCallback.call(self._context, _idx);
};
// Connect the the two AOIs
dummyAOI.doTriggerEvent = _entry.aoi.doTriggerEvent;
// Implementation of the getDOMNode function, so that the event
// handlers can be properly bound
dummyAOI.getDOMNode = function () { return _tr; };
return dummyAOI;
},
_attachActionObject: function (_entry, _tr, _uid, _links, _idx) {
};
et2_dataview_selectionManager.prototype._attachActionObject = function (_entry, _tr, _uid, _links, _idx) {
// Get the dummyAOI which connects the action object to the tr but
// does no selection handling
var dummyAOI = this._getDummyAOI(_entry, _tr, _uid, _idx);
// Create an action object for the tr and connect it to a dummy AOI
if(this._actionObjectManager)
{
if(this._actionObjectManager.getObjectById(_uid))
{
if (this._actionObjectManager) {
if (this._actionObjectManager.getObjectById(_uid)) {
var state = _entry.state;
this._actionObjectManager.getObjectById(_uid).remove();
_entry.state = state;
}
_entry.ao = this._actionObjectManager.addObject(_uid, dummyAOI);
}
// Force context (actual widget) in here, it's the last place it's available
_entry.ao._context = this._context;
_entry.ao.updateActionLinks(_links);
_entry.ao._index = _idx;
// Overwrite some functions like "traversePath", "getNext" and
// "getPrevious"
var self = this;
function getIndexAO (_idx) {
function getIndexAO(_idx) {
// Check whether the index is in the index map
if (typeof self._indexMap[_idx] !== "undefined"
&& self._indexMap[_idx].uid)
{
&& self._indexMap[_idx].uid) {
return self._getRegisteredRowsEntry(self._indexMap[_idx].uid).ao;
}
return null;
}
function getElementRelatively (_step) {
function getElementRelatively(_step) {
var total = self._total || Object.keys(self._indexMap).length;
var max_index = Math.max.apply(Math,Object.keys(self._indexMap));
var max_index = Math.max.apply(Math, Object.keys(self._indexMap));
// Get a reasonable number of iterations - not all
var count = Math.max(1,Math.min(self._total,50));
var count = Math.max(1, Math.min(self._total, 50));
var element = null;
var idx = _entry.idx;
while(element == null && count > 0 && max_index > 0)
{
while (element == null && count > 0 && max_index > 0) {
count--;
element = getIndexAO(Math.max(0,
Math.min(max_index, idx += _step)));
element = getIndexAO(Math.max(0, Math.min(max_index, idx += _step)));
}
return element;
};
}
_entry.ao.getPrevious = function (_step) {
return getElementRelatively(-_step);
};
_entry.ao.getNext = function (_step) {
return getElementRelatively(_step);
};
_entry.ao.traversePath = function (_obj) {
// Get the start and the stop index
var s = Math.min(this._index, _obj._index);
var e = Math.max(this._index, _obj._index);
var result = [];
for (var i = s; i < e; i++)
{
for (var i = s; i < e; i++) {
var ao = getIndexAO(i);
if (ao)
{
if (ao) {
result.push(ao);
}
}
return result;
};
},
_updateState: function (_uid, _state) {
};
et2_dataview_selectionManager.prototype._updateState = function (_uid, _state) {
var entry = this._getRegisteredRowsEntry(_uid);
this._updateEntryState(entry, _state);
return entry;
},
_updateEntryState: function (_entry, _state) {
if (this._selectAll)
{
};
et2_dataview_selectionManager.prototype._updateEntryState = function (_entry, _state) {
if (this._selectAll) {
_state |= EGW_AO_STATE_SELECTED;
}
else if (this._invertSelection)
{
else if (this._invertSelection) {
_state ^= EGW_AO_STATE_SELECTED;
}
// Attach ao if not there, happens for rows loaded for selection, but
// not displayed yet
if(!_entry.ao && _entry.uid && this._actionObjectManager)
{
if (!_entry.ao && _entry.uid && this._actionObjectManager) {
var _links = [];
for (var key in this._registeredRows)
{
if(this._registeredRows[key].ao && this._registeredRows[key].ao.actionLinks)
{
for (var key in this._registeredRows) {
if (this._registeredRows[key].ao && this._registeredRows[key].ao.actionLinks) {
_links = this._registeredRows[key].ao.actionLinks;
break;
}
}
if(_links)
{
if (_links) {
this._attachActionObjectInterface(_entry, null, _entry.uid);
this._attachActionObject(_entry, null, _entry.uid, _links, _entry.idx);
}
}
// Update the state if it has changed
if ((_entry.aoi && _entry.aoi.getState() !== _state) || _entry.state != _state)
{
if ((_entry.aoi && _entry.aoi.getState() !== _state) || _entry.state != _state) {
this._inUpdate = true; // Recursion prevention
// Update the state of the action object
if (_entry.ao)
{
if (_entry.ao) {
_entry.ao.setSelected(egwBitIsSet(_state, EGW_AO_STATE_SELECTED));
_entry.ao.setFocused(egwBitIsSet(_state, EGW_AO_STATE_FOCUSED));
}
this._inUpdate = false;
// Delete the element if state was set to "NORMAL" and there is
// no tr
if (_state === EGW_AO_STATE_NORMAL && !_entry.tr)
{
if (_state === EGW_AO_STATE_NORMAL && !_entry.tr) {
delete this._registeredRows[_entry.uid];
}
}
// Update the visual state
if (_entry.aoi && _entry.aoi.doSetState)
{
if (_entry.aoi && _entry.aoi.doSetState) {
_entry.aoi.doSetState(_state);
}
// Update the state of the entry
_entry.state = _state;
},
_getRegisteredRowsEntry: function (_uid) {
if (typeof this._registeredRows[_uid] === "undefined")
{
};
et2_dataview_selectionManager.prototype._getRegisteredRowsEntry = function (_uid) {
if (typeof this._registeredRows[_uid] === "undefined") {
this._registeredRows[_uid] = {
"uid": _uid,
"idx": null,
@ -513,49 +378,36 @@ var et2_dataview_selectionManager = (function(){ "use strict"; return Class.exte
"ao": null
};
}
return this._registeredRows[_uid];
},
_handleSelect: function (_uid, _entry, _shift, _ctrl) {
};
et2_dataview_selectionManager.prototype._handleSelect = function (_uid, _entry, _shift, _ctrl) {
// If not "_ctrl" is set, reset the selection
if (!_ctrl)
{
if (!_ctrl) {
var top = this;
while(top._parent !== null)
{
while (top._parent !== null) {
top = top._parent;
}
top.resetSelection();
this._actionObjectManager.setAllSelected(false); // needed for hirachical stuff
}
// Mark the element that was clicked as selected
var entry = this._getRegisteredRowsEntry(_uid);
this.setSelected(_uid,
!_ctrl || !egwBitIsSet(entry.state, EGW_AO_STATE_SELECTED));
this.setSelected(_uid, !_ctrl || !egwBitIsSet(entry.state, EGW_AO_STATE_SELECTED));
// Focus the element if shift is not pressed
if (!_shift)
{
if (!_shift) {
this.setFocused(_uid, true);
}
else if (this._focusedEntry)
{
else if (this._focusedEntry) {
this._selectRange(this._focusedEntry.idx, _entry.idx);
}
if(this.select_callback && typeof this.select_callback == "function")
{
if (this.select_callback && typeof this.select_callback == "function") {
this.select_callback.apply(this._context, arguments);
}
},
_selectRange: function (_start, _stop) {
};
et2_dataview_selectionManager.prototype._selectRange = function (_start, _stop) {
// Contains ranges that are not currently in the index map and that have
// to be queried
var queryRanges = [];
// Iterate over the given range and select the elements in the range
// from _start to _stop
var naStart = false;
@ -563,56 +415,43 @@ var et2_dataview_selectionManager = (function(){ "use strict"; return Class.exte
var e = Math.max(_stop, _start);
var RANGE_MAX = 50;
var range_break = s + RANGE_MAX;
for (var i = s; i <= e; i++)
{
for (var i = s; i <= e; i++) {
if (typeof this._indexMap[i] !== "undefined" &&
this._indexMap[i].uid && egw.dataGetUIDdata(this._indexMap[i].uid))
{
this._indexMap[i].uid && egw.dataGetUIDdata(this._indexMap[i].uid)) {
// Add the range to the "queryRanges"
if (naStart !== false)
{
if (naStart !== false) {
queryRanges.push(et2_bounds(naStart, i - 1));
naStart = false;
range_break += RANGE_MAX;
}
// Select the element, unless flagged for exclusion
// Check for no_actions flag via data
var data = egw.dataGetUIDdata(this._indexMap[i].uid);
if(data && data.data && !data.data.no_actions)
{
if (data && data.data && !data.data.no_actions) {
this.setSelected(this._indexMap[i].uid, true);
}
}
else if (naStart === false)
{
else if (naStart === false) {
naStart = i;
range_break = naStart + RANGE_MAX;
}
else if(i >= range_break)
{
else if (i >= range_break) {
queryRanges.push(et2_bounds(naStart ? naStart : s, i - 1));
naStart = i;
range_break += RANGE_MAX;
}
}
// Add the last range to the "queryRanges"
if (naStart !== false)
{
if (naStart !== false) {
queryRanges.push(et2_bounds(naStart, i - 1));
naStart = false;
}
// Query all unknown ranges from the server
if(queryRanges.length > 0)
{
if (queryRanges.length > 0) {
this._query_ranges(queryRanges);
}
},
_query_ranges: function _query_ranges(queryRanges)
{
};
et2_dataview_selectionManager.prototype._query_ranges = function (queryRanges) {
var that = this;
var record_count = 0;
var range_index = 0;
@ -623,63 +462,57 @@ var et2_dataview_selectionManager = (function(){ "use strict"; return Class.exte
});
// Found after dialog loads
var progressbar;
var parent = et2_dialog._create_parent();
var dialog = et2_createWidget("dialog", {
callback:
// Abort the long task if they canceled the data load
function() {cont = false},
template: egw.webserverUrl+'/api/templates/default/long_task.xet',
function () { cont = false; },
template: egw.webserverUrl + '/api/templates/default/long_task.xet',
message: egw.lang('Loading'),
title: egw.lang('please wait...'),
buttons: [{"button_id": et2_dialog.CANCEL_BUTTON,"text": egw.lang('cancel'),id: 'dialog[cancel]',image: 'cancel'}],
buttons: [{ "button_id": et2_dialog.CANCEL_BUTTON, "text": egw.lang('cancel'), id: 'dialog[cancel]', image: 'cancel' }],
width: 300
}, parent);
jQuery(dialog.template.DOMContainer).on('load', function() {
jQuery(dialog.template.DOMContainer).on('load', function () {
// Get access to template widgets
progressbar = dialog.template.widgetContainer.getWidgetById('progressbar');
});
for (var i = 0; i < queryRanges.length; i++)
{
if(record_count + (queryRanges[i].bottom - queryRanges[i].top+1) > that.MAX_SELECTION)
{
for (var i = 0; i < queryRanges.length; i++) {
if (record_count + (queryRanges[i].bottom - queryRanges[i].top + 1) > that.MAX_SELECTION) {
egw.message(egw.lang('Too many rows selected.<br />Select all, or less than %1 rows', that.MAX_SELECTION));
break;
}
else
{
record_count += (queryRanges[i].bottom - queryRanges[i].top+1);
fetchPromise = fetchPromise.then((function ()
{
else {
record_count += (queryRanges[i].bottom - queryRanges[i].top + 1);
fetchPromise = fetchPromise.then((function () {
// Check for abort
if(!cont) return;
return new Promise(function(resolve) {
that._queryRangeCallback.call(that._context, this,
function (_order) {
for (var j = 0; j < _order.length; j++)
{
if (!cont)
return;
return new Promise(function (resolve) {
that._queryRangeCallback.call(that._context, this, function (_order) {
for (var j = 0; j < _order.length; j++) {
// Check for no_actions flag via data since entry isn't there/available
var data = egw.dataGetUIDdata(_order[j]);
if(!data || data && data.data && !data.data.no_actions)
{
if (!data || data && data.data && !data.data.no_actions) {
var entry = this._getRegisteredRowsEntry(_order[j]);
this._updateEntryState(entry,
egwSetBit(entry.state, EGW_AO_STATE_SELECTED, true));
this._updateEntryState(entry, egwSetBit(entry.state, EGW_AO_STATE_SELECTED, true));
}
}
progressbar.set_value(100*(++range_index/range_count));
progressbar.set_value(100 * (++range_index / range_count));
resolve();
}, that);
}.bind(this));
}).bind(queryRanges[i]));
}
}
fetchPromise.finally(function() {
fetchPromise.finally(function () {
dialog.destroy();
});
}
});}).call(this);
};
// Maximum number of rows we can safely fetch for selection
// Actual selection may have more rows if we already have some
et2_dataview_selectionManager.MAX_SELECTION = 1000;
return et2_dataview_selectionManager;
}());
exports.et2_dataview_selectionManager = et2_dataview_selectionManager;
//# sourceMappingURL=et2_dataview_controller_selection.js.map

View File

@ -0,0 +1,720 @@
/**
* EGroupware eTemplate2
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package etemplate
* @subpackage dataview
* @link http://www.egroupware.org
* @author Andreas Stöckel
* @copyright Stylite 2011-2012
*
/*egw:uses
et2_dataview_view_aoi;
egw_action.egw_keymanager;
*/
/**
* The selectioManager is internally used by the et2_dataview_controller class
* to manage the row selection.
* As the action system does not allow selection of entries which are currently
* not in the dom tree, we have to manage this in this class. The idea is to
* manage an external action object interface for each visible row and proxy all
* state changes between an dummy action object, that does no selection handling,
* and the external action object interface.
*
* @augments Class
*/
export class et2_dataview_selectionManager
{
// Maximum number of rows we can safely fetch for selection
// Actual selection may have more rows if we already have some
public static readonly MAX_SELECTION = 1000;
private _parent: any;
private _indexMap: any;
private _actionObjectManager: any;
private _makeVisibleCallback: any;
private _queryRangeCallback: any;
private select_callback: null;
private _context: any;
private _registeredRows: {};
private _focusedEntry: null;
private _invertSelection: boolean;
private _selectAll: boolean;
private _inUpdate: boolean;
private _total: number;
private _children: any[];
/**
* Constructor
*
* @param _parent
* @param _indexMap
* @param _actionObjectManager
* @param _queryRangeCallback
* @param _makeVisibleCallback
* @param _context
* @memberOf et2_dataview_selectionManager
*/
constructor(_parent, _indexMap, _actionObjectManager,
_queryRangeCallback, _makeVisibleCallback, _context)
{
// Copy the arguments
this._parent = _parent;
this._indexMap = _indexMap;
this._actionObjectManager = _actionObjectManager;
this._queryRangeCallback = _queryRangeCallback;
this._makeVisibleCallback = _makeVisibleCallback;
this._context = _context;
// Attach this manager to the parent manager if one is given
if (this._parent)
{
this._parent._children.push(this);
}
// Use our selection instead of object manager's to handle not-loaded rows
if(_actionObjectManager)
{
this._actionObjectManager.getAllSelected = jQuery.proxy(
this.getAllSelected, this
);
}
// Internal map which contains all curently selected uids and their
// state
this._registeredRows = {};
this._focusedEntry = null;
this._invertSelection = false;
this._selectAll = false;
this._inUpdate = false;
this._total = 0;
this._children = [];
// Callback for when the selection changes
this.select_callback = null;
}
destroy( )
{
// If we have a parent, unregister from that
if (this._parent)
{
var idx = this._parent._children.indexOf(this);
this._parent._children.splice(idx, 1);
}
// Destroy all children
for (var i = this._children.length - 1; i >= 0; i--)
{
this._children[i].destroy();
}
// Delete all still registered rows
for (var key in this._registeredRows)
{
this.unregisterRow(key, this._registeredRows[key].tr);
}
this.select_callback = null;
}
clear( )
{
for (var key in this._registeredRows)
{
this.unregisterRow(key, this._registeredRows[key].tr);
delete this._registeredRows[key];
}
if(this._actionObjectManager)
{
this._actionObjectManager.clear();
}
for (key in this._indexMap) {
delete this._indexMap[key];
}
this._total = 0;
this._focusedEntry = null;
this._invertSelection = false;
this._selectAll = false;
this._inUpdate = false;
}
setIndexMap( _indexMap)
{
this._indexMap = _indexMap;
}
setTotalCount( _total)
{
this._total = _total;
}
registerRow( _uid, _idx, _tr, _links)
{
// Get the corresponding entry from the registered rows array
var entry = this._getRegisteredRowsEntry(_uid);
// If the row has changed unregister the old one and do not delete
// entry from the entry map
if (entry.tr && entry.tr !== _tr) {
this.unregisterRow(_uid, entry.tr, true);
}
// Create the AOI for the tr
if (!entry.tr && _links)
{
this._attachActionObjectInterface(entry, _tr, _uid);
this._attachActionObject(entry, _tr, _uid, _links, _idx);
}
// Update the entry
if(entry.ao) entry.ao._index;
entry.idx = _idx;
entry.tr = _tr;
// Update the visible state of the _tr
this._updateEntryState(entry, entry.state);
}
unregisterRow( _uid, _tr, _noDelete? : boolean)
{
// _noDelete defaults to false
_noDelete = _noDelete ? true : false;
if (typeof this._registeredRows[_uid] !== "undefined"
&& this._registeredRows[_uid].tr === _tr)
{
this._inUpdate = true;
this._registeredRows[_uid].tr = null;
this._registeredRows[_uid].aoi = null;
// Remove the action object from its container
if (this._registeredRows[_uid].ao)
{
this._registeredRows[_uid].ao.remove();
this._registeredRows[_uid].ao = null;
}
if (!_noDelete
&& this._registeredRows[_uid].state === EGW_AO_STATE_NORMAL)
{
delete this._registeredRows[_uid];
}
this._inUpdate = false;
}
}
resetSelection( )
{
this._invertSelection = false;
this._selectAll = false;
this._actionObjectManager.setAllSelected(false);
for (var key in this._registeredRows)
{
this.setSelected(key, false);
}
for(var i = 0; i < this._children.length; i++)
{
this._children[i].resetSelection();
}
}
setSelected( _uid, _selected)
{
this._selectAll = false;
var entry = this._getRegisteredRowsEntry(_uid);
this._updateEntryState(entry,
egwSetBit(entry.state, EGW_AO_STATE_SELECTED, _selected));
}
getAllSelected()
{
var selected = this.getSelected();
return selected.all || (selected.ids.length === this._total);
}
setFocused( _uid, _focused)
{
// Reset the state of the currently focused entry
if (this._focusedEntry)
{
this._updateEntryState(this._focusedEntry,
egwSetBit(this._focusedEntry.state, EGW_AO_STATE_FOCUSED,
false));
this._focusedEntry = null;
}
// Mark the new given uid as focused
if (_focused)
{
//console.log('et2_dataview_controller_selection::setFocused -> UID:'+_uid+' is focused by:'+this._actionObjectManager.name);
var entry = this._focusedEntry = this._getRegisteredRowsEntry(_uid);
this._updateEntryState(entry,
egwSetBit(entry.state, EGW_AO_STATE_FOCUSED, true));
}
}
selectAll( )
{
// Reset the selection
this.resetSelection();
this._selectAll = true;
// Run as a range if there's less then the max
if(egw.dataKnownUIDs(this._context._dataProvider.dataStorePrefix).length !== this._total &&
this._total <= et2_dataview_selectionManager.MAX_SELECTION
)
{
this._selectRange(0, this._total);
}
// Tell action manager to do all
this._actionObjectManager.setAllSelected(true);
// Update the selection
for (var key in this._registeredRows)
{
var entry = this._registeredRows[key];
this._updateEntryState(entry, entry.state);
}
this._selectAll = true;
}
getSelected( )
{
// Collect all currently selected ids
var ids = [];
for (var key in this._registeredRows)
{
if (egwBitIsSet(this._registeredRows[key].state, EGW_AO_STATE_SELECTED))
{
ids.push(key);
}
}
// Push all events of the child managers onto the list
for (var i = 0; i < this._children.length; i++)
{
ids = ids.concat(this._children[i].getSelected().ids);
}
// Return an array containing those ids
// RB: we are currently NOT using "inverted"
return {
//"inverted": this._invertSelection,
"all": this._selectAll,
"ids": ids
};
}
/** -- PRIVATE FUNCTIONS -- **/
_attachActionObjectInterface( _entry, _tr, _uid)
{
// Create the AOI which is used internally in the selection manager
// this AOI is not connected to the AO, as the selection manager
// cares about selection etc.
_entry.aoi = new et2_dataview_rowAOI(_tr);
_entry.aoi.setStateChangeCallback(
function (_newState, _changedBit, _shiftState) {
if (_changedBit === EGW_AO_STATE_SELECTED)
{
// Call the select handler
this._handleSelect(
_uid,
_entry,
egwBitIsSet(_shiftState, EGW_AO_SHIFT_STATE_BLOCK),
egwBitIsSet(_shiftState, EGW_AO_SHIFT_STATE_MULTI)
);
}
}, this);
}
_getDummyAOI( _entry, _tr, _uid, _idx)
{
// Create AOI
var dummyAOI = new egwActionObjectInterface();
var self = this;
// Handling for Action Implementations updating the state
dummyAOI.doSetState = function (_state) {
if (!self._inUpdate)
{
// Update the "focused" flag
self.setFocused(_uid, egwBitIsSet(_state, EGW_AO_STATE_FOCUSED));
// Generally update the state
self._updateState(_uid, _state);
}
};
// Handle the "make visible" event, pass the request to the parent
// controller
dummyAOI.doMakeVisible = function () {
self._makeVisibleCallback.call(self._context, _idx);
};
// Connect the the two AOIs
dummyAOI.doTriggerEvent = _entry.aoi.doTriggerEvent;
// Implementation of the getDOMNode function, so that the event
// handlers can be properly bound
dummyAOI.getDOMNode = function () { return _tr; };
return dummyAOI;
}
_attachActionObject( _entry, _tr, _uid, _links, _idx)
{
// Get the dummyAOI which connects the action object to the tr but
// does no selection handling
var dummyAOI = this._getDummyAOI(_entry, _tr, _uid, _idx);
// Create an action object for the tr and connect it to a dummy AOI
if(this._actionObjectManager)
{
if(this._actionObjectManager.getObjectById(_uid))
{
var state = _entry.state;
this._actionObjectManager.getObjectById(_uid).remove();
_entry.state = state;
}
_entry.ao = this._actionObjectManager.addObject(_uid, dummyAOI);
}
// Force context (actual widget) in here, it's the last place it's available
_entry.ao._context = this._context;
_entry.ao.updateActionLinks(_links);
_entry.ao._index = _idx;
// Overwrite some functions like "traversePath", "getNext" and
// "getPrevious"
var self = this;
function getIndexAO (_idx) {
// Check whether the index is in the index map
if (typeof self._indexMap[_idx] !== "undefined"
&& self._indexMap[_idx].uid)
{
return self._getRegisteredRowsEntry(self._indexMap[_idx].uid).ao;
}
return null;
}
function getElementRelatively (_step) {
var total = self._total || Object.keys(self._indexMap).length;
var max_index = Math.max.apply(Math,Object.keys(self._indexMap));
// Get a reasonable number of iterations - not all
var count = Math.max(1,Math.min(self._total,50));
var element = null;
var idx = _entry.idx;
while(element == null && count > 0 && max_index > 0)
{
count--;
element = getIndexAO(Math.max(0,
Math.min(max_index, idx += _step)));
}
return element;
}
_entry.ao.getPrevious = function (_step) {
return getElementRelatively(-_step);
};
_entry.ao.getNext = function (_step) {
return getElementRelatively(_step);
};
_entry.ao.traversePath = function (_obj) {
// Get the start and the stop index
var s = Math.min(this._index, _obj._index);
var e = Math.max(this._index, _obj._index);
var result = [];
for (var i = s; i < e; i++)
{
var ao = getIndexAO(i);
if (ao)
{
result.push(ao);
}
}
return result;
};
}
_updateState( _uid, _state)
{
var entry = this._getRegisteredRowsEntry(_uid);
this._updateEntryState(entry, _state);
return entry;
}
_updateEntryState( _entry, _state)
{
if (this._selectAll)
{
_state |= EGW_AO_STATE_SELECTED;
}
else if (this._invertSelection)
{
_state ^= EGW_AO_STATE_SELECTED;
}
// Attach ao if not there, happens for rows loaded for selection, but
// not displayed yet
if(!_entry.ao && _entry.uid && this._actionObjectManager)
{
var _links = [];
for (var key in this._registeredRows)
{
if(this._registeredRows[key].ao && this._registeredRows[key].ao.actionLinks)
{
_links = this._registeredRows[key].ao.actionLinks;
break;
}
}
if(_links)
{
this._attachActionObjectInterface(_entry, null, _entry.uid);
this._attachActionObject(_entry, null, _entry.uid, _links, _entry.idx);
}
}
// Update the state if it has changed
if ((_entry.aoi && _entry.aoi.getState() !== _state) || _entry.state != _state)
{
this._inUpdate = true; // Recursion prevention
// Update the state of the action object
if (_entry.ao)
{
_entry.ao.setSelected(egwBitIsSet(_state, EGW_AO_STATE_SELECTED));
_entry.ao.setFocused(egwBitIsSet(_state, EGW_AO_STATE_FOCUSED));
}
this._inUpdate = false;
// Delete the element if state was set to "NORMAL" and there is
// no tr
if (_state === EGW_AO_STATE_NORMAL && !_entry.tr)
{
delete this._registeredRows[_entry.uid];
}
}
// Update the visual state
if (_entry.aoi && _entry.aoi.doSetState)
{
_entry.aoi.doSetState(_state);
}
// Update the state of the entry
_entry.state = _state;
}
_getRegisteredRowsEntry( _uid)
{
if (typeof this._registeredRows[_uid] === "undefined")
{
this._registeredRows[_uid] = {
"uid": _uid,
"idx": null,
"state": EGW_AO_STATE_NORMAL,
"tr": null,
"aoi": null,
"ao": null
};
}
return this._registeredRows[_uid];
}
_handleSelect( _uid, _entry, _shift, _ctrl)
{
// If not "_ctrl" is set, reset the selection
if (!_ctrl)
{
var top = this;
while(top._parent !== null)
{
top = top._parent;
}
top.resetSelection();
this._actionObjectManager.setAllSelected(false); // needed for hirachical stuff
}
// Mark the element that was clicked as selected
var entry = this._getRegisteredRowsEntry(_uid);
this.setSelected(_uid,
!_ctrl || !egwBitIsSet(entry.state, EGW_AO_STATE_SELECTED));
// Focus the element if shift is not pressed
if (!_shift)
{
this.setFocused(_uid, true);
}
else if (this._focusedEntry)
{
this._selectRange(this._focusedEntry.idx, _entry.idx);
}
if(this.select_callback && typeof this.select_callback == "function")
{
this.select_callback.apply(this._context, arguments);
}
}
_selectRange( _start, _stop)
{
// Contains ranges that are not currently in the index map and that have
// to be queried
var queryRanges = [];
// Iterate over the given range and select the elements in the range
// from _start to _stop
var naStart = false;
var s = Math.min(_start, _stop);
var e = Math.max(_stop, _start);
var RANGE_MAX = 50;
var range_break = s + RANGE_MAX;
for (var i = s; i <= e; i++)
{
if (typeof this._indexMap[i] !== "undefined" &&
this._indexMap[i].uid && egw.dataGetUIDdata(this._indexMap[i].uid))
{
// Add the range to the "queryRanges"
if (naStart !== false)
{
queryRanges.push(et2_bounds(naStart, i - 1));
naStart = false;
range_break += RANGE_MAX;
}
// Select the element, unless flagged for exclusion
// Check for no_actions flag via data
var data = egw.dataGetUIDdata(this._indexMap[i].uid);
if(data && data.data && !data.data.no_actions)
{
this.setSelected(this._indexMap[i].uid, true);
}
}
else if (naStart === false)
{
naStart = i;
range_break = naStart + RANGE_MAX;
}
else if(i >= range_break)
{
queryRanges.push(et2_bounds(naStart ? naStart : s, i - 1));
naStart = i;
range_break += RANGE_MAX;
}
}
// Add the last range to the "queryRanges"
if (naStart !== false)
{
queryRanges.push(et2_bounds(naStart, i - 1));
naStart = false;
}
// Query all unknown ranges from the server
if(queryRanges.length > 0)
{
this._query_ranges(queryRanges);
}
}
_query_ranges(queryRanges)
{
var that = this;
var record_count = 0;
var range_index = 0;
var range_count = queryRanges.length;
var cont = true;
var fetchPromise = new Promise(function (resolve) {
resolve();
});
// Found after dialog loads
var progressbar;
var parent = et2_dialog._create_parent();
var dialog = et2_createWidget("dialog", {
callback:
// Abort the long task if they canceled the data load
function() {cont = false},
template: egw.webserverUrl+'/api/templates/default/long_task.xet',
message: egw.lang('Loading'),
title: egw.lang('please wait...'),
buttons: [{"button_id": et2_dialog.CANCEL_BUTTON,"text": egw.lang('cancel'),id: 'dialog[cancel]',image: 'cancel'}],
width: 300
}, parent);
jQuery(dialog.template.DOMContainer).on('load', function() {
// Get access to template widgets
progressbar = dialog.template.widgetContainer.getWidgetById('progressbar');
});
for (var i = 0; i < queryRanges.length; i++)
{
if(record_count + (queryRanges[i].bottom - queryRanges[i].top+1) > that.MAX_SELECTION)
{
egw.message(egw.lang('Too many rows selected.<br />Select all, or less than %1 rows', that.MAX_SELECTION));
break;
}
else
{
record_count += (queryRanges[i].bottom - queryRanges[i].top+1);
fetchPromise = fetchPromise.then((function ()
{
// Check for abort
if(!cont) return;
return new Promise(function(resolve) {
that._queryRangeCallback.call(that._context, this,
function (_order) {
for (var j = 0; j < _order.length; j++)
{
// Check for no_actions flag via data since entry isn't there/available
var data = egw.dataGetUIDdata(_order[j]);
if(!data || data && data.data && !data.data.no_actions)
{
var entry = this._getRegisteredRowsEntry(_order[j]);
this._updateEntryState(entry,
egwSetBit(entry.state, EGW_AO_STATE_SELECTED, true));
}
}
progressbar.set_value(100*(++range_index/range_count));
resolve();
}, that);
}.bind(this));
}).bind(queryRanges[i]));
}
}
fetchPromise.finally(function() {
dialog.destroy();
});
}
}

View File

@ -11,4 +11,16 @@
* @version $Id$
*/
Object.defineProperty(exports, "__esModule", { value: true });
var et2_dataviewIInvalidatable = "et2_dataview_IInvalidatable";
function implements_et2_dataview_IInvalidatable(obj) {
return implements_methods(obj, ["invalidate"]);
}
var et2_dataview_IViewRange = "et2_dataview_IViewRange";
function implements_et2_dataview_IViewRange(obj) {
return implements_methods(obj, ["setViewRange"]);
}
var et2_IDataProvider = "et2_IDataProvider";
function implements_et2_IDataProvider(obj) {
return implements_methods(obj, ["dataFetch", "dataRegisterUID", "dataUnregisterUID"]);
}
//# sourceMappingURL=et2_dataview_interfaces.js.map

View File

@ -16,16 +16,21 @@
export interface et2_dataview_IInvalidatable
{
invalidate()
}
var et2_dataviewIInvalidatable = "et2_dataview_IInvalidatable";
function implements_et2_dataview_IInvalidatable(obj : et2_widget)
{
return implements_methods(obj, ["invalidate"]);
}
export interface et2_dataview_IViewRange
{
setViewRange(_range)
}
var et2_dataview_IViewRange = "et2_dataview_IViewRange";
function implements_et2_dataview_IViewRange(obj : et2_widget)
{
return implements_methods(obj, ["setViewRange"]);
}
/**
@ -96,5 +101,10 @@ export interface et2_IDataProvider
dataUnregisterUID (_uid : string, _callback : Function, _context : object)
}
var et2_IDataProvider = "et2_IDataProvider";
function implements_et2_IDataProvider(obj : et2_widget)
{
return implements_methods(obj, ["dataFetch", "dataRegisterUID", "dataUnregisterUID"]);
}

View File

@ -15,13 +15,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
et2_core_inheritance;
et2_inheritance;
*/
var ET2_COL_TYPE_DEFAULT = 0;
var ET2_COL_TYPE_NAME_ICON_FIXED = 1;
var ET2_COL_VISIBILITY_ALWAYS = 0;
var ET2_COL_VISIBILITY_VISIBLE = 1;
var ET2_COL_VISIBILITY_INVISIBLE = 2;
var ET2_COL_VISIBILITY_ALWAYS_NOSELECT = 3;
var ET2_COL_VISIBILITY_DISABLED = 4;
/**
* Class which stores the data of a single column.
*
@ -35,14 +28,14 @@ var et2_dataview_column = /** @class */ (function () {
/**
* Defines the visibility state of this column.
*/
this.visibility = ET2_COL_VISIBILITY_VISIBLE;
this.visibility = et2_dataview_column.ET2_COL_VISIBILITY_VISIBLE;
this.caption = '';
/**
* Column type - Type of the column
*
* One of ET2_COL_TYPE_DEFAULT or ET2_COL_TYPE_NAME_ICON_FIXED
*/
this.type = ET2_COL_TYPE_DEFAULT;
this.type = et2_dataview_column.ET2_COL_TYPE_DEFAULT;
/**
* Width of the column
*/
@ -55,6 +48,23 @@ var et2_dataview_column = /** @class */ (function () {
* Minimum width of the column, in pixels. Values below this are rejected.
*/
this.minWidth = 20;
this.id = _attrs.id;
if (typeof _attrs.visibility !== "undefined") {
this.visibility = _attrs.visibility;
}
this.caption = _attrs.caption;
if (typeof _attrs.type !== "undefined") {
this.type = _attrs.type;
}
if (typeof _attrs.width !== "undefined") {
this.set_width(_attrs.width);
}
if (typeof _attrs.maxWidth !== "undefined") {
this.maxWidth = _attrs.maxWidth;
}
if (typeof _attrs.minWidth !== "undefined") {
this.minWidth = _attrs.minWidth;
}
}
/**
* Set the column width
@ -91,13 +101,13 @@ var et2_dataview_column = /** @class */ (function () {
};
et2_dataview_column.prototype.set_visibility = function (_value) {
// If visibility is always, don't turn it off
if (this.visibility == ET2_COL_VISIBILITY_ALWAYS || this.visibility == ET2_COL_VISIBILITY_ALWAYS_NOSELECT)
if (this.visibility == et2_dataview_column.ET2_COL_VISIBILITY_ALWAYS || this.visibility == et2_dataview_column.ET2_COL_VISIBILITY_ALWAYS_NOSELECT)
return;
if (_value === true) {
this.visibility = ET2_COL_VISIBILITY_VISIBLE;
this.visibility = et2_dataview_column.ET2_COL_VISIBILITY_VISIBLE;
}
else if (_value === false) {
this.visibility = ET2_COL_VISIBILITY_INVISIBLE;
this.visibility = et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE;
}
else if (typeof _value == "number") {
this.visibility = _value;
@ -106,6 +116,13 @@ var et2_dataview_column = /** @class */ (function () {
egw().debug("warn", "Invalid visibility option for column: ", _value);
}
};
et2_dataview_column.ET2_COL_TYPE_DEFAULT = 0;
et2_dataview_column.ET2_COL_TYPE_NAME_ICON_FIXED = 1;
et2_dataview_column.ET2_COL_VISIBILITY_ALWAYS = 0;
et2_dataview_column.ET2_COL_VISIBILITY_VISIBLE = 1;
et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE = 2;
et2_dataview_column.ET2_COL_VISIBILITY_ALWAYS_NOSELECT = 3;
et2_dataview_column.ET2_COL_VISIBILITY_DISABLED = 4;
et2_dataview_column._attributes = {
"id": {
"name": "ID",
@ -116,7 +133,7 @@ var et2_dataview_column = /** @class */ (function () {
"visibility": {
"name": "Visibility",
"type": "integer",
"default": ET2_COL_VISIBILITY_VISIBLE,
"default": et2_dataview_column.ET2_COL_VISIBILITY_VISIBLE,
"description": "Defines the visibility state of this column."
},
"caption": {
@ -128,7 +145,7 @@ var et2_dataview_column = /** @class */ (function () {
"type": {
"name": "Column type",
"type": "integer",
"default": ET2_COL_TYPE_DEFAULT,
"default": et2_dataview_column.ET2_COL_TYPE_DEFAULT,
"description": "Type of the column"
},
"width": {
@ -162,14 +179,14 @@ var et2_dataview_columns = /** @class */ (function () {
function et2_dataview_columns(_columnData) {
// Initialize some variables
this._totalWidth = 0;
this.totalFixed = 0;
this._totalFixed = 0;
this.columnWidths = [];
// Create the columns object
this.columns = new Array(_columnData.length);
for (var i = 0; i < _columnData.length; i++) {
this.columns[i] = new et2_dataview_column(_columnData[i]);
}
this.updated = true;
this._updated = true;
}
et2_dataview_columns.prototype.destroy = function () {
// Free all column objects
@ -177,6 +194,12 @@ var et2_dataview_columns = /** @class */ (function () {
this.columns[i] = null;
}
};
et2_dataview_columns.prototype.updated = function () {
this._updated = true;
};
et2_dataview_columns.prototype.columnCount = function () {
return this.columns.length;
};
Object.defineProperty(et2_dataview_columns.prototype, "totalWidth", {
get: function () {
return this._totalWidth;
@ -184,6 +207,13 @@ var et2_dataview_columns = /** @class */ (function () {
enumerable: true,
configurable: true
});
Object.defineProperty(et2_dataview_columns.prototype, "totalFixed", {
get: function () {
return this._totalFixed ? this._totalFixed : 0;
},
enumerable: true,
configurable: true
});
/**
* Set the total width of the header row
*
@ -192,7 +222,7 @@ var et2_dataview_columns = /** @class */ (function () {
et2_dataview_columns.prototype.setTotalWidth = function (_width) {
if (_width != this._totalWidth && _width > 0) {
this._totalWidth = _width;
this.updated = true;
this._updated = true;
}
};
/**
@ -225,9 +255,9 @@ var et2_dataview_columns = /** @class */ (function () {
et2_dataview_columns.prototype.getColumnWidth = function (_idx) {
if (this._totalWidth > 0 && _idx >= 0 && _idx < this.columns.length) {
// Recalculate the column widths if something has changed.
if (this.updated) {
if (this._updated) {
this._calculateWidths();
this.updated = false;
this._updated = false;
}
// Return the calculated width for the column with the given index.
return this.columnWidths[_idx];
@ -244,8 +274,8 @@ var et2_dataview_columns = /** @class */ (function () {
result.push({
"id": this.columns[i].id,
"width": this.getColumnWidth(i),
"visible": this.columns[i].visibility !== ET2_COL_VISIBILITY_INVISIBLE &&
this.columns[i].visibility !== ET2_COL_VISIBILITY_DISABLED
"visible": this.columns[i].visibility !== et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE &&
this.columns[i].visibility !== et2_dataview_column.ET2_COL_VISIBILITY_DISABLED
});
}
return result;
@ -257,13 +287,13 @@ var et2_dataview_columns = /** @class */ (function () {
et2_dataview_columns.prototype.getColumnVisibilitySet = function () {
var result = {};
for (var i = 0; i < this.columns.length; i++) {
if (this.columns[i].visibility != ET2_COL_VISIBILITY_ALWAYS_NOSELECT) {
if (this.columns[i].visibility != et2_dataview_column.ET2_COL_VISIBILITY_ALWAYS_NOSELECT) {
result[this.columns[i].id] = {
"caption": this.columns[i].caption,
"enabled": (this.columns[i].visibility != ET2_COL_VISIBILITY_ALWAYS) &&
(this.columns[i].visibility != ET2_COL_VISIBILITY_DISABLED) &&
(this.columns[i].type != ET2_COL_TYPE_NAME_ICON_FIXED),
"visible": this.columns[i].visibility != ET2_COL_VISIBILITY_INVISIBLE
"enabled": (this.columns[i].visibility != et2_dataview_column.ET2_COL_VISIBILITY_ALWAYS) &&
(this.columns[i].visibility != et2_dataview_column.ET2_COL_VISIBILITY_DISABLED) &&
(this.columns[i].type != et2_dataview_column.ET2_COL_TYPE_NAME_ICON_FIXED),
"visible": this.columns[i].visibility != et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE
};
}
}
@ -278,11 +308,11 @@ var et2_dataview_columns = /** @class */ (function () {
for (var k in _set) {
var col = this.getColumnById(k);
if (col) {
col.set_visibility(_set[k].visible ? ET2_COL_VISIBILITY_VISIBLE :
ET2_COL_VISIBILITY_INVISIBLE);
col.set_visibility(_set[k].visible ? et2_dataview_column.ET2_COL_VISIBILITY_VISIBLE :
et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE);
}
}
this.updated = true;
this._updated = true;
};
/* ---- PRIVATE FUNCTIONS ---- */
/**
@ -302,11 +332,11 @@ var et2_dataview_columns = /** @class */ (function () {
// relative or fixed width
var totalRelative = 0;
var fixedCount = 0;
this.totalFixed = 0;
this._totalFixed = 0;
for (var i = 0; i < this.columns.length; i++) {
var col = this.columns[i];
if (col.visibility !== ET2_COL_VISIBILITY_INVISIBLE &&
col.visibility !== ET2_COL_VISIBILITY_DISABLED) {
if (col.visibility !== et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE &&
col.visibility !== et2_dataview_column.ET2_COL_VISIBILITY_DISABLED) {
// Some bounds sanity checking
if (col.fixedWidth > tw || col.fixedWidth < 0) {
col.fixedWidth = false;
@ -318,7 +348,7 @@ var et2_dataview_columns = /** @class */ (function () {
totalRelative += col.relativeWidth;
}
else if (col.fixedWidth) {
this.totalFixed += col.fixedWidth;
this._totalFixed += col.fixedWidth;
fixedCount++;
}
}
@ -329,8 +359,8 @@ var et2_dataview_columns = /** @class */ (function () {
for (var i = 0; i < this.columns.length; i++) {
var w = 0;
var col = this.columns[i];
if (col.visibility != ET2_COL_VISIBILITY_INVISIBLE &&
col.visibility !== ET2_COL_VISIBILITY_DISABLED) {
if (col.visibility != et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE &&
col.visibility !== et2_dataview_column.ET2_COL_VISIBILITY_DISABLED) {
if (_larger[i]) {
w = col.maxWidth;
}
@ -341,7 +371,7 @@ var et2_dataview_columns = /** @class */ (function () {
// Reset relative to an actual percentage (of 1.00) or
// resizing eventually sends them to 0
col.relativeWidth = col.relativeWidth / totalRelative;
w = Math.round((tw - this.totalFixed) * col.relativeWidth);
w = Math.round((tw - this._totalFixed) * col.relativeWidth);
}
if (w > tw || (col.maxWidth && w > col.maxWidth)) {
w = Math.min(tw - usedTotal, col.maxWidth);
@ -359,8 +389,8 @@ var et2_dataview_columns = /** @class */ (function () {
var remaining_width = (usedTotal - tw);
// Pick the first relative column and use it
for (columnIndex = 0; columnIndex < this.columns.length; columnIndex++) {
if (this.columns[columnIndex].visibility === ET2_COL_VISIBILITY_INVISIBLE ||
this.columns[columnIndex].visibility === ET2_COL_VISIBILITY_DISABLED ||
if (this.columns[columnIndex].visibility === et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE ||
this.columns[columnIndex].visibility === et2_dataview_column.ET2_COL_VISIBILITY_DISABLED ||
this.columnWidths[columnIndex] <= 0 ||
remaining_width > 0 && this.columnWidths[columnIndex] <= this.columns[columnIndex].minWidth) {
continue;

View File

@ -16,15 +16,6 @@
*/
var ET2_COL_TYPE_DEFAULT = 0;
var ET2_COL_TYPE_NAME_ICON_FIXED = 1;
var ET2_COL_VISIBILITY_ALWAYS = 0;
var ET2_COL_VISIBILITY_VISIBLE = 1;
var ET2_COL_VISIBILITY_INVISIBLE = 2;
var ET2_COL_VISIBILITY_ALWAYS_NOSELECT = 3;
var ET2_COL_VISIBILITY_DISABLED = 4;
/**
* Class which stores the data of a single column.
*
@ -33,6 +24,15 @@ var ET2_COL_VISIBILITY_DISABLED = 4;
export class et2_dataview_column
{
public static readonly ET2_COL_TYPE_DEFAULT = 0;
public static readonly ET2_COL_TYPE_NAME_ICON_FIXED = 1;
public static readonly ET2_COL_VISIBILITY_ALWAYS = 0;
public static readonly ET2_COL_VISIBILITY_VISIBLE = 1;
public static readonly ET2_COL_VISIBILITY_INVISIBLE = 2;
public static readonly ET2_COL_VISIBILITY_ALWAYS_NOSELECT = 3;
public static readonly ET2_COL_VISIBILITY_DISABLED = 4;
static readonly _attributes: any = {
"id": {
"name": "ID",
@ -43,7 +43,7 @@ export class et2_dataview_column
"visibility": {
"name": "Visibility",
"type": "integer",
"default": ET2_COL_VISIBILITY_VISIBLE,
"default": et2_dataview_column.ET2_COL_VISIBILITY_VISIBLE,
"description": "Defines the visibility state of this column."
},
"caption": {
@ -55,7 +55,7 @@ export class et2_dataview_column
"type": {
"name": "Column type",
"type": "integer",
"default": ET2_COL_TYPE_DEFAULT,
"default": et2_dataview_column.ET2_COL_TYPE_DEFAULT,
"description": "Type of the column"
},
"width": {
@ -89,7 +89,7 @@ export class et2_dataview_column
/**
* Defines the visibility state of this column.
*/
public visibility: number = ET2_COL_VISIBILITY_VISIBLE;
public visibility: number = et2_dataview_column.ET2_COL_VISIBILITY_VISIBLE;
public caption: string = '';
@ -98,7 +98,7 @@ export class et2_dataview_column
*
* One of ET2_COL_TYPE_DEFAULT or ET2_COL_TYPE_NAME_ICON_FIXED
*/
public type: number = ET2_COL_TYPE_DEFAULT;
public type: number = et2_dataview_column.ET2_COL_TYPE_DEFAULT;
/**
* Width of the column
@ -120,6 +120,29 @@ export class et2_dataview_column
*/
constructor(_attrs)
{
this.id = _attrs.id;
if(typeof _attrs.visibility !== "undefined")
{
this.visibility = _attrs.visibility;
}
this.caption = _attrs.caption;
if(typeof _attrs.type !== "undefined")
{
this.type = _attrs.type;
}
if(typeof _attrs.width !== "undefined")
{
this.set_width( _attrs.width );
}
if(typeof _attrs.maxWidth !== "undefined")
{
this.maxWidth = _attrs.maxWidth;
}
if(typeof _attrs.minWidth !== "undefined")
{
this.minWidth = _attrs.minWidth;
}
}
/**
@ -167,15 +190,15 @@ export class et2_dataview_column
set_visibility(_value)
{
// If visibility is always, don't turn it off
if(this.visibility == ET2_COL_VISIBILITY_ALWAYS || this.visibility == ET2_COL_VISIBILITY_ALWAYS_NOSELECT) return;
if(this.visibility == et2_dataview_column.ET2_COL_VISIBILITY_ALWAYS || this.visibility == et2_dataview_column.ET2_COL_VISIBILITY_ALWAYS_NOSELECT) return;
if(_value === true)
{
this.visibility = ET2_COL_VISIBILITY_VISIBLE;
this.visibility = et2_dataview_column.ET2_COL_VISIBILITY_VISIBLE;
}
else if (_value === false)
{
this.visibility = ET2_COL_VISIBILITY_INVISIBLE;
this.visibility = et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE;
}
else if (typeof _value == "number")
{
@ -197,16 +220,16 @@ export class et2_dataview_column
export class et2_dataview_columns
{
private _totalWidth: number;
private totalFixed: number | boolean;
private _totalFixed: number | boolean;
private columnWidths: any[];
private columns: et2_dataview_column[];
private updated: boolean;
private _updated: boolean;
constructor(_columnData)
{
// Initialize some variables
this._totalWidth = 0;
this.totalFixed = 0;
this._totalFixed = 0;
this.columnWidths = [];
// Create the columns object
@ -216,7 +239,7 @@ export class et2_dataview_columns
this.columns[i] = new et2_dataview_column(_columnData[i]);
}
this.updated = true;
this._updated = true;
}
destroy() {
@ -227,9 +250,25 @@ export class et2_dataview_columns
}
}
get totalWidth(): number {
public updated()
{
this._updated = true;
}
columnCount() : number
{
return this.columns.length;
}
get totalWidth(): number
{
return this._totalWidth;
}
get totalFixed(): number {
return this._totalFixed ? <number>this._totalFixed : 0;
}
/**
* Set the total width of the header row
*
@ -240,7 +279,7 @@ export class et2_dataview_columns
if (_width != this._totalWidth && _width > 0)
{
this._totalWidth = _width;
this.updated = true;
this._updated = true;
}
}
@ -282,10 +321,10 @@ export class et2_dataview_columns
if (this._totalWidth > 0 && _idx >= 0 && _idx < this.columns.length)
{
// Recalculate the column widths if something has changed.
if (this.updated)
if (this._updated)
{
this._calculateWidths();
this.updated = false;
this._updated = false;
}
// Return the calculated width for the column with the given index.
@ -308,8 +347,8 @@ export class et2_dataview_columns
result.push({
"id": this.columns[i].id,
"width": this.getColumnWidth(i),
"visible": this.columns[i].visibility !== ET2_COL_VISIBILITY_INVISIBLE &&
this.columns[i].visibility !== ET2_COL_VISIBILITY_DISABLED
"visible": this.columns[i].visibility !== et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE &&
this.columns[i].visibility !== et2_dataview_column.ET2_COL_VISIBILITY_DISABLED
});
}
@ -327,14 +366,14 @@ export class et2_dataview_columns
for (var i = 0; i < this.columns.length; i++)
{
if (this.columns[i].visibility != ET2_COL_VISIBILITY_ALWAYS_NOSELECT)
if (this.columns[i].visibility != et2_dataview_column.ET2_COL_VISIBILITY_ALWAYS_NOSELECT)
{
result[this.columns[i].id] = {
"caption": this.columns[i].caption,
"enabled": (this.columns[i].visibility != ET2_COL_VISIBILITY_ALWAYS) &&
(this.columns[i].visibility != ET2_COL_VISIBILITY_DISABLED) &&
(this.columns[i].type != ET2_COL_TYPE_NAME_ICON_FIXED),
"visible": this.columns[i].visibility != ET2_COL_VISIBILITY_INVISIBLE
"enabled": (this.columns[i].visibility != et2_dataview_column.ET2_COL_VISIBILITY_ALWAYS) &&
(this.columns[i].visibility != et2_dataview_column.ET2_COL_VISIBILITY_DISABLED) &&
(this.columns[i].type != et2_dataview_column.ET2_COL_TYPE_NAME_ICON_FIXED),
"visible": this.columns[i].visibility != et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE
};
}
}
@ -354,12 +393,12 @@ export class et2_dataview_columns
var col = this.getColumnById(k);
if (col)
{
col.set_visibility(_set[k].visible ? ET2_COL_VISIBILITY_VISIBLE :
ET2_COL_VISIBILITY_INVISIBLE);
col.set_visibility(_set[k].visible ? et2_dataview_column.ET2_COL_VISIBILITY_VISIBLE :
et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE);
}
}
this.updated = true;
this._updated = true;
}
/* ---- PRIVATE FUNCTIONS ---- */
@ -385,13 +424,13 @@ export class et2_dataview_columns
// relative or fixed width
var totalRelative: number = 0;
var fixedCount = 0;
this.totalFixed = 0;
this._totalFixed = 0;
for (var i = 0; i < this.columns.length; i++)
{
var col = this.columns[i];
if (col.visibility !== ET2_COL_VISIBILITY_INVISIBLE &&
col.visibility !== ET2_COL_VISIBILITY_DISABLED
if (col.visibility !== et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE &&
col.visibility !== et2_dataview_column.ET2_COL_VISIBILITY_DISABLED
)
{
// Some bounds sanity checking
@ -409,7 +448,7 @@ export class et2_dataview_columns
}
else if (col.fixedWidth)
{
this.totalFixed += <number>col.fixedWidth;
this._totalFixed += <number>col.fixedWidth;
fixedCount++;
}
}
@ -422,8 +461,8 @@ export class et2_dataview_columns
{
var w = 0;
var col = this.columns[i];
if (col.visibility != ET2_COL_VISIBILITY_INVISIBLE &&
col.visibility !== ET2_COL_VISIBILITY_DISABLED
if (col.visibility != et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE &&
col.visibility !== et2_dataview_column.ET2_COL_VISIBILITY_DISABLED
)
{
if (_larger[i])
@ -439,7 +478,7 @@ export class et2_dataview_columns
// Reset relative to an actual percentage (of 1.00) or
// resizing eventually sends them to 0
col.relativeWidth = <number>col.relativeWidth / totalRelative;
w = Math.round((tw-this.totalFixed) * col.relativeWidth);
w = Math.round((tw-this._totalFixed) * col.relativeWidth);
}
if (w > tw || (col.maxWidth && w > col.maxWidth))
{
@ -463,8 +502,8 @@ export class et2_dataview_columns
// Pick the first relative column and use it
for(columnIndex = 0; columnIndex < this.columns.length; columnIndex++)
{
if(this.columns[columnIndex].visibility === ET2_COL_VISIBILITY_INVISIBLE ||
this.columns[columnIndex].visibility === ET2_COL_VISIBILITY_DISABLED ||
if(this.columns[columnIndex].visibility === et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE ||
this.columns[columnIndex].visibility === et2_dataview_column.ET2_COL_VISIBILITY_DISABLED ||
this.columnWidths[columnIndex] <= 0 ||
remaining_width > 0 && this.columnWidths[columnIndex] <= this.columns[columnIndex].minWidth)
{

View File

@ -9,7 +9,16 @@
* @author Andreas Stöckel
* @copyright Stylite 2011
* @version $Id$
*/
*
/*egw:uses
/vendor/bower-asset/jquery/dist/jquery.js;
et2_core_common;
et2_dataview_interfaces;
et2_dataview_view_container;
et2_dataview_view_spacer;
*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
@ -25,6 +34,7 @@ var __extends = (this && this.__extends) || (function () {
})();
Object.defineProperty(exports, "__esModule", { value: true });
var et2_dataview_view_container_1 = require("./et2_dataview_view_container");
var et2_dataview_view_spacer_1 = require("./et2_dataview_view_spacer");
var et2_dataview_grid = /** @class */ (function (_super_1) {
__extends(et2_dataview_grid, _super_1);
/**
@ -236,7 +246,7 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
*/
et2_dataview_grid.prototype.getVisibleIndexRange = function (_viewRange) {
function getElemIdx(_elem, _px) {
if (_elem instanceof et2_dataview_spacer) {
if (_elem instanceof et2_dataview_view_spacer_1.et2_dataview_spacer) {
return _elem.getIndex()
+ Math.floor((_px - _elem.getTop()) / this.getAverageHeight());
}
@ -281,7 +291,7 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
var idxTop = false;
var idxBottom = false;
for (var i = 0; i < this._map.length; i++) {
if (!(this._map[i] instanceof et2_dataview_spacer)) {
if (!(this._map[i] instanceof et2_dataview_view_spacer_1.et2_dataview_spacer)) {
var idx = this._map[i].getIndex();
if (idxTop === false) {
idxTop = idx;
@ -439,7 +449,7 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
// Get the map element
var elem = this._map[mapIdx];
// Get the element range
if (elem instanceof et2_dataview_spacer) {
if (elem instanceof et2_dataview_view_spacer_1.et2_dataview_spacer) {
var avg = this.getAverageHeight();
return et2_range(elem.getTop() + avg * (elem.getIndex() - _idx), avg);
}
@ -557,9 +567,9 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
var _loop_1 = function (i) {
var container = this_1._map[i];
// Check which type the container object has
var isSpacer = container instanceof et2_dataview_spacer;
var isSpacer = container instanceof et2_dataview_view_spacer_1.et2_dataview_spacer;
var hasIViewRange = !isSpacer
&& container.implements(et2_dataview_IViewRange);
&& implements_et2_dataview_IViewRange(container);
// If the container has one of those special types, calculate the
// view range and use that to update the view range of the element
// or to request new elements for the spacer
@ -699,7 +709,7 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
// Add the new element after the old container
_container.insertIntoTree(_mapElem.getLastNode());
// Create a new spacer and add it after the newly inserted container
var newSpacer = new et2_dataview_spacer(this, this._rowProvider);
var newSpacer = new et2_dataview_view_spacer_1.et2_dataview_spacer(this, this._rowProvider);
newSpacer.setCount(cntBottom, _avg);
newSpacer.setIndex(_index + 1);
newSpacer.insertIntoTree(_container.getLastNode());
@ -726,7 +736,7 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
// Append the new container to the current container and then
// destroy the old container
_container.insertIntoTree(_mapElem.getLastNode());
_mapElem.free();
_mapElem.destroy();
this._map.splice(_mapIndex, 1, _container);
}
};
@ -743,7 +753,7 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
// Update the index of the element
this._map[i].setIndex(_newIndex++);
// We've found a spacer -- decrement its element count and abort
if (this._map[i] instanceof et2_dataview_spacer) {
if (this._map[i] instanceof et2_dataview_view_spacer_1.et2_dataview_spacer) {
this._decrementSpacerCount(i, _avg);
return;
}
@ -751,7 +761,7 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
// We've found no spacer so far, remove the last element from the map in
// order to obtain the "totalCount" (especially the last element is no
// spacer, so the following code cannot remove a spacer)
this._map.pop().free();
this._map.pop().destroy();
};
/**
* Inserts the given container at the given index.
@ -760,7 +770,7 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
// Check whether the given element at the map index is a spacer. If
// yes, we have to split the spacer at that position.
var mapElem = this._map[_mapIndex];
if (mapElem instanceof et2_dataview_spacer) {
if (mapElem instanceof et2_dataview_view_spacer_1.et2_dataview_spacer) {
this._insertContainerAtSpacer(_index, _mapIndex, mapElem, _container, _avg);
}
else {
@ -786,16 +796,16 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
var spacerAbove = null;
var spacerBelow = null;
if (_mapIndex > 0
&& this._map[_mapIndex - 1] instanceof et2_dataview_spacer) {
&& this._map[_mapIndex - 1] instanceof et2_dataview_view_spacer_1.et2_dataview_spacer) {
spacerAbove = this._map[_mapIndex - 1];
}
if (_mapIndex < this._map.length - 1
&& this._map[_mapIndex + 1] instanceof et2_dataview_spacer) {
&& this._map[_mapIndex + 1] instanceof et2_dataview_view_spacer_1.et2_dataview_spacer) {
spacerBelow = this._map[_mapIndex + 1];
}
if (!spacerAbove && !spacerBelow) {
// No spacer can be extended -- simply create a new one
spacer = new et2_dataview_spacer(this, this._rowProvider);
spacer = new et2_dataview_view_spacer_1.et2_dataview_spacer(this, this._rowProvider);
spacer.setIndex(_mapElem.getIndex());
spacer.addAvgHeight(_mapElem.getHeight());
spacer.setCount(1, _mapElem.getHeight());
@ -818,7 +828,7 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
spacerAbove.addAvgHeight(_mapElem.getHeight());
spacerAbove.setCount(totalCount, newAvg);
// Delete the lower spacer and remove it from the mapping
spacerBelow.free();
spacerBelow.destroy();
this._map.splice(_mapIndex + 1, 1);
}
else {
@ -840,8 +850,8 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
*/
et2_dataview_grid.prototype._consolidateSpacers = function (_mapIndex) {
if (_mapIndex < this._map.length - 1
&& this._map[_mapIndex] instanceof et2_dataview_spacer
&& this._map[_mapIndex + 1] instanceof et2_dataview_spacer) {
&& this._map[_mapIndex] instanceof et2_dataview_view_spacer_1.et2_dataview_spacer
&& this._map[_mapIndex + 1] instanceof et2_dataview_view_spacer_1.et2_dataview_spacer) {
var spacerAbove = this._map[_mapIndex];
var spacerBelow = this._map[_mapIndex + 1];
// Calculate the new height/count of both containers
@ -851,7 +861,7 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
// Extend the new spacer
spacerAbove.setCount(totalCount, newAvg);
// Delete the old spacer
spacerBelow.free();
spacerBelow.destroy();
this._map.splice(_mapIndex + 1, 1);
}
};
@ -874,7 +884,7 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
this._map[_mapIndex].setCount(cnt, _avg);
}
else {
this._map[_mapIndex].free();
this._map[_mapIndex].destroy();
this._map.splice(_mapIndex, 1);
}
};
@ -891,7 +901,7 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
var removedElement = false;
// Check whether the map element is a spacer -- if yes, we have to do
// some special treatment
if (mapElem instanceof et2_dataview_spacer) {
if (mapElem instanceof et2_dataview_view_spacer_1.et2_dataview_spacer) {
// Do nothing if the "_replaceWithSpacer" flag is true as the
// element already is a spacer
if (!_replaceWithSpacer) {
@ -907,7 +917,7 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
removedElement = true;
}
// Remove the complete (current) container, decrement the _mapIndex
this._map[_mapIndex].free();
this._map[_mapIndex].destroy();
this._map.splice(_mapIndex, 1);
_mapIndex--;
// The delete operation may have created two joining spacers -- this
@ -940,9 +950,9 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
var spacer = null;
var lastIndex = this._map.length - 1;
if (this._map.length === 0 ||
!(this._map[lastIndex] instanceof et2_dataview_spacer)) {
!(this._map[lastIndex] instanceof et2_dataview_view_spacer_1.et2_dataview_spacer)) {
// Create a new spacer
spacer = new et2_dataview_spacer(this, this._rowProvider);
spacer = new et2_dataview_view_spacer_1.et2_dataview_spacer(this, this._rowProvider);
// Insert the spacer -- we have a special case if there currently is
// no element inside the mapping
if (this._map.length === 0) {
@ -985,7 +995,7 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
while (_delta > 0 && this._map.length > 0) {
var cont = this._map[this._map.length - 1];
// Remove as many containers as possible from spacers
if (cont instanceof et2_dataview_spacer) {
if (cont instanceof et2_dataview_view_spacer_1.et2_dataview_spacer) {
var diff = cont.getCount() - _delta;
if (diff > 0) {
// We're done as the spacer still has entries left
@ -1003,7 +1013,7 @@ var et2_dataview_grid = /** @class */ (function (_super_1) {
_delta -= 1;
}
// Destroy the container if there are no rows left
cont.free();
cont.destroy();
this._map.pop();
}
// Check whether _delta is really zero

View File

@ -8,7 +8,7 @@
* @author Andreas Stöckel
* @copyright Stylite 2011
* @version $Id$
*/
*
/*egw:uses
/vendor/bower-asset/jquery/dist/jquery.js;
@ -21,10 +21,11 @@
import {et2_dataview_IViewRange} from "./et2_dataview_interfaces";
import {et2_dataview_container} from "./et2_dataview_view_container";
import {et2_dataview_spacer} from "./et2_dataview_view_spacer";
import {et2_dataview_rowProvider} from "./et2_dataview_view_rowProvider";
export class et2_dataview_grid extends et2_dataview_container implements et2_dataview_IViewRange
{
/**
* Determines how many pixels the view range of the gridview is extended inside
* the scroll callback.
@ -794,7 +795,7 @@ export class et2_dataview_grid extends et2_dataview_container implements et2_dat
// Check which type the container object has
const isSpacer = container instanceof et2_dataview_spacer;
const hasIViewRange = !isSpacer
&& container.implements(et2_dataview_IViewRange);
&& implements_et2_dataview_IViewRange(container);
// If the container has one of those special types, calculate the
// view range and use that to update the view range of the element
@ -1020,7 +1021,7 @@ export class et2_dataview_grid extends et2_dataview_container implements et2_dat
// Append the new container to the current container and then
// destroy the old container
_container.insertIntoTree(_mapElem.getLastNode());
_mapElem.free();
_mapElem.destroy();
this._map.splice(_mapIndex, 1, _container);
}
@ -1053,7 +1054,7 @@ export class et2_dataview_grid extends et2_dataview_container implements et2_dat
// We've found no spacer so far, remove the last element from the map in
// order to obtain the "totalCount" (especially the last element is no
// spacer, so the following code cannot remove a spacer)
this._map.pop().free();
this._map.pop().destroy();
}
/**
@ -1139,7 +1140,7 @@ export class et2_dataview_grid extends et2_dataview_container implements et2_dat
spacerAbove.setCount(totalCount, newAvg);
// Delete the lower spacer and remove it from the mapping
spacerBelow.free();
spacerBelow.destroy();
this._map.splice(_mapIndex + 1, 1);
}
else
@ -1181,7 +1182,7 @@ export class et2_dataview_grid extends et2_dataview_container implements et2_dat
spacerAbove.setCount(totalCount, newAvg);
// Delete the old spacer
spacerBelow.free();
spacerBelow.destroy();
this._map.splice(_mapIndex + 1, 1);
}
}
@ -1208,7 +1209,7 @@ export class et2_dataview_grid extends et2_dataview_container implements et2_dat
}
else
{
this._map[_mapIndex].free();
this._map[_mapIndex].destroy();
this._map.splice(_mapIndex, 1);
}
}
@ -1252,7 +1253,7 @@ export class et2_dataview_grid extends et2_dataview_container implements et2_dat
}
// Remove the complete (current) container, decrement the _mapIndex
this._map[_mapIndex].free();
this._map[_mapIndex].destroy();
this._map.splice(_mapIndex, 1);
_mapIndex--;
@ -1374,7 +1375,7 @@ export class et2_dataview_grid extends et2_dataview_container implements et2_dat
}
// Destroy the container if there are no rows left
cont.free();
cont.destroy();
this._map.pop();
}

View File

@ -1,3 +1,4 @@
"use strict";
/**
* EGroupware eTemplate2 - dataview
*
@ -8,188 +9,152 @@
* @author Andreas Stöckel
* @copyright Stylite 2011-2012
* @version $Id$
*/
*
/*egw:uses
egw_action.egw_action;
et2_dataview_view_container;
*/
/**
* @augments et2_dataview_container
*/
var et2_dataview_row = (function(){ "use strict"; return et2_dataview_container.extend(et2_dataview_IViewRange,
{
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var et2_dataview_row = /** @class */ (function (_super) {
__extends(et2_dataview_row, _super);
/**
* Creates the row container. Use the "setRow" function to load the actual
* row content.
*
* @param _parent is the row parent container.
* @memberOf et2_dataview_row
*/
init: function(_parent) {
function et2_dataview_row(_parent) {
var _this =
// Call the inherited constructor
this._super(_parent);
_super.call(this, _parent) || this;
// Create the outer "tr" tag and append it to the container
this.tr = jQuery(document.createElement("tr"));
this.appendNode(this.tr);
_this.tr = jQuery(document.createElement("tr"));
_this.appendNode(_this.tr);
// Grid row which gets expanded when clicking on the corresponding
// button
this.expansionContainer = null;
this.expansionVisible = false;
_this.expansionContainer = null;
_this.expansionVisible = false;
// Toggle button which is used to show and hide the expansionContainer
this.expansionButton = null;
},
destroy: function () {
if (this.expansionContainer != null)
{
this.expansionContainer.free();
_this.expansionButton = null;
return _this;
}
this._super();
},
clear: function() {
et2_dataview_row.prototype.destroy = function () {
if (this.expansionContainer != null) {
this.expansionContainer.destroy();
}
_super.prototype.destroy.call(this);
};
et2_dataview_row.prototype.clear = function () {
this.tr.empty();
},
makeExpandable: function (_expandable, _callback, _context) {
if (_expandable)
{
};
et2_dataview_row.prototype.makeExpandable = function (_expandable, _callback, _context) {
if (_expandable) {
// Create the tr and the button if this has not been done yet
if (!this.expansionButton)
{
if (!this.expansionButton) {
this.expansionButton = jQuery(document.createElement("span"));
this.expansionButton.addClass("arrow closed");
}
// Update context
var self = this;
this.expansionButton.off("click").on("click", function (e) {
self._handleExpansionButtonClick(_callback, _context);
e.stopImmediatePropagation();
});
jQuery("td:first", this.tr).prepend(this.expansionButton);
}
else
{
else {
// If the row is made non-expandable, remove the created DOM-Nodes
if (this.expansionButton)
{
if (this.expansionButton) {
this.expansionButton.remove();
}
if (this.expansionContainer)
{
this.expansionContainer.free();
if (this.expansionContainer) {
this.expansionContainer.destroy();
}
this.expansionButton = null;
this.expansionContainer = null;
}
},
removeFromTree: function () {
if (this.expansionContainer)
{
};
et2_dataview_row.prototype.removeFromTree = function () {
if (this.expansionContainer) {
this.expansionContainer.removeFromTree();
}
this.expansionContainer = null;
this.expansionButton = null;
this._super();
},
getDOMNode: function () {
_super.prototype.removeFromTree.call(this);
};
et2_dataview_row.prototype.getDOMNode = function () {
return this.tr[0];
},
getJNode: function () {
};
et2_dataview_row.prototype.getJNode = function () {
return this.tr;
},
getHeight: function () {
var h = this._super();
if (this.expansionContainer && this.expansionVisible)
{
};
et2_dataview_row.prototype.getHeight = function () {
var h = _super.prototype.getHeight.call(this);
if (this.expansionContainer && this.expansionVisible) {
h += this.expansionContainer.getHeight();
}
return h;
},
getAvgHeightData: function() {
};
et2_dataview_row.prototype.getAvgHeightData = function () {
// Only take the height of the own tr into account
//var oldVisible = this.expansionVisible;
this.expansionVisible = false;
var res = {
"avgHeight": this.getHeight(),
"avgCount": 1
};
this.expansionVisible = true;
return res;
},
};
/** -- PRIVATE FUNCTIONS -- **/
_handleExpansionButtonClick: function (_callback, _context) {
et2_dataview_row.prototype._handleExpansionButtonClick = function (_callback, _context) {
// Create the "expansionContainer" if it does not exist yet
if (!this.expansionContainer)
{
if (!this.expansionContainer) {
this.expansionContainer = _callback.call(_context);
this.expansionContainer.insertIntoTree(this.tr);
this.expansionVisible = false;
}
// Toggle the visibility of the expansion tr
this.expansionVisible = !this.expansionVisible;
jQuery(this.expansionContainer._nodes[0]).toggle(this.expansionVisible);
// Set the class of the arrow
if (this.expansionVisible)
{
if (this.expansionVisible) {
this.expansionButton.addClass("opened");
this.expansionButton.removeClass("closed");
}
else
{
else {
this.expansionButton.addClass("closed");
this.expansionButton.removeClass("opened");
}
this.invalidate();
},
};
/** -- Implementation of et2_dataview_IViewRange -- **/
setViewRange: function (_range) {
et2_dataview_row.prototype.setViewRange = function (_range) {
if (this.expansionContainer && this.expansionVisible
&& this.expansionContainer.implements(et2_dataview_IViewRange))
{
&& this.expansionContainer.implements(et2_dataview_IViewRange)) {
// Substract the height of the own row from the container
var oh = jQuery(this._nodes[0]).height();
_range.top -= oh;
// Proxy the setViewRange call to the expansion container
this.expansionContainer.setViewRange(_range);
}
}
});}).call(this);
};
return et2_dataview_row;
}(et2_dataview_container));
exports.et2_dataview_row = et2_dataview_row;
//# sourceMappingURL=et2_dataview_view_row.js.map

View File

@ -0,0 +1,203 @@
/**
* EGroupware eTemplate2 - dataview
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package etemplate
* @subpackage dataview
* @link http://www.egroupware.org
* @author Andreas Stöckel
* @copyright Stylite 2011-2012
* @version $Id$
*
/*egw:uses
egw_action.egw_action;
et2_dataview_view_container;
*/
import {et2_dataview_IViewRange} from "./et2_dataview_interfaces";
export class et2_dataview_row extends et2_dataview_container implements et2_dataview_IViewRange
{
/**
* Creates the row container. Use the "setRow" function to load the actual
* row content.
*
* @param _parent is the row parent container.
*/
constructor( _parent)
{
// Call the inherited constructor
super(_parent);
// Create the outer "tr" tag and append it to the container
this.tr = jQuery(document.createElement("tr"));
this.appendNode(this.tr);
// Grid row which gets expanded when clicking on the corresponding
// button
this.expansionContainer = null;
this.expansionVisible = false;
// Toggle button which is used to show and hide the expansionContainer
this.expansionButton = null;
}
destroy( )
{
if (this.expansionContainer != null)
{
this.expansionContainer.destroy();
}
super.destroy();
}
clear( )
{
this.tr.empty();
}
makeExpandable( _expandable, _callback, _context)
{
if (_expandable)
{
// Create the tr and the button if this has not been done yet
if (!this.expansionButton)
{
this.expansionButton = jQuery(document.createElement("span"));
this.expansionButton.addClass("arrow closed");
}
// Update context
var self = this;
this.expansionButton.off("click").on("click", function (e) {
self._handleExpansionButtonClick(_callback, _context);
e.stopImmediatePropagation();
});
jQuery("td:first", this.tr).prepend(this.expansionButton);
}
else
{
// If the row is made non-expandable, remove the created DOM-Nodes
if (this.expansionButton)
{
this.expansionButton.remove();
}
if (this.expansionContainer)
{
this.expansionContainer.destroy();
}
this.expansionButton = null;
this.expansionContainer = null;
}
}
removeFromTree( )
{
if (this.expansionContainer)
{
this.expansionContainer.removeFromTree();
}
this.expansionContainer = null;
this.expansionButton = null;
super.removeFromTree();
}
getDOMNode( )
{
return this.tr[0];
}
getJNode( )
{
return this.tr;
}
getHeight( )
{
var h = super.getHeight();
if (this.expansionContainer && this.expansionVisible)
{
h += this.expansionContainer.getHeight();
}
return h;
}
getAvgHeightData( )
{
// Only take the height of the own tr into account
//var oldVisible = this.expansionVisible;
this.expansionVisible = false;
var res = {
"avgHeight": this.getHeight(),
"avgCount": 1
};
this.expansionVisible = true;
return res;
}
/** -- PRIVATE FUNCTIONS -- **/
_handleExpansionButtonClick( _callback, _context)
{
// Create the "expansionContainer" if it does not exist yet
if (!this.expansionContainer)
{
this.expansionContainer = _callback.call(_context);
this.expansionContainer.insertIntoTree(this.tr);
this.expansionVisible = false;
}
// Toggle the visibility of the expansion tr
this.expansionVisible = !this.expansionVisible;
jQuery(this.expansionContainer._nodes[0]).toggle(this.expansionVisible);
// Set the class of the arrow
if (this.expansionVisible)
{
this.expansionButton.addClass("opened");
this.expansionButton.removeClass("closed");
}
else
{
this.expansionButton.addClass("closed");
this.expansionButton.removeClass("opened");
}
this.invalidate();
}
/** -- Implementation of et2_dataview_IViewRange -- **/
setViewRange( _range)
{
if (this.expansionContainer && this.expansionVisible
&& this.expansionContainer.implements(et2_dataview_IViewRange))
{
// Substract the height of the own row from the container
var oh = jQuery(this._nodes[0]).height();
_range.top -= oh;
// Proxy the setViewRange call to the expansion container
this.expansionContainer.setViewRange(_range);
}
}
}

View File

@ -1,3 +1,4 @@
"use strict";
/**
* EGroupware eTemplate2 - Class which contains a factory method for rows
*
@ -9,7 +10,7 @@
* @copyright Stylite 2011
* @version $Id$
*/
Object.defineProperty(exports, "__esModule", { value: true });
/*egw:uses
/vendor/bower-asset/jquery/dist/jquery.js;
et2_core_inheritance;
@ -17,42 +18,33 @@
et2_core_arrayMgr;
et2_core_widget;
*/
/**
* The row provider contains prototypes (full clonable dom-trees)
* for all registered row types.
*
* @augments Class
*/
var et2_dataview_rowProvider = (function(){ "use strict"; return Class.extend(
{
var et2_dataview_rowProvider = /** @class */ (function () {
/**
*
* @param _outerId
* @param _columnIds
* @memberOf et2_dataview_rowProvider
*/
init: function(_outerId, _columnIds) {
function et2_dataview_rowProvider(_outerId, _columnIds) {
// Copy the given parameters
this._outerId = _outerId;
this._columnIds = _columnIds;
this._prototypes = {};
this._template = null;
this._mgrs = null;
this._rootWidget = null;
// Create the default row "prototypes"
this._createFullRowPrototype();
this._createDefaultPrototype();
this._createEmptyPrototype();
this._createLoadingPrototype();
},
getColumnCount: function() {
}
et2_dataview_rowProvider.prototype.getColumnCount = function () {
return this._columnIds.length;
},
};
/**
* Returns a clone of the prototype with the given name. If the generator
* callback function is given, this function is called if the prototype
@ -62,28 +54,19 @@ var et2_dataview_rowProvider = (function(){ "use strict"; return Class.extend(
* @param {function} _generator
* @param {object} _context
*/
getPrototype: function(_name, _generator, _context) {
if (typeof this._prototypes[_name] == "undefined")
{
if (typeof _generator != "undefined")
{
this._prototypes[_name] = _generator.call(_context, this._outerId,
this._columnIds);
et2_dataview_rowProvider.prototype.getPrototype = function (_name, _generator, _context) {
if (typeof this._prototypes[_name] == "undefined") {
if (typeof _generator != "undefined") {
this._prototypes[_name] = _generator.call(_context, this._outerId, this._columnIds);
}
else
{
else {
return null;
}
}
return this._prototypes[_name].clone();
},
};
/* ---- PRIVATE FUNCTIONS ---- */
_createFullRowPrototype: function() {
et2_dataview_rowProvider.prototype._createFullRowPrototype = function () {
var tr = jQuery(document.createElement("tr"));
var td = jQuery(document.createElement("td"))
.addClass(this._outerId + "_td_fullRow")
@ -92,16 +75,12 @@ var et2_dataview_rowProvider = (function(){ "use strict"; return Class.extend(
var div = jQuery(document.createElement("div"))
.addClass(this._outerId + "_div_fullRow")
.appendTo(td);
this._prototypes["fullRow"] = tr;
},
_createDefaultPrototype: function() {
};
et2_dataview_rowProvider.prototype._createDefaultPrototype = function () {
var tr = jQuery(document.createElement("tr"));
// Append a td for each column
for (var i = 0; i < this._columnIds.length; i++)
{
for (var i = 0; i < this._columnIds.length; i++) {
var td = jQuery(document.createElement("td"))
.addClass(this._outerId + "_td_" + this._columnIds[i])
.appendTo(tr);
@ -110,20 +89,17 @@ var et2_dataview_rowProvider = (function(){ "use strict"; return Class.extend(
.addClass("innerContainer")
.appendTo(td);
}
this._prototypes["default"] = tr;
},
_createEmptyPrototype: function() {
};
et2_dataview_rowProvider.prototype._createEmptyPrototype = function () {
this._prototypes["empty"] = jQuery(document.createElement("tr"));
},
_createLoadingPrototype: function() {
};
et2_dataview_rowProvider.prototype._createLoadingPrototype = function () {
var fullRow = this.getPrototype("fullRow");
jQuery("div", fullRow).addClass("loading");
this._prototypes["loading"] = fullRow;
}
});}).call(this);
};
return et2_dataview_rowProvider;
}());
exports.et2_dataview_rowProvider = et2_dataview_rowProvider;
//# sourceMappingURL=et2_dataview_view_rowProvider.js.map

View File

@ -0,0 +1,139 @@
/**
* EGroupware eTemplate2 - Class which contains a factory method for rows
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package etemplate
* @subpackage dataview
* @link http://www.egroupware.org
* @author Andreas Stöckel
* @copyright Stylite 2011
* @version $Id$
*/
/*egw:uses
/vendor/bower-asset/jquery/dist/jquery.js;
et2_core_inheritance;
et2_core_interfaces;
et2_core_arrayMgr;
et2_core_widget;
*/
/**
* The row provider contains prototypes (full clonable dom-trees)
* for all registered row types.
*/
export class et2_dataview_rowProvider
{
private _outerId: any;
private _columnIds: any;
private _prototypes: {};
private _template: null;
private _mgrs: null;
private _rootWidget: null;
/**
*
* @param _outerId
* @param _columnIds
*/
constructor( _outerId, _columnIds)
{
// Copy the given parameters
this._outerId = _outerId;
this._columnIds = _columnIds;
this._prototypes = {};
this._template = null;
this._mgrs = null;
this._rootWidget = null;
// Create the default row "prototypes"
this._createFullRowPrototype();
this._createDefaultPrototype();
this._createEmptyPrototype();
this._createLoadingPrototype();
}
public getColumnCount()
{
return this._columnIds.length;
}
/**
* Returns a clone of the prototype with the given name. If the generator
* callback function is given, this function is called if the prototype
* does not yet registered.
*
* @param {string} _name
* @param {function} _generator
* @param {object} _context
*/
getPrototype( _name : string, _generator? : Function, _context? : any)
{
if (typeof this._prototypes[_name] == "undefined")
{
if (typeof _generator != "undefined")
{
this._prototypes[_name] = _generator.call(_context, this._outerId,
this._columnIds);
}
else
{
return null;
}
}
return this._prototypes[_name].clone();
}
/* ---- PRIVATE FUNCTIONS ---- */
_createFullRowPrototype( )
{
var tr = jQuery(document.createElement("tr"));
var td = jQuery(document.createElement("td"))
.addClass(this._outerId + "_td_fullRow")
.attr("colspan", this._columnIds.length)
.appendTo(tr);
var div = jQuery(document.createElement("div"))
.addClass(this._outerId + "_div_fullRow")
.appendTo(td);
this._prototypes["fullRow"] = tr;
}
_createDefaultPrototype( )
{
var tr = jQuery(document.createElement("tr"));
// Append a td for each column
for (var i = 0; i < this._columnIds.length; i++)
{
var td = jQuery(document.createElement("td"))
.addClass(this._outerId + "_td_" + this._columnIds[i])
.appendTo(tr);
var div = jQuery(document.createElement("div"))
.addClass(this._outerId + "_div_" + this._columnIds[i])
.addClass("innerContainer")
.appendTo(td);
}
this._prototypes["default"] = tr;
}
_createEmptyPrototype( )
{
this._prototypes["empty"] = jQuery(document.createElement("tr"));
}
_createLoadingPrototype( )
{
var fullRow = this.getPrototype("fullRow");
jQuery("div", fullRow).addClass("loading");
this._prototypes["loading"] = fullRow;
}
}

View File

@ -1,3 +1,4 @@
"use strict";
/**
* EGroupware eTemplate2 - Class which contains the spacer container
*
@ -9,17 +10,29 @@
* @copyright Stylite 2011
* @version $Id$
*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
/*egw:uses
/vendor/bower-asset/jquery/dist/jquery.js;
et2_dataview_view_container;
*/
/**
* @augments et2_dataview_container
*/
var et2_dataview_spacer = (function(){ "use strict"; return et2_dataview_container.extend(
{
var et2_dataview_spacer = /** @class */ (function (_super) {
__extends(et2_dataview_spacer, _super);
/**
* Constructor
*
@ -27,79 +40,64 @@ var et2_dataview_spacer = (function(){ "use strict"; return et2_dataview_contain
* @param _rowProvider
* @memberOf et2_dataview_spacer
*/
init: function (_parent, _rowProvider) {
function et2_dataview_spacer(_parent, _rowProvider) {
var _this =
// Call the inherited container constructor
this._super(_parent);
_super.call(this, _parent) || this;
// Initialize the row count and the row height
this._count = 0;
this._rowHeight = 19;
this._avgSum = 0;
this._avgCount = 0;
_this._count = 0;
_this._rowHeight = 19;
_this._avgSum = 0;
_this._avgCount = 0;
// Get the spacer row and append it to the container
this.spacerNode = _rowProvider.getPrototype("spacer",
this._createSpacerPrototype, this);
this._phDiv = jQuery("td", this.spacerNode);
this.appendNode(this.spacerNode);
},
setCount: function (_count, _rowHeight) {
_this.spacerNode = _rowProvider.getPrototype("spacer", _this._createSpacerPrototype, _this);
_this._phDiv = jQuery("td", _this.spacerNode);
_this.appendNode(_this.spacerNode);
return _this;
}
et2_dataview_spacer.prototype.setCount = function (_count, _rowHeight) {
// Set the new count and _rowHeight if given
this._count = _count;
if (typeof _rowHeight !== "undefined")
{
if (typeof _rowHeight !== "undefined") {
this._rowHeight = _rowHeight;
}
// Update the element height
this._phDiv.height(this._count * this._rowHeight);
// Call the invalidate function
this.invalidate();
},
getCount: function () {
};
et2_dataview_spacer.prototype.getCount = function () {
return this._count;
},
getHeight: function () {
};
et2_dataview_spacer.prototype.getHeight = function () {
// Set the calculated height, so that "invalidate" will work correctly
this._height = this._count * this._rowHeight;
return this._height;
},
getAvgHeightData: function () {
if (this._avgCount > 0)
{
};
et2_dataview_spacer.prototype.getAvgHeightData = function () {
if (this._avgCount > 0) {
return {
"avgHeight": this._avgSum / this._avgCount,
"avgCount": this._avgCount
};
}
return null;
},
addAvgHeight: function (_height) {
};
et2_dataview_spacer.prototype.addAvgHeight = function (_height) {
this._avgSum += _height;
this._avgCount++;
},
};
/* ---- PRIVATE FUNCTIONS ---- */
_createSpacerPrototype: function (_outerId, _columnIds) {
et2_dataview_spacer.prototype._createSpacerPrototype = function (_outerId, _columnIds) {
var tr = jQuery(document.createElement("tr"));
var td = jQuery(document.createElement("td"))
.addClass("egwGridView_spacer")
.addClass(_outerId + "_spacer_fullRow")
.attr("colspan", _columnIds.length)
.appendTo(tr);
return tr;
}
});}).call(this);
};
return et2_dataview_spacer;
}(et2_dataview_container));
exports.et2_dataview_spacer = et2_dataview_spacer;
//# sourceMappingURL=et2_dataview_view_spacer.js.map

View File

@ -0,0 +1,112 @@
/**
* EGroupware eTemplate2 - Class which contains the spacer container
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package etemplate
* @subpackage dataview
* @link http://www.egroupware.org
* @author Andreas Stöckel
* @copyright Stylite 2011
* @version $Id$
*/
/*egw:uses
/vendor/bower-asset/jquery/dist/jquery.js;
et2_dataview_view_container;
*/
/**
* @augments et2_dataview_container
*/
export class et2_dataview_spacer extends et2_dataview_container
{
/**
* Constructor
*
* @param _parent
* @param _rowProvider
* @memberOf et2_dataview_spacer
*/
constructor( _parent, _rowProvider)
{
// Call the inherited container constructor
super(_parent);
// Initialize the row count and the row height
this._count = 0;
this._rowHeight = 19;
this._avgSum = 0;
this._avgCount = 0;
// Get the spacer row and append it to the container
this.spacerNode = _rowProvider.getPrototype("spacer",
this._createSpacerPrototype, this);
this._phDiv = jQuery("td", this.spacerNode);
this.appendNode(this.spacerNode);
}
setCount( _count, _rowHeight)
{
// Set the new count and _rowHeight if given
this._count = _count;
if (typeof _rowHeight !== "undefined")
{
this._rowHeight = _rowHeight;
}
// Update the element height
this._phDiv.height(this._count * this._rowHeight);
// Call the invalidate function
this.invalidate();
}
getCount( )
{
return this._count;
}
getHeight( )
{
// Set the calculated height, so that "invalidate" will work correctly
this._height = this._count * this._rowHeight;
return this._height;
}
getAvgHeightData( )
{
if (this._avgCount > 0)
{
return {
"avgHeight": this._avgSum / this._avgCount,
"avgCount": this._avgCount
};
}
return null;
}
addAvgHeight( _height)
{
this._avgSum += _height;
this._avgCount++;
}
/* ---- PRIVATE FUNCTIONS ---- */
_createSpacerPrototype( _outerId, _columnIds)
{
var tr = jQuery(document.createElement("tr"));
var td = jQuery(document.createElement("td"))
.addClass("egwGridView_spacer")
.addClass(_outerId + "_spacer_fullRow")
.attr("colspan", _columnIds.length)
.appendTo(tr);
return tr;
}
}

View File

@ -1,3 +1,4 @@
"use strict";
/**
* EGroupware eTemplate2 - dataview code
*
@ -9,24 +10,33 @@
* @copyright Nathan Gray 2014
* @version $Id: et2_dataview_view_container_1.js 46338 2014-03-20 09:40:37Z ralfbecker $
*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
/*egw:uses
/vendor/bower-asset/jquery/dist/jquery.js;
et2_dataview_interfaces;
*/
/**
* Displays tiles or thumbnails (squares) instead of full rows.
*
* It's important that the template specifies a fixed width and height (via CSS)
* so that the rows and columns work out properly.
*
* @augments et2_dataview_container
*/
var et2_dataview_tile = (function(){ "use strict"; return et2_dataview_row.extend([],
{
columns: 4,
var et2_dataview_tile = /** @class */ (function (_super) {
__extends(et2_dataview_tile, _super);
/**
* Creates the row container. Use the "setRow" function to load the actual
* row content.
@ -34,26 +44,25 @@ var et2_dataview_tile = (function(){ "use strict"; return et2_dataview_row.exten
* @param _parent is the row parent container.
* @memberOf et2_dataview_row
*/
init: function(_parent) {
function et2_dataview_tile(_parent) {
var _this =
// Call the inherited constructor
this._super(_parent);
_super.call(this, _parent) || this;
_this.columns = 4;
// Make sure the needed class is there to get the CSS
this.tr.addClass('tile');
},
makeExpandable: function (_expandable, _callback, _context) {
_this.tr.addClass('tile');
return _this;
}
et2_dataview_tile.prototype.makeExpandable = function (_expandable, _callback, _context) {
// Nope. It mostly works, it's just weird.
},
getAvgHeightData: function() {
};
et2_dataview_tile.prototype.getAvgHeightData = function () {
var res = {
"avgHeight": this.getHeight() / this.columns,
"avgCount": this.columns
};
return res;
},
};
/**
* Returns the height for the tile.
*
@ -61,44 +70,39 @@ var et2_dataview_tile = (function(){ "use strict"; return et2_dataview_row.exten
* height. If this should be another tile in the same row, we say it has 0 height.
* @returns {Number}
*/
getHeight: function() {
if(this._index % this.columns == 0)
{
return this._super();
et2_dataview_tile.prototype.getHeight = function () {
if (this._index % this.columns == 0) {
return _super.prototype.getHeight.call(this);
}
else
{
else {
return 0;
}
},
};
/**
* Broadcasts an invalidation through the container tree. Marks the own
* height as invalid.
*/
invalidate: function() {
if(this._inTree && this.tr)
{
var template_width = jQuery('.innerContainer',this.tr).children().outerWidth(true);
if(template_width)
{
et2_dataview_tile.prototype.invalidate = function () {
if (this._inTree && this.tr) {
var template_width = jQuery('.innerContainer', this.tr).children().outerWidth(true);
if (template_width) {
this.tr.css('width', template_width + (this.tr.outerWidth(true) - this.tr.width()));
}
}
this._recalculate_columns();
this._super();
},
_super.prototype.invalidate.call(this);
};
/**
* Recalculate how many columns we can fit in a row.
* While browser takes care of the actual layout, we need this for proper
* pagination.
*/
_recalculate_columns: function() {
if(this._inTree && this.tr && this.tr.parent())
{
this.columns = Math.max(1,parseInt(this.tr.parent().innerWidth() / this.tr.outerWidth(true)));
et2_dataview_tile.prototype._recalculate_columns = function () {
if (this._inTree && this.tr && this.tr.parent()) {
this.columns = Math.max(1, parseInt(this.tr.parent().innerWidth() / this.tr.outerWidth(true)));
}
}
});}).call(this);
};
return et2_dataview_tile;
}(et2_dataview_row));
exports.et2_dataview_tile = et2_dataview_tile;
//# sourceMappingURL=et2_dataview_view_tile.js.map

View File

@ -0,0 +1,107 @@
/**
* EGroupware eTemplate2 - dataview code
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package etemplate
* @subpackage dataview
* @link http://www.egroupware.org
* @author Nathan Gray
* @copyright Nathan Gray 2014
* @version $Id: et2_dataview_view_container_1.js 46338 2014-03-20 09:40:37Z ralfbecker $
*/
/*egw:uses
/vendor/bower-asset/jquery/dist/jquery.js;
et2_dataview_interfaces;
*/
/**
* Displays tiles or thumbnails (squares) instead of full rows.
*
* It's important that the template specifies a fixed width and height (via CSS)
* so that the rows and columns work out properly.
*
*/
export class et2_dataview_tile extends et2_dataview_row {
columns: number = 4;
/**
* Creates the row container. Use the "setRow" function to load the actual
* row content.
*
* @param _parent is the row parent container.
* @memberOf et2_dataview_row
*/
constructor(_parent)
{
// Call the inherited constructor
super(_parent);
// Make sure the needed class is there to get the CSS
this.tr.addClass('tile');
}
makeExpandable(_expandable, _callback, _context)
{
// Nope. It mostly works, it's just weird.
}
getAvgHeightData()
{
var res = {
"avgHeight": this.getHeight() / this.columns,
"avgCount": this.columns
};
return res;
}
/**
* Returns the height for the tile.
*
* This is where we do the magic. If a new row should start, we return the proper
* height. If this should be another tile in the same row, we say it has 0 height.
* @returns {Number}
*/
getHeight()
{
if (this._index % this.columns == 0)
{
return super.getHeight();
}
else
{
return 0;
}
}
/**
* Broadcasts an invalidation through the container tree. Marks the own
* height as invalid.
*/
invalidate()
{
if (this._inTree && this.tr)
{
var template_width = jQuery('.innerContainer', this.tr).children().outerWidth(true);
if (template_width)
{
this.tr.css('width', template_width + (this.tr.outerWidth(true) - this.tr.width()));
}
}
this._recalculate_columns();
super.invalidate();
}
/**
* Recalculate how many columns we can fit in a row.
* While browser takes care of the actual layout, we need this for proper
* pagination.
*/
_recalculate_columns()
{
if (this._inTree && this.tr && this.tr.parent())
{
this.columns = Math.max(1, parseInt(this.tr.parent().innerWidth() / this.tr.outerWidth(true)));
}
}
}

View File

@ -9,21 +9,8 @@
* @author Andreas Stöckel
* @copyright Stylite 2011
* @version $Id$
*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
*
/*egw:uses
// Include the action system
@ -46,14 +33,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
et2_extension_customfields;
// Include all nextmatch subclasses
et2_extension_nextmatch_controller;
et2_extension_nextmatch_rowProvider;
et2_extension_nextmatch_controller;
et2_extension_nextmatch_dynheight;
// Include the grid classes
et2_dataview;
*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
require("./et2_core_common");
require("./et2_core_interfaces");
var et2_core_widget_1 = require("./et2_core_widget");
@ -62,6 +63,10 @@ var et2_core_baseWidget_1 = require("./et2_core_baseWidget");
var et2_core_inputWidget_1 = require("./et2_core_inputWidget");
var et2_widget_selectbox_1 = require("./et2_widget_selectbox");
var et2_core_inheritance_1 = require("./et2_core_inheritance");
var et2_extension_nextmatch_rowProvider_1 = require("./et2_extension_nextmatch_rowProvider");
var et2_extension_nextmatch_controller_1 = require("./et2_extension_nextmatch_controller");
var et2_dataview_1 = require("./et2_dataview");
var et2_dataview_model_columns_1 = require("./et2_dataview_model_columns");
var et2_INextmatchHeader = "et2_INextmatchHeader";
function implements_et2_INextmatchHeader(obj) {
return implements_methods(obj, ["setNextmatch"]);
@ -89,15 +94,15 @@ function implements_et2_INextmatchSortable(obj) {
* +--------------+-----------+-------+
* @augments et2_DOMWidget
*/
var et2_nextmatch = /** @class */ (function (_super_1) {
__extends(et2_nextmatch, _super_1);
var et2_nextmatch = /** @class */ (function (_super) {
__extends(et2_nextmatch, _super);
/**
* Constructor
*
* @memberOf et2_nextmatch
*/
function et2_nextmatch(_parent, _attrs, _child) {
var _this = _super_1.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_nextmatch._attributes, _child || {})) || this;
var _this = _super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_nextmatch._attributes, _child || {})) || this;
_this.activeFilters = { col_filter: {} };
_this.columns = [];
// keeps sorted columns
@ -128,7 +133,7 @@ var et2_nextmatch = /** @class */ (function (_super_1) {
// container.
_this.dynheight = _this._getDynheight();
// Create the outer grid container
_this.dataview = new et2_dataview(_this.innerDiv, _this.egw());
_this.dataview = new et2_dataview_1.et2_dataview(_this.innerDiv, _this.egw());
// Blank placeholder
_this.blank = jQuery(document.createElement("div"))
.appendTo(_this.dataview.table);
@ -151,15 +156,15 @@ var et2_nextmatch = /** @class */ (function (_super_1) {
jQuery(this.getInstanceManager().DOMContainer.parentNode).off('show.et2_nextmatch');
jQuery(this.getInstanceManager().DOMContainer.parentNode).off('hide.et2_nextmatch');
// Free the grid components
this.dataview.free();
this.dataview.destroy();
if (this.rowProvider) {
this.rowProvider.free();
this.rowProvider.destroy();
}
if (this.controller) {
this.controller.free();
this.controller.destroy();
}
this.dynheight.free();
_super_1.prototype.destroy.call(this);
this.dynheight.destroy();
_super.prototype.destroy.call(this);
};
/**
* Loads the nextmatch settings
@ -167,7 +172,7 @@ var et2_nextmatch = /** @class */ (function (_super_1) {
* @param {object} _attrs
*/
et2_nextmatch.prototype.transformAttributes = function (_attrs) {
_super_1.prototype.transformAttributes.call(this, _attrs);
_super.prototype.transformAttributes.call(this, _attrs);
if (this.id) {
var entry = this.getArrayMgr("content").data;
_attrs["settings"] = {};
@ -188,7 +193,7 @@ var et2_nextmatch = /** @class */ (function (_super_1) {
}
};
et2_nextmatch.prototype.doLoadingFinished = function () {
_super_1.prototype.doLoadingFinished.call(this);
_super.prototype.doLoadingFinished.call(this);
if (!this.dynheight) {
this.dynheight = this._getDynheight();
}
@ -866,11 +871,11 @@ var et2_nextmatch = /** @class */ (function (_super_1) {
"widget": _row[x].widget
}, _colData[x]);
var visibility = (!_colData[x] || _colData[x].visible) ?
et2_dataview_grid.ET2_COL_VISIBILITY_VISIBLE :
et2_dataview_grid.ET2_COL_VISIBILITY_INVISIBLE;
et2_dataview_model_columns_1.et2_dataview_column.ET2_COL_VISIBILITY_VISIBLE :
et2_dataview_model_columns_1.et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE;
if (_colData[x].disabled && _colData[x].disabled !== '' &&
this.getArrayMgr("content").parseBoolExpression(_colData[x].disabled)) {
visibility = et2_dataview_grid.ET2_COL_VISIBILITY_DISABLED;
visibility = et2_dataview_model_columns_1.et2_dataview_column.ET2_COL_VISIBILITY_DISABLED;
}
columnData[x] = {
"id": "col_" + x,
@ -914,11 +919,7 @@ var et2_nextmatch = /** @class */ (function (_super_1) {
this.addChild(_row[x].widget);
}
// Create the nextmatch row provider
/* TODO
this.rowProvider = new et2_nextmatch_rowProvider(
this.dataview.rowProvider, this._getSubgrid, this);
*/
this.rowProvider = new et2_extension_nextmatch_rowProvider_1.et2_nextmatch_rowProvider(this.dataview.rowProvider, this._getSubgrid, this);
// Register handler to update preferences when column properties are changed
var self = this;
this.dataview.onUpdateColumns = function () {
@ -962,11 +963,9 @@ var et2_nextmatch = /** @class */ (function (_super_1) {
columnWidgets[x].align = _row[x].align;
}
}
return;
// TODO
this.rowProvider.setDataRowTemplate(columnWidgets, _rowData, this);
// Create the grid controller
this.controller = new et2_nextmatch_controller(null, this.egw(), this.getInstanceManager().etemplate_exec_id, this, null, this.dataview.grid, this.rowProvider, this.options.settings.action_links, null, this.options.actions);
this.controller = new et2_extension_nextmatch_controller_1.et2_nextmatch_controller(null, this.egw(), this.getInstanceManager().etemplate_exec_id, this, null, this.dataview.grid, this.rowProvider, this.options.settings.action_links, null, this.options.actions);
// Need to trigger empty row the first time
if (total == 0)
this.controller._emptyRow();
@ -1018,11 +1017,11 @@ var et2_nextmatch = /** @class */ (function (_super_1) {
// parent grid
var grid = new et2_dataview_grid(_row, this.dataview.grid);
// Create a new controller for the grid
var controller = new et2_nextmatch_controller(_controller, this.egw(), this.getInstanceManager().etemplate_exec_id, this, rowId, grid, this.rowProvider, this.options.settings.action_links, _controller.getObjectManager());
var controller = new et2_extension_nextmatch_controller_1.et2_nextmatch_controller(_controller, this.egw(), this.getInstanceManager().etemplate_exec_id, this, rowId, grid, this.rowProvider, this.options.settings.action_links, _controller.getObjectManager());
controller.update();
// Register inside the destruction callback of the grid
grid.setDestroyCallback(function () {
controller.free();
controller.destroy();
});
return grid;
};
@ -1396,9 +1395,9 @@ var et2_nextmatch = /** @class */ (function (_super_1) {
return;
}
// Free the grid components - they'll be re-created as the template is processed
this.dataview.free();
this.rowProvider.free();
this.controller.free();
this.dataview.destroy();
this.rowProvider.destroy();
this.controller.destroy();
// Free any children from previous template
// They may get left behind because of how detached nodes are processed
// We don't use iterateOver because it checks sub-children
@ -1414,7 +1413,7 @@ var et2_nextmatch = /** @class */ (function (_super_1) {
if (this.template == this.options.settings.columnselection_pref) {
this.options.settings.columnselection_pref = template_name;
}
this.dataview = new et2_dataview(this.innerDiv, this.egw());
this.dataview = new et2_dataview_1.et2_dataview(this.innerDiv, this.egw());
}
// Create the template
if (template_name) {
@ -1549,7 +1548,7 @@ var et2_nextmatch = /** @class */ (function (_super_1) {
*/
et2_nextmatch.prototype.set_disabled = function (_value) {
var previous = this.disabled;
_super_1.prototype.set_disabled.call(this, _value);
_super.prototype.set_disabled.call(this, _value);
if (previous && !_value) {
this.resize();
}
@ -1663,7 +1662,7 @@ var et2_nextmatch = /** @class */ (function (_super_1) {
// Fade out nicely
status.delay(linked ? 1 : 2000)
.fadeOut(500, function () {
link.free();
link.destroy();
status.remove();
});
});
@ -2041,8 +2040,8 @@ et2_core_widget_1.et2_register_widget(et2_nextmatch, ["nextmatch"]);
* actually load templates from the server.
* @augments et2_DOMWidget
*/
var et2_nextmatch_header_bar = /** @class */ (function (_super_1) {
__extends(et2_nextmatch_header_bar, _super_1);
var et2_nextmatch_header_bar = /** @class */ (function (_super) {
__extends(et2_nextmatch_header_bar, _super);
/**
* Constructor
*
@ -2051,7 +2050,7 @@ var et2_nextmatch_header_bar = /** @class */ (function (_super_1) {
* @memberOf et2_nextmatch_header_bar
*/
function et2_nextmatch_header_bar(_parent, _attrs, _child) {
var _this = _super_1.call(this, _parent, [_parent, _parent.options.settings], et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_nextmatch_header_bar._attributes, _child || {})) || this;
var _this = _super.call(this, _parent, [_parent, _parent.options.settings], et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_nextmatch_header_bar._attributes, _child || {})) || this;
_this.nextmatch = _parent;
_this.div = jQuery(document.createElement("div"))
.addClass("nextmatch_header");
@ -2062,7 +2061,7 @@ var et2_nextmatch_header_bar = /** @class */ (function (_super_1) {
}
et2_nextmatch_header_bar.prototype.destroy = function () {
this.nextmatch = null;
_super_1.prototype.destroy.call(this);
_super.prototype.destroy.call(this);
this.div = null;
};
et2_nextmatch_header_bar.prototype.setNextmatch = function (nextmatch) {
@ -2587,15 +2586,15 @@ et2_core_widget_1.et2_register_widget(et2_nextmatch_header_bar, ["nextmatch_head
*
* @augments et2_baseWidget
*/
var et2_nextmatch_header = /** @class */ (function (_super_1) {
__extends(et2_nextmatch_header, _super_1);
var et2_nextmatch_header = /** @class */ (function (_super) {
__extends(et2_nextmatch_header, _super);
/**
* Constructor
*
* @memberOf et2_nextmatch_header
*/
function et2_nextmatch_header(_parent, _attrs, _child) {
var _this = _super_1.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_nextmatch_header._attributes, _child || {})) || this;
var _this = _super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_nextmatch_header._attributes, _child || {})) || this;
_this.labelNode = jQuery(document.createElement("span"));
_this.nextmatch = null;
_this.setDOMNode(_this.labelNode[0]);
@ -2627,24 +2626,24 @@ et2_core_widget_1.et2_register_widget(et2_nextmatch_header, ['nextmatch-header']
*
* TODO This should extend customfield widget when it's ready, put the whole column in constructor() back too
*/
var et2_nextmatch_customfields = /** @class */ (function (_super_1) {
__extends(et2_nextmatch_customfields, _super_1);
var et2_nextmatch_customfields = /** @class */ (function (_super) {
__extends(et2_nextmatch_customfields, _super);
/**
* Constructor
*
* @memberOf et2_nextmatch_customfields
*/
function et2_nextmatch_customfields(_parent, _attrs, _child) {
return _super_1.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_nextmatch_customfields._attributes, _child || {})) || this;
return _super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_nextmatch_customfields._attributes, _child || {})) || this;
// Specifically take the whole column
// this.table.css("width", "100%");
}
et2_nextmatch_customfields.prototype.destroy = function () {
this.nextmatch = null;
_super_1.prototype.destroy.call(this);
_super.prototype.destroy.call(this);
};
et2_nextmatch_customfields.prototype.transformAttributes = function (_attrs) {
_super_1.prototype.transformAttributes.call(this, _attrs);
_super.prototype.transformAttributes.call(this, _attrs);
// Add in settings that are objects
if (!_attrs.customfields) {
// Check for custom stuff (unlikely)
@ -2744,7 +2743,7 @@ var et2_nextmatch_customfields = /** @class */ (function (_super_1) {
* @param {array} _fields
*/
et2_nextmatch_customfields.prototype.set_visible = function (_fields) {
_super_1.prototype.set_visible.call(this, _fields);
_super.prototype.set_visible.call(this, _fields);
// Find data row, and do it too
var self = this;
if (this.nextmatch) {
@ -2807,21 +2806,21 @@ et2_core_widget_1.et2_register_widget(et2_nextmatch_customfields, ['nextmatch-cu
* @augments et2_nextmatch_header
*/
// @ts-ignore
var et2_nextmatch_sortheader = /** @class */ (function (_super_1) {
__extends(et2_nextmatch_sortheader, _super_1);
var et2_nextmatch_sortheader = /** @class */ (function (_super) {
__extends(et2_nextmatch_sortheader, _super);
/**
* Constructor
*
* @memberOf et2_nextmatch_sortheader
*/
function et2_nextmatch_sortheader(_parent, _attrs, _child) {
var _this = _super_1.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_nextmatch_sortheader._attributes, _child || {})) || this;
var _this = _super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_nextmatch_sortheader._attributes, _child || {})) || this;
_this.sortmode = "none";
_this.labelNode.addClass("nextmatch_sortheader none");
return _this;
}
et2_nextmatch_sortheader.prototype.click = function (_event) {
if (this.nextmatch && _super_1.prototype.click.call(this, _event)) {
if (this.nextmatch && _super.prototype.click.call(this, _event)) {
// Send default sort mode if not sorted, otherwise send undefined to calculate
this.nextmatch.sortBy(this.id, this.sortmode == "none" ? !(this.options.sortmode.toUpperCase() == "DESC") : undefined);
return true;
@ -2857,10 +2856,10 @@ et2_core_widget_1.et2_register_widget(et2_nextmatch_sortheader, ['nextmatch-sort
/**
* @augments et2_selectbox
*/
var et2_nextmatch_filterheader = /** @class */ (function (_super_1) {
__extends(et2_nextmatch_filterheader, _super_1);
var et2_nextmatch_filterheader = /** @class */ (function (_super) {
__extends(et2_nextmatch_filterheader, _super);
function et2_nextmatch_filterheader() {
return _super_1 !== null && _super_1.apply(this, arguments) || this;
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Override to add change handler
@ -2872,7 +2871,7 @@ var et2_nextmatch_filterheader = /** @class */ (function (_super_1) {
if (!this.options.empty_label && (!this.options.select_options || !this.options.select_options[""])) {
this.options.empty_label = this.options.label ? this.options.label : egw.lang("All");
}
_super_1.prototype.createInputWidget.call(this);
_super.prototype.createInputWidget.call(this);
jQuery(this.getInputNode()).change(this, function (event) {
if (typeof event.data.nextmatch == 'undefined') {
// Not fully set up yet
@ -2911,10 +2910,10 @@ et2_core_widget_1.et2_register_widget(et2_nextmatch_filterheader, ['nextmatch-fi
/**
* @augments et2_selectAccount
*/
var et2_nextmatch_accountfilterheader = /** @class */ (function (_super_1) {
__extends(et2_nextmatch_accountfilterheader, _super_1);
var et2_nextmatch_accountfilterheader = /** @class */ (function (_super) {
__extends(et2_nextmatch_accountfilterheader, _super);
function et2_nextmatch_accountfilterheader() {
return _super_1 !== null && _super_1.apply(this, arguments) || this;
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Override to add change handler
@ -2926,7 +2925,7 @@ var et2_nextmatch_accountfilterheader = /** @class */ (function (_super_1) {
if (!this.options.empty_label && !this.options.select_options[""]) {
this.options.empty_label = this.options.label ? this.options.label : egw.lang("All");
}
this._super.apply(this, arguments);
_super.prototype.createInputWidget.call(this, this, arguments);
this.input.change(this, function (event) {
if (typeof event.data.nextmatch == 'undefined') {
// Not fully set up yet
@ -2968,10 +2967,10 @@ et2_core_widget_1.et2_register_widget(et2_nextmatch_accountfilterheader, ['nextm
*
* @augments et2_taglist
*/
var et2_nextmatch_taglistheader = /** @class */ (function (_super_1) {
__extends(et2_nextmatch_taglistheader, _super_1);
var et2_nextmatch_taglistheader = /** @class */ (function (_super) {
__extends(et2_nextmatch_taglistheader, _super);
function et2_nextmatch_taglistheader() {
return _super_1 !== null && _super_1.apply(this, arguments) || this;
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Override to add change handler
@ -2983,7 +2982,7 @@ var et2_nextmatch_taglistheader = /** @class */ (function (_super_1) {
if (!this.options.empty_label && (!this.options.select_options || !this.options.select_options[""])) {
this.options.empty_label = this.options.label ? this.options.label : egw.lang("All");
}
_super_1.prototype.createInputWidget.call(this);
_super.prototype.createInputWidget.call(this);
};
/**
* Disable toggle if there are 2 or less options
@ -2993,7 +2992,7 @@ var et2_nextmatch_taglistheader = /** @class */ (function (_super_1) {
if (options && options.length <= 2 && this.options.multiple == 'toggle') {
this.set_multiple(false);
}
_super_1.prototype.set_select_options.call(this, options);
_super.prototype.set_select_options.call(this, options);
};
/**
* Set nextmatch is the function which has to be implemented for the
@ -3014,7 +3013,7 @@ var et2_nextmatch_taglistheader = /** @class */ (function (_super_1) {
et2_nextmatch_taglistheader.prototype.resize = function () {
this.div.css("height", '');
this.div.css("max-width", jQuery(this.parentNode).innerWidth() + "px");
_super_1.prototype.resize.call(this);
_super.prototype.resize.call(this);
};
et2_nextmatch_taglistheader._attributes = {
autocomplete_url: { default: '' },
@ -3042,10 +3041,10 @@ et2_core_widget_1.et2_register_widget(et2_nextmatch_taglistheader, ['nextmatch-t
/**
* @augments et2_link_entry
*/
var et2_nextmatch_entryheader = /** @class */ (function (_super_1) {
__extends(et2_nextmatch_entryheader, _super_1);
var et2_nextmatch_entryheader = /** @class */ (function (_super) {
__extends(et2_nextmatch_entryheader, _super);
function et2_nextmatch_entryheader() {
return _super_1 !== null && _super_1.apply(this, arguments) || this;
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Override to add change handler
@ -3065,7 +3064,7 @@ var et2_nextmatch_entryheader = /** @class */ (function (_super_1) {
* id, the original parent value is returned.
*/
et2_nextmatch_entryheader.prototype.getValue = function () {
var value = _super_1.prototype.getValue.call(this);
var value = _super.prototype.getValue.call(this);
if (typeof value == "object" && value != null) {
if (!value.app || !value.id)
return null;
@ -3108,8 +3107,8 @@ et2_core_widget_1.et2_register_widget(et2_nextmatch_entryheader, ['nextmatch-ent
/**
* @augments et2_nextmatch_filterheader
*/
var et2_nextmatch_customfilter = /** @class */ (function (_super_1) {
__extends(et2_nextmatch_customfilter, _super_1);
var et2_nextmatch_customfilter = /** @class */ (function (_super) {
__extends(et2_nextmatch_customfilter, _super);
/**
* Constructor
*
@ -3118,7 +3117,7 @@ var et2_nextmatch_customfilter = /** @class */ (function (_super_1) {
* @memberOf et2_nextmatch_customfilter
*/
function et2_nextmatch_customfilter(_parent, _attrs, _child) {
var _this = _super_1.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_nextmatch_customfilter._attributes, _child || {})) || this;
var _this = _super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_nextmatch_customfilter._attributes, _child || {})) || this;
switch (_attrs.widget_type) {
case "link-entry":
_attrs.type = 'nextmatch-entryheader';
@ -3133,7 +3132,7 @@ var et2_nextmatch_customfilter = /** @class */ (function (_super_1) {
}
jQuery.extend(_attrs.widget_options, { id: _this.id });
_attrs.id = '';
_this = _super_1.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_nextmatch_customfilter._attributes, _child || {})) || this;
_this = _super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_nextmatch_customfilter._attributes, _child || {})) || this;
_this.real_node = et2_createWidget(_attrs.type, _attrs.widget_options, _this.getParent());
var select_options = [];
var correct_type = _attrs.type;

View File

@ -8,7 +8,7 @@
* @author Andreas Stöckel
* @copyright Stylite 2011
* @version $Id$
*/
*
/*egw:uses
@ -32,8 +32,8 @@
et2_extension_customfields;
// Include all nextmatch subclasses
et2_extension_nextmatch_controller;
et2_extension_nextmatch_rowProvider;
et2_extension_nextmatch_controller;
et2_extension_nextmatch_dynheight;
// Include the grid classes
@ -51,6 +51,11 @@ import {et2_inputWidget} from "./et2_core_inputWidget";
import {et2_selectbox} from "./et2_widget_selectbox";
import {ClassWithAttributes} from "./et2_core_inheritance";
import {et2_nextmatch_rowProvider} from "./et2_extension_nextmatch_rowProvider";
import {et2_nextmatch_controller} from "./et2_extension_nextmatch_controller";
import {et2_dataview} from "./et2_dataview";
import {et2_dataview_column} from "./et2_dataview_model_columns";
/**
* Interface all special nextmatch header elements have to implement.
*/
@ -305,16 +310,16 @@ export class et2_nextmatch extends et2_DOMWidget implements et2_IResizeable, et2
jQuery(this.getInstanceManager().DOMContainer.parentNode).off('hide.et2_nextmatch');
// Free the grid components
this.dataview.free();
this.dataview.destroy();
if(this.rowProvider)
{
this.rowProvider.free();
this.rowProvider.destroy();
}
if(this.controller)
{
this.controller.free();
this.controller.destroy();
}
this.dynheight.free();
this.dynheight.destroy();
super.destroy();
}
@ -1214,12 +1219,12 @@ export class et2_nextmatch extends et2_DOMWidget implements et2_IResizeable, et2
},_colData[x]);
var visibility = (!_colData[x] || _colData[x].visible) ?
et2_dataview_grid.ET2_COL_VISIBILITY_VISIBLE :
et2_dataview_grid.ET2_COL_VISIBILITY_INVISIBLE;
et2_dataview_column.ET2_COL_VISIBILITY_VISIBLE :
et2_dataview_column.ET2_COL_VISIBILITY_INVISIBLE;
if(_colData[x].disabled && _colData[x].disabled !=='' &&
this.getArrayMgr("content").parseBoolExpression(_colData[x].disabled))
{
visibility = et2_dataview_grid.ET2_COL_VISIBILITY_DISABLED;
visibility = et2_dataview_column.ET2_COL_VISIBILITY_DISABLED;
}
columnData[x] = {
"id": "col_" + x,
@ -1277,12 +1282,9 @@ export class et2_nextmatch extends et2_DOMWidget implements et2_IResizeable, et2
}
// Create the nextmatch row provider
/* TODO
this.rowProvider = new et2_nextmatch_rowProvider(
this.dataview.rowProvider, this._getSubgrid, this);
*/
// Register handler to update preferences when column properties are changed
var self = this;
this.dataview.onUpdateColumns = function() {
@ -1341,11 +1343,8 @@ export class et2_nextmatch extends et2_DOMWidget implements et2_IResizeable, et2
}
}
return;
// TODO
this.rowProvider.setDataRowTemplate(columnWidgets, _rowData, this);
// Create the grid controller
this.controller = new et2_nextmatch_controller(
null,
@ -1445,7 +1444,7 @@ export class et2_nextmatch extends et2_DOMWidget implements et2_IResizeable, et2
// Register inside the destruction callback of the grid
grid.setDestroyCallback(function () {
controller.free();
controller.destroy();
});
return grid;
@ -1906,9 +1905,9 @@ export class et2_nextmatch extends et2_DOMWidget implements et2_IResizeable, et2
}
// Free the grid components - they'll be re-created as the template is processed
this.dataview.free();
this.rowProvider.free();
this.controller.free();
this.dataview.destroy();
this.rowProvider.destroy();
this.controller.destroy();
// Free any children from previous template
// They may get left behind because of how detached nodes are processed
@ -2251,7 +2250,7 @@ export class et2_nextmatch extends et2_DOMWidget implements et2_IResizeable, et2
// Fade out nicely
status.delay(linked ? 1 : 2000)
.fadeOut(500, function() {
link.free();
link.destroy();
status.remove();
});
@ -3783,7 +3782,7 @@ class et2_nextmatch_accountfilterheader extends et2_selectAccount implements et2
{
this.options.empty_label = this.options.label ? this.options.label : egw.lang("All");
}
this._super.apply(this, arguments);
super.createInputWidget(this, arguments);
this.input.change(this, function(event) {
if(typeof event.data.nextmatch == 'undefined')

View File

@ -1,3 +1,4 @@
"use strict";
/**
* EGroupware eTemplate2 - Class which contains a the data model for nextmatch widgets
*
@ -8,7 +9,7 @@
* @author Andreas Stöckel
* @copyright Stylite 2012
* @version $Id$
*/
*
/*egw:uses
et2_core_common;
@ -23,16 +24,27 @@
egw_data;
*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var et2_dataview_view_row_1 = require("./et2_dataview_view_row");
var et2_dataview_view_tile_1 = require("./et2_dataview_view_tile");
/**
* @augments et2_dataview_controller
*/
var et2_nextmatch_controller = (function(){ "use strict"; return et2_dataview_controller.extend(et2_IDataProvider,
{
// Display constants
VIEW_ROW: 'row',
VIEW_TILE: 'tile',
var et2_nextmatch_controller = /** @class */ (function (_super) {
__extends(et2_nextmatch_controller, _super);
/**
* Initializes the nextmatch controller.
*
@ -49,260 +61,216 @@ var et2_nextmatch_controller = (function(){ "use strict"; return et2_dataview_co
* is given.
* @memberOf et2_nextmatch_controller
*/
init: function (_parentController, _egw, _execId, _widget, _parentId,
_grid, _rowProvider, _actionLinks, _objectManager, _actions) {
function et2_nextmatch_controller(_parentController, _egw, _execId, _widget, _parentId, _grid, _rowProvider, _actionLinks, _objectManager, _actions) {
var _this =
// Call the parent et2_dataview_controller constructor
_super.call(this, _parentController, _grid) || this;
_this.setDataProvider(_this);
_this.setRowCallback(_this._rowCallback);
_this.setLinkCallback(_this._linkCallback);
_this.setContext(_this);
// Copy the egw reference
this.egw = _egw;
_this.egw = _egw;
// Keep a reference to the widget
this._widget = _widget;
_this._widget = _widget;
// Copy the given parameters
this._actionLinks = _actionLinks;
this._execId = _execId;
_this._actionLinks = _actionLinks;
_this._execId = _execId;
// Get full widget ID, including path
var id = _widget.getArrayMgr('content').getPath();
if(typeof id == 'string')
{
this._widgetId = id;
if (typeof id == 'string') {
_this._widgetId = id;
}
else if (id.length === 1)
{
this._widgetId = id[0];
else if (id.length === 1) {
_this._widgetId = id[0];
}
else
{
this._widgetId = id.shift() + '[' + id.join('][') + ']';
else {
_this._widgetId = id.shift() + '[' + id.join('][') + ']';
}
this._parentId = _parentId;
this._rowProvider = _rowProvider;
_this._parentId = _parentId;
_this._rowProvider = _rowProvider;
// Initialize the action and the object manager
// _initActions calls _init_link_dnd, which uses this._actionLinks,
// so this must happen after the above parameter copying
if (!_objectManager)
{
this._initActions(_actions);
if (!_objectManager) {
_this._initActions(_actions);
}
else
{
this._actionManager = null;
this._objectManager = _objectManager;
else {
_this._actionManager = null;
_this._objectManager = _objectManager;
}
_this.setActionObjectManager(_this._objectManager);
// Add our selection callback to selection manager
var self = this;
this._objectManager.setSelectedCallback = function() {self._selectCallback.apply(self,[this,arguments]);};
// Call the parent et2_dataview_controller constructor
this._super(_parentController, _grid, this, this._rowCallback,
this._linkCallback, this, this._objectManager);
var self = _this;
_this._objectManager.setSelectedCallback = function () { self._selectCallback.apply(self, [this, arguments]); };
// We start with no filters
this._filters = {};
_this._filters = {};
// Keep selection across filter changes
this.kept_selection = null;
this.kept_focus = null;
this.kept_expansion = [];
_this.kept_selection = null;
_this.kept_focus = null;
_this.kept_expansion = [];
// Directly use the API-Implementation of dataRegisterUID and
// dataUnregisterUID
this.dataUnregisterUID = _egw.dataUnregisterUID;
_this.dataUnregisterUID = _egw.dataUnregisterUID;
// Default to rows
this._view = et2_nextmatch_controller.prototype.VIEW_ROW;
},
destroy: function () {
_this._view = et2_nextmatch_controller.VIEW_ROW;
return _this;
}
et2_nextmatch_controller.prototype.destroy = function () {
// If the actionManager variable is set, the object- and actionManager
// were created by this instance -- clear them
if (this._actionManager)
{
if (this._actionManager) {
this._objectManager.remove();
this._actionManager.remove();
}
this._super();
},
_super.prototype.destroy.call(this);
};
/**
* Updates the filter instance.
*/
setFilters: function (_filters) {
et2_nextmatch_controller.prototype.setFilters = function (_filters) {
// Update the filters
this._filters = _filters;
},
};
/**
* Keep the selection, if possible, across a data fetch and restore it
* after
*/
keepSelection: function() {
et2_nextmatch_controller.prototype.keepSelection = function () {
this.kept_selection = this._selectionMgr ? this._selectionMgr.getSelected() : null;
this.kept_focus = this._selectionMgr && this._selectionMgr._focusedEntry ?
this._selectionMgr._focusedEntry.uid || null : null;
// Find expanded rows
var nm = this._widget;
var controller = this;
jQuery('.arrow.opened',this._widget.getDOMNode(this._widget)).each(function() {
jQuery('.arrow.opened', this._widget.getDOMNode(this._widget)).each(function () {
var entry = controller.getRowByNode(this);
if(entry && entry.uid)
{
if (entry && entry.uid) {
controller.kept_expansion.push(entry.uid);
}
});
},
getObjectManager: function () {
};
et2_nextmatch_controller.prototype.getObjectManager = function () {
return this._objectManager;
},
};
/**
* Deletes a row from the grid
*
* @param {string} uid
*/
deleteRow: function(uid) {
et2_nextmatch_controller.prototype.deleteRow = function (uid) {
var entry = this._selectionMgr._getRegisteredRowsEntry(uid);
// Unselect
this._selectionMgr.setSelected(uid,false);
if(entry && entry.idx !== null)
{
this._selectionMgr.setSelected(uid, false);
if (entry && entry.idx !== null) {
// This will remove the row, but add an empty to the end.
// That's OK, because it will be removed when we update the row count
this._grid.deleteRow(entry.idx);
// Trigger controller to remove from internals
this.egw.dataStoreUID(uid,null);
this.egw.dataStoreUID(uid, null);
// Stop caring about this ID
this.egw.dataDeleteUID(uid);
// Remove from internal map
delete this._indexMap[entry.idx];
// Update the indices of all elements after the current one
for(var mapIndex = entry.idx + 1; typeof this._indexMap[mapIndex] !== 'undefined'; mapIndex++)
{
for (var mapIndex = entry.idx + 1; typeof this._indexMap[mapIndex] !== 'undefined'; mapIndex++) {
var entry = this._indexMap[mapIndex];
entry.idx = mapIndex-1;
this._indexMap[mapIndex-1] = entry;
entry.idx = mapIndex - 1;
this._indexMap[mapIndex - 1] = entry;
// Update selection mgr too
if(entry.uid && typeof this._selectionMgr._registeredRows[entry.uid] !== 'undefined')
{
if (entry.uid && typeof this._selectionMgr._registeredRows[entry.uid] !== 'undefined') {
var reg = this._selectionMgr._getRegisteredRowsEntry(entry.uid);
reg.idx = entry.idx;
if(reg.ao && reg.ao._index) reg.ao._index = entry.idx;
if (reg.ao && reg.ao._index)
reg.ao._index = entry.idx;
}
}
// Remove last one, it was moved to mapIndex-1 before increment
delete this._indexMap[mapIndex-1];
delete this._indexMap[mapIndex - 1];
// Not needed, they share by reference
// this._selectionMgr.setIndexMap(this._indexMap);
}
},
};
/** -- PRIVATE FUNCTIONS -- **/
/**
* Create a new row, either normal or tiled
*
* @param {type} ctx
* @returns {et2_dataview_container}
*/
_createRow: function(ctx) {
switch(this._view)
{
case et2_nextmatch_controller.prototype.VIEW_TILE:
var row = new et2_dataview_tile(this._grid);
et2_nextmatch_controller.prototype._createRow = function (ctx) {
switch (this._view) {
case et2_nextmatch_controller.VIEW_TILE:
var row = new et2_dataview_view_tile_1.et2_dataview_tile(this._grid);
// Try to overcome chrome rendering issue where float is not
// applied properly, leading to incomplete rows
window.setTimeout(function() {
if(!row.tr) return;
row.tr.css('float','none');
window.setTimeout(function() {
if(!row.tr) return;
row.tr.css('float','left');
},50);
},100);
window.setTimeout(function () {
if (!row.tr)
return;
row.tr.css('float', 'none');
window.setTimeout(function () {
if (!row.tr)
return;
row.tr.css('float', 'left');
}, 50);
}, 100);
return row;
case et2_nextmatch_controller.prototype.VIEW_ROW:
case et2_nextmatch_controller.VIEW_ROW:
default:
return new et2_dataview_row(this._grid);
return new et2_dataview_view_row_1.et2_dataview_row(this._grid);
}
},
};
/**
* Initializes the action and the object manager.
*/
_initActions: function (_actions) {
et2_nextmatch_controller.prototype._initActions = function (_actions) {
// Generate a uid for the action and object manager
var uid = this._widget.id||this.egw.uid();
if(_actions == null) _actions = [];
var uid = this._widget.id || this.egw.uid();
if (_actions == null)
_actions = [];
// Initialize the action manager and add some actions to it
// Only look 1 level deep
var gam = egw_getActionManager(this.egw.appName,true,1);
if(this._actionManager == null)
{
var gam = egw_getActionManager(this.egw.appName, true, 1);
if (this._actionManager == null) {
this._actionManager = gam.addAction("actionManager", uid);
}
this._actionManager.updateActions(_actions, this.egw.appName);
var data = this._actionManager.data;
if (data == 'undefined' || !data)
{
if (data == 'undefined' || !data) {
data = {};
}
data.nextmatch = this._widget;
this._actionManager.set_data(data);
// Set the default execute handler
var self = this;
this._actionManager.setDefaultExecute(function (_action, _senders, _target) {
// Get the selected ids descriptor object
var ids = self._selectionMgr.getSelected();
// Pass a reference to the actual widget
if (typeof _action.data == 'undefined' || !_action.data) _action.data = {};
if (typeof _action.data == 'undefined' || !_action.data)
_action.data = {};
_action.data.nextmatch = self._widget;
// Call the nm_action function with the ids
nm_action(_action, _senders, _target, ids);
});
// Set the 'Select All' handler
var select_all = this._actionManager.getActionById('select_all');
if(select_all)
{
select_all.set_onExecute(jQuery.proxy(function(action, selected) {
if (select_all) {
select_all.set_onExecute(jQuery.proxy(function (action, selected) {
this._selectionMgr.selectAll();
}, this));
}
// Initialize the object manager - look for application
// object manager 1 level deep
var gom = egw_getObjectManager(this.egw.appName,true,1);
if(this._objectManager == null)
{
this._objectManager = gom.addObject(
new egwActionObjectManager(uid, this._actionManager));
this._objectManager.handleKeyPress = function(_keyCode, _shift, _ctrl, _alt) {
for(var i = 0; i < self._actionManager.children.length; i++)
{
if(typeof self._actionManager.children[i].shortcut === 'object' &&
var gom = egw_getObjectManager(this.egw.appName, true, 1);
if (this._objectManager == null) {
this._objectManager = gom.addObject(new egwActionObjectManager(uid, this._actionManager));
this._objectManager.handleKeyPress = function (_keyCode, _shift, _ctrl, _alt) {
for (var i = 0; i < self._actionManager.children.length; i++) {
if (typeof self._actionManager.children[i].shortcut === 'object' &&
self._actionManager.children[i].shortcut &&
_keyCode == self._actionManager.children[i].shortcut.keyCode)
{
return this.executeActionImplementation(
{
_keyCode == self._actionManager.children[i].shortcut.keyCode) {
return this.executeActionImplementation({
"keyEvent": {
"keyCode": _keyCode,
"shift": _shift,
@ -312,144 +280,108 @@ var et2_nextmatch_controller = (function(){ "use strict"; return et2_dataview_co
}, "popup", EGW_AO_EXEC_SELECTED);
}
}
return egwActionObject.prototype.handleKeyPress.call(this, _keyCode,_shift,_ctrl,_alt);
}
return egwActionObject.prototype.handleKeyPress.call(this, _keyCode, _shift, _ctrl, _alt);
};
}
this._objectManager.flags = this._objectManager.flags
| EGW_AO_FLAG_DEFAULT_FOCUS | EGW_AO_FLAG_IS_CONTAINER;
this._init_links_dnd(this._actionManager);
if(this._selectionMgr)
{
this._init_links_dnd();
if (this._selectionMgr) {
// Need to update the action links for every registered row too
for (var uid in this._selectionMgr._registeredRows)
{
for (var uid in this._selectionMgr._registeredRows) {
// Get the corresponding entry from the registered rows array
var entry = this._selectionMgr._getRegisteredRowsEntry(uid);
if(entry.ao)
{
if (entry.ao) {
entry.ao.updateActionLinks(this._actionLinks);
}
}
}
},
};
/**
* Automatically add dnd support for linking
*/
_init_links_dnd: function() {
et2_nextmatch_controller.prototype._init_links_dnd = function () {
var mgr = this._actionManager;
var self = this;
var drop_action = mgr.getActionById('egw_link_drop');
var drag_action = mgr.getActionById('egw_link_drag');
var drop_cancel = mgr.getActionById('egw_cancel_drop');
if(!this._actionLinks)
{
if (!this._actionLinks) {
this._actionLinks = [];
}
if (!drop_cancel)
{
if (!drop_cancel) {
// Create a generic cancel action in order to cancel drop action
// applied for all apps plus file and link action.
drop_cancel = mgr.addAction('drop', 'egw_cancel_drop', this.egw.lang('Cancel'), egw.image('cancel'), function(){},true);
drop_cancel = mgr.addAction('drop', 'egw_cancel_drop', this.egw.lang('Cancel'), egw.image('cancel'), function () { }, true);
drop_cancel.set_group('99');
drop_cancel.acceptedTypes = drop_cancel.acceptedTypes.concat(Object.keys(egw.user('apps')).concat(['link', 'file']));
this._actionLinks.push (drop_cancel.id);
this._actionLinks.push(drop_cancel.id);
}
// Check if this app supports linking
if(!egw.link_get_registry(this.dataStorePrefix || this.egw.appName, 'query') ||
egw.link_get_registry(this.dataStorePrefix || this.egw.appName, 'title'))
{
if(drop_action)
{
if (!egw.link_get_registry(this.dataStorePrefix || this.egw.appName, 'query') ||
egw.link_get_registry(this.dataStorePrefix || this.egw.appName, 'title')) {
if (drop_action) {
drop_action.remove();
if(this._actionLinks.indexOf(drop_action.id) >= 0)
{
this._actionLinks.splice(this._actionLinks.indexOf(drop_action.id),1);
if (this._actionLinks.indexOf(drop_action.id) >= 0) {
this._actionLinks.splice(this._actionLinks.indexOf(drop_action.id), 1);
}
}
if(drag_action)
{
if (drag_action) {
drag_action.remove();
if(this._actionLinks.indexOf(drag_action.id) >= 0)
{
this._actionLinks.splice(this._actionLinks.indexOf(drag_action.id),1);
if (this._actionLinks.indexOf(drag_action.id) >= 0) {
this._actionLinks.splice(this._actionLinks.indexOf(drag_action.id), 1);
}
}
return;
}
// Don't re-add
if(drop_action == null)
{
if (drop_action == null) {
// Create the drop action that links entries
drop_action = mgr.addAction('drop', 'egw_link_drop', this.egw.lang('Create link'), egw.image('link'), function(action, source, dropped) {
drop_action = mgr.addAction('drop', 'egw_link_drop', this.egw.lang('Create link'), egw.image('link'), function (action, source, dropped) {
// Extract link IDs
var links = [];
var id = '';
for(var i = 0; i < source.length; i++)
{
if(!source[i].id) continue;
for (var i = 0; i < source.length; i++) {
if (!source[i].id)
continue;
id = source[i].id.split('::');
links.push({app: id[0] == 'filemanager' ? 'link' : id[0], id: id[1]});
links.push({ app: id[0] == 'filemanager' ? 'link' : id[0], id: id[1] });
}
if(!links.length)
{
if (!links.length) {
return;
}
// Link the entries
self.egw.json("EGroupware\\Api\\Etemplate\\Widget\\Link::ajax_link",
dropped.id.split('::').concat([links]),
function(result) {
if(result)
{
for (var i=0; i < this._objectManager.selectedChildren.length; i++)
{
this._widget.refresh(this._objectManager.selectedChildren[i].id,'update');
self.egw.json("EGroupware\\Api\\Etemplate\\Widget\\Link::ajax_link", dropped.id.split('::').concat([links]), function (result) {
if (result) {
for (var i = 0; i < this._objectManager.selectedChildren.length; i++) {
this._widget.refresh(this._objectManager.selectedChildren[i].id, 'update');
}
this._widget.egw().message('Linked');
// Update the target to show the liks
this._widget.refresh(dropped.id,'update');
this._widget.refresh(dropped.id, 'update');
}
},
self,
true,
self
).sendRequest();
},true);
}, self, true, self).sendRequest();
}, true);
}
if(this._actionLinks.indexOf(drop_action.id) < 0)
{
if (this._actionLinks.indexOf(drop_action.id) < 0) {
this._actionLinks.push(drop_action.id);
}
// Accept other links, and files dragged from the filemanager
// This does not handle files dragged from the desktop. They are
// handled by et2_nextmatch, since it needs DOM stuff
if(drop_action.acceptedTypes.indexOf('link') == -1)
{
if (drop_action.acceptedTypes.indexOf('link') == -1) {
drop_action.acceptedTypes.push('link');
}
// Don't re-add
if(drag_action == null)
{
if (drag_action == null) {
// Create drag action that allows linking
drag_action = mgr.addAction('drag', 'egw_link_drag', this.egw.lang('link'), 'link', function(action, selected) {
drag_action = mgr.addAction('drag', 'egw_link_drag', this.egw.lang('link'), 'link', function (action, selected) {
// Drag helper - list titles. Arbitrarily limited to 10.
var helper = jQuery(document.createElement("div"));
for(var i = 0; i < selected.length && i < 10; i++)
{
for (var i = 0; i < selected.length && i < 10; i++) {
var id = selected[i].id.split('::');
var span = jQuery(document.createElement('span')).appendTo(helper);
self.egw.link_title(id[0],id[1], function(title) {
self.egw.link_title(id[0], id[1], function (title) {
this.append(title);
this.append('<br />');
}, span);
@ -458,42 +390,35 @@ var et2_nextmatch_controller = (function(){ "use strict"; return et2_dataview_co
// TODO: Need to decide if we need to create a customized helper interface for links anyway
//return helper;
return null;
},true);
}, true);
}
if(this._actionLinks.indexOf(drag_action.id) < 0)
{
if (this._actionLinks.indexOf(drag_action.id) < 0) {
this._actionLinks.push(drag_action.id);
}
drag_action.set_dragType('link');
},
};
/**
* Set the data cache prefix
* Overridden from the parent to re-check automatically the added link dnd
* since the prefix is used in support detection.
*/
setPrefix: function(prefix) {
this._super.apply(this, arguments)
this._init_links_dnd(this._actionManager);
},
et2_nextmatch_controller.prototype.setPrefix = function (prefix) {
_super.prototype.setPrefix.call(this, prefix);
this._init_links_dnd();
};
/**
* Overwrites the inherited _destroyCallback function in order to be able
* to free the "rowWidget".
*/
_destroyCallback: function (_row) {
et2_nextmatch_controller.prototype._destroyCallback = function (_row) {
// Destroy any widget associated to the row
if (this.entry.widget)
{
this.entry.widget.free();
if (this.entry.widget) {
this.entry.widget.destroy();
this.entry.widget = null;
}
// Call the inherited function
this._super.apply(this, arguments);
},
_super.prototype._destroyCallback.call(this, _row);
};
/**
* Creates the actual data row.
*
@ -504,13 +429,11 @@ var et2_nextmatch_controller = (function(){ "use strict"; return et2_dataview_co
* this special case used to store the rowWidget reference, so that it can
* be properly freed.
*/
_rowCallback: function (_data, _tr, _idx, _entry) {
et2_nextmatch_controller.prototype._rowCallback = function (_data, _tr, _idx, _entry) {
// Let the row provider fill in the data row -- store the returned
// rowWidget inside the _entry
_entry.widget = this._rowProvider.getDataRow(
{ "content": _data }, _tr, _idx, this);
},
_entry.widget = this._rowProvider.getDataRow({ "content": _data }, _tr, _idx, this);
};
/**
* Returns the names of action links for a given data row -- currently these are
* always the same links, as we controll enabled/disabled over the row
@ -528,12 +451,10 @@ var et2_nextmatch_controller = (function(){ "use strict"; return et2_dataview_co
*
* @return Array List of action names that valid for the row
*/
_linkCallback: function (_data, _idx, _uid) {
if(_uid.trim() != "")
{
et2_nextmatch_controller.prototype._linkCallback = function (_data, _idx, _uid) {
if (_uid.trim() != "") {
return this._actionLinks;
}
// No UID, so return a filtered list of actions that doesn't need a UID
var links = [];
try {
@ -542,201 +463,157 @@ var et2_nextmatch_controller = (function(){ "use strict"; return et2_dataview_co
// Make sure that placeholder actions are defined and existed in client-side,
// otherwise do not set them as placeholder. for instance actions with
// attribute hideOnMobile do not get sent to client-side.
var action_search = function(current) {
if (typeof this._widget.options.actions[current] !== 'undefined') return true;
var action_search = function (current) {
if (typeof this._widget.options.actions[current] !== 'undefined')
return true;
// Check children
for(var action in this._widget.options.actions)
{
for (var action in this._widget.options.actions) {
action = this._widget.options.actions[action];
if( action.children && action.children[current]) return true;
if (action.children && action.children[current])
return true;
}
return false;
}
};
links = links.filter(action_search, this);
} catch (e) {
}
catch (e) {
}
return links;
},
};
/**
* Overridden from the parent to also process any additional data that
* the data source adds, such as readonlys and additonal content.
* For example, non-numeric IDs in rows are added to the content manager
*/
_fetchCallback: function (_response) {
et2_nextmatch_controller.prototype._fetchCallback = function (_response) {
var nm = this.self._widget;
if(!nm)
{
if (!nm) {
// Nextmatch either not connected, or it tried to destroy this
// but the server returned something
return;
}
// Readonlys
// Other stuff
for(var i in _response.rows)
{
if(jQuery.isNumeric(i)) continue;
if(i == 'sel_options')
{
for (var i in _response.rows) {
if (jQuery.isNumeric(i))
continue;
if (i == 'sel_options') {
var mgr = nm.getArrayMgr(i);
for(var id in _response.rows.sel_options)
{
for (var id in _response.rows.sel_options) {
mgr.data[id] = _response.rows.sel_options[id];
var select = nm.getWidgetById(id);
if(select && select.set_select_options)
{
if (select && select.set_select_options) {
select.set_select_options(_response.rows.sel_options[id]);
}
// Clear rowProvider internal cache so it uses new values
if(id == 'cat_id')
{
if (id == 'cat_id') {
this.self._rowProvider.categories = null;
}
// update array mgr so select widgets in row also get refreshed options
nm.getParent().getArrayMgr('sel_options').data[id] = _response.rows.sel_options[id];
}
}
else
{
else {
var mgr = nm.getArrayMgr('content');
mgr.data[i] = _response.rows[i];
// It's not enough to just update the data, the widgets need to
// be updated too, if there are matching widgets.
var widget = nm.getWidgetById(i);
if(widget && widget.set_value)
{
if (widget && widget.set_value) {
widget.set_value(mgr.getEntry(i));
}
}
}
// Might be trying to disable a column
var col_refresh = false;
for(var column_index = 0; column_index < nm.columns.length; column_index++)
{
if(typeof nm.columns[column_index].disabled === 'string' &&
nm.columns[column_index].disabled[0] === '@')
{
for (var column_index = 0; column_index < nm.columns.length; column_index++) {
if (typeof nm.columns[column_index].disabled === 'string' &&
nm.columns[column_index].disabled[0] === '@') {
col_refresh = true;
nm.dataview.columnMgr.getColumnById('col_'+column_index)
.set_visibility(
nm.getArrayMgr('content').parseBoolExpression(nm.columns[column_index].disabled) ?
ET2_COL_VISIBILITY_DISABLED :
nm.columns[column_index].visible
);
nm.dataview.columnMgr.getColumnById('col_' + column_index)
.set_visibility(nm.getArrayMgr('content').parseBoolExpression(nm.columns[column_index].disabled) ?
et2_dataview_column.ET2_COL_VISIBILITY_DISABLED :
nm.columns[column_index].visible);
}
}
if(col_refresh)
{
nm.dataview.columnMgr.updated = true;
if (col_refresh) {
nm.dataview.columnMgr.updated();
nm.dataview._updateColumns();
}
// If we're doing an autorefresh and the count decreases, preserve the
// selection or it will be lost when the grid rows are shuffled. Increases
// are fine though.
if(this.self && this.self.kept_selection == null &&
!this.refresh && this.self._grid.getTotalCount() > _response.total)
{
if (this.self && this.self.kept_selection == null &&
!this.refresh && this.self._grid.getTotalCount() > _response.total) {
this.self.keepSelection();
}
// Call the inherited function
this._super.apply(this, arguments);
_super.prototype._fetchCallback.apply(this, arguments);
// Restore selection, if passed
if(this.self && this.self.kept_selection && this.self._selectionMgr)
{
if(this.self.kept_selection.all)
{
if (this.self && this.self.kept_selection && this.self._selectionMgr) {
if (this.self.kept_selection.all) {
this.self._selectionMgr.selectAll();
}
for(var i = (this.self.kept_selection.ids.length || 1)-1; i >= 0; i--)
{
for (var i = (this.self.kept_selection.ids.length || 1) - 1; i >= 0; i--) {
// Only keep the selected if they came back in the fetch
if(_response.order.indexOf(this.self.kept_selection.ids[i]) >= 0)
{
this.self._selectionMgr.setSelected(this.self.kept_selection.ids[i],true);
this.self.kept_selection.ids.splice(i,1);
if (_response.order.indexOf(this.self.kept_selection.ids[i]) >= 0) {
this.self._selectionMgr.setSelected(this.self.kept_selection.ids[i], true);
this.self.kept_selection.ids.splice(i, 1);
}
else
{
this.self.kept_selection.ids.splice(i,1);
else {
this.self.kept_selection.ids.splice(i, 1);
}
}
if(this.self.kept_focus && _response.order.indexOf(this.self.kept_focus) >= 0)
{
this.self._selectionMgr.setFocused(this.self.kept_focus,true);
if (this.self.kept_focus && _response.order.indexOf(this.self.kept_focus) >= 0) {
this.self._selectionMgr.setFocused(this.self.kept_focus, true);
}
// Re-expanding rows handled in et2_extension_nextmatch_rowProvider
// Expansions might still be valid, so we don't clear them
if(this.self.kept_selection != null && typeof this.self.kept_selection.ids != 'undefined' && this.self.kept_selection.ids.length == 0)
{
if (this.self.kept_selection != null && typeof this.self.kept_selection.ids != 'undefined' && this.self.kept_selection.ids.length == 0) {
this.self.kept_selection = null;
}
this.self.kept_focus = null;
}
},
};
/**
* Execute the select callback when the row selection changes
*/
_selectCallback: function(action,senders)
{
if(typeof senders == "undefined")
{
et2_nextmatch_controller.prototype._selectCallback = function (action, senders) {
if (typeof senders == "undefined") {
senders = [];
}
if(!this._widget) return;
if (!this._widget)
return;
// inform mobile framework about nm selections, need to update status of header objects on selection
if (egwIsMobile()) framework.nm_onselect_ctrl(this._widget, action, senders);
this._widget.onselect.call(this._widget, action,senders);
},
if (egwIsMobile())
framework.nm_onselect_ctrl(this._widget, action, senders);
this._widget.onselect.call(this._widget, action, senders);
};
/** -- Implementation of et2_IDataProvider -- **/
dataFetch: function (_queriedRange, _callback, _context) {
et2_nextmatch_controller.prototype.dataFetch = function (_queriedRange, _callback, _context) {
// Merge the parent id into the _queriedRange if it is set
if (this._parentId !== null)
{
if (this._parentId !== null) {
_queriedRange["parent_id"] = this._parentId;
}
// sub-levels dont have there own _filters object, need to use the one from parent (or it's parents parent)
var obj = this;
while((typeof obj._filters == 'undefined' || jQuery.isEmptyObject(obj._filters)) && obj._parentController)
{
while ((typeof obj._filters == 'undefined' || jQuery.isEmptyObject(obj._filters)) && obj._parentController) {
obj = obj._parentController;
}
// Pass the fetch call to the API, multiplex the data about the
// nextmatch instance into the call.
this.egw.dataFetch(
this._widget.getInstanceManager().etemplate_exec_id || this._execId,
_queriedRange,
obj._filters,
this._widgetId,
_callback,
_context);
},
dataRegisterUID: function (_uid, _callback, _context) {
this.egw.dataRegisterUID(_uid, _callback, _context,
this._widget.getInstanceManager().etemplate_exec_id || this._execId,
this._widgetId
);
},
dataUnregisterUID: function () {
this.egw.dataFetch(this._widget.getInstanceManager().etemplate_exec_id || this._execId, _queriedRange, obj._filters, this._widgetId, _callback, _context);
};
et2_nextmatch_controller.prototype.dataRegisterUID = function (_uid, _callback, _context) {
this.egw.dataRegisterUID(_uid, _callback, _context, this._widget.getInstanceManager().etemplate_exec_id || this._execId, this._widgetId);
};
et2_nextmatch_controller.prototype.dataUnregisterUID = function () {
// Overwritten in the constructor
}
});}).call(this);
};
// Display constants
et2_nextmatch_controller.VIEW_ROW = 'row';
et2_nextmatch_controller.VIEW_TILE = 'tile';
return et2_nextmatch_controller;
}(et2_dataview_controller));
exports.et2_nextmatch_controller = et2_nextmatch_controller;
//# sourceMappingURL=et2_extension_nextmatch_controller.js.map

View File

@ -0,0 +1,769 @@
/**
* EGroupware eTemplate2 - Class which contains a the data model for nextmatch widgets
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package etemplate
* @subpackage api
* @link http://www.egroupware.org
* @author Andreas Stöckel
* @copyright Stylite 2012
* @version $Id$
*
/*egw:uses
et2_core_common;
et2_core_inheritance;
et2_dataview_view_row;
et2_dataview_controller;
et2_dataview_interfaces;
et2_dataview_view_tile;
et2_extension_nextmatch_actions; // Contains nm_action
egw_data;
*/
import {et2_IDataProvider} from "./et2_dataview_interfaces";
import {et2_dataview_row} from "./et2_dataview_view_row";
import {et2_dataview_tile} from "./et2_dataview_view_tile";
/**
* @augments et2_dataview_controller
*/
export class et2_nextmatch_controller extends et2_dataview_controller implements et2_IDataProvider
{
// Display constants
public static readonly VIEW_ROW : string = 'row';
public static readonly VIEW_TILE: string = 'tile';
/**
* Initializes the nextmatch controller.
*
* @param _parentController is the parent nextmatch controller instance
* @param _egw is the api instance
* @param _execId is the execId of the etemplate
* @param _widget is the nextmatch-widget we are fetching data for.
* @param _grid is the grid the grid controller will be controlling
* @param _rowProvider is the nextmatch row provider instance.
* @param _objectManager is the parent object manager (if null, the object
* manager) will be created using
* @param _actionLinks contains the action links
* @param _actions contains the actions, may be null if an object manager
* is given.
* @memberOf et2_nextmatch_controller
*/
constructor( _parentController, _egw, _execId, _widget, _parentId,
_grid, _rowProvider, _actionLinks, _objectManager, _actions)
{
// Call the parent et2_dataview_controller constructor
super(_parentController, _grid);
this.setDataProvider(this);
this.setRowCallback(this._rowCallback);
this.setLinkCallback(this._linkCallback);
this.setContext(this);
// Copy the egw reference
this.egw = _egw;
// Keep a reference to the widget
this._widget = _widget;
// Copy the given parameters
this._actionLinks = _actionLinks;
this._execId = _execId;
// Get full widget ID, including path
var id = _widget.getArrayMgr('content').getPath();
if(typeof id == 'string')
{
this._widgetId = id;
}
else if (id.length === 1)
{
this._widgetId = id[0];
}
else
{
this._widgetId = id.shift() + '[' + id.join('][') + ']';
}
this._parentId = _parentId;
this._rowProvider = _rowProvider;
// Initialize the action and the object manager
// _initActions calls _init_link_dnd, which uses this._actionLinks,
// so this must happen after the above parameter copying
if (!_objectManager)
{
this._initActions(_actions);
}
else
{
this._actionManager = null;
this._objectManager = _objectManager;
}
this.setActionObjectManager(this._objectManager);
// Add our selection callback to selection manager
var self = this;
this._objectManager.setSelectedCallback = function() {self._selectCallback.apply(self,[this,arguments]);};
// We start with no filters
this._filters = {};
// Keep selection across filter changes
this.kept_selection = null;
this.kept_focus = null;
this.kept_expansion = [];
// Directly use the API-Implementation of dataRegisterUID and
// dataUnregisterUID
this.dataUnregisterUID = _egw.dataUnregisterUID;
// Default to rows
this._view = et2_nextmatch_controller.VIEW_ROW;
}
destroy( )
{
// If the actionManager variable is set, the object- and actionManager
// were created by this instance -- clear them
if (this._actionManager)
{
this._objectManager.remove();
this._actionManager.remove();
}
super.destroy();
}
/**
* Updates the filter instance.
*/
setFilters( _filters)
{
// Update the filters
this._filters = _filters;
}
/**
* Keep the selection, if possible, across a data fetch and restore it
* after
*/
keepSelection( )
{
this.kept_selection = this._selectionMgr ? this._selectionMgr.getSelected() : null;
this.kept_focus = this._selectionMgr && this._selectionMgr._focusedEntry ?
this._selectionMgr._focusedEntry.uid || null : null;
// Find expanded rows
var nm = this._widget;
var controller = this;
jQuery('.arrow.opened',this._widget.getDOMNode(this._widget)).each(function() {
var entry = controller.getRowByNode(this);
if(entry && entry.uid)
{
controller.kept_expansion.push(entry.uid);
}
});
}
getObjectManager( )
{
return this._objectManager;
}
/**
* Deletes a row from the grid
*
* @param {string} uid
*/
deleteRow( uid)
{
var entry = this._selectionMgr._getRegisteredRowsEntry(uid);
// Unselect
this._selectionMgr.setSelected(uid,false);
if(entry && entry.idx !== null)
{
// This will remove the row, but add an empty to the end.
// That's OK, because it will be removed when we update the row count
this._grid.deleteRow(entry.idx);
// Trigger controller to remove from internals
this.egw.dataStoreUID(uid,null);
// Stop caring about this ID
this.egw.dataDeleteUID(uid);
// Remove from internal map
delete this._indexMap[entry.idx];
// Update the indices of all elements after the current one
for(var mapIndex = entry.idx + 1; typeof this._indexMap[mapIndex] !== 'undefined'; mapIndex++)
{
var entry = this._indexMap[mapIndex];
entry.idx = mapIndex-1;
this._indexMap[mapIndex-1] = entry;
// Update selection mgr too
if(entry.uid && typeof this._selectionMgr._registeredRows[entry.uid] !== 'undefined')
{
var reg = this._selectionMgr._getRegisteredRowsEntry(entry.uid);
reg.idx = entry.idx;
if(reg.ao && reg.ao._index) reg.ao._index = entry.idx;
}
}
// Remove last one, it was moved to mapIndex-1 before increment
delete this._indexMap[mapIndex-1];
// Not needed, they share by reference
// this._selectionMgr.setIndexMap(this._indexMap);
}
}
/** -- PRIVATE FUNCTIONS -- **/
/**
* Create a new row, either normal or tiled
*
* @param {type} ctx
* @returns {et2_dataview_container}
*/
_createRow( ctx)
{
switch(this._view)
{
case et2_nextmatch_controller.VIEW_TILE:
var row = new et2_dataview_tile(this._grid);
// Try to overcome chrome rendering issue where float is not
// applied properly, leading to incomplete rows
window.setTimeout(function() {
if(!row.tr) return;
row.tr.css('float','none');
window.setTimeout(function() {
if(!row.tr) return;
row.tr.css('float','left');
},50);
},100);
return row;
case et2_nextmatch_controller.VIEW_ROW:
default:
return new et2_dataview_row(this._grid);
}
}
/**
* Initializes the action and the object manager.
*/
_initActions( _actions)
{
// Generate a uid for the action and object manager
var uid = this._widget.id||this.egw.uid();
if(_actions == null) _actions = [];
// Initialize the action manager and add some actions to it
// Only look 1 level deep
var gam = egw_getActionManager(this.egw.appName,true,1);
if(this._actionManager == null)
{
this._actionManager = gam.addAction("actionManager", uid);
}
this._actionManager.updateActions(_actions, this.egw.appName);
var data = this._actionManager.data;
if (data == 'undefined' || !data)
{
data = {};
}
data.nextmatch = this._widget;
this._actionManager.set_data(data);
// Set the default execute handler
var self = this;
this._actionManager.setDefaultExecute(function (_action, _senders, _target) {
// Get the selected ids descriptor object
var ids = self._selectionMgr.getSelected();
// Pass a reference to the actual widget
if (typeof _action.data == 'undefined' || !_action.data) _action.data = {};
_action.data.nextmatch = self._widget;
// Call the nm_action function with the ids
nm_action(_action, _senders, _target, ids);
});
// Set the 'Select All' handler
var select_all = this._actionManager.getActionById('select_all');
if(select_all)
{
select_all.set_onExecute(jQuery.proxy(function(action, selected) {
this._selectionMgr.selectAll();
}, this));
}
// Initialize the object manager - look for application
// object manager 1 level deep
var gom = egw_getObjectManager(this.egw.appName,true,1);
if(this._objectManager == null)
{
this._objectManager = gom.addObject(
new egwActionObjectManager(uid, this._actionManager));
this._objectManager.handleKeyPress = function(_keyCode, _shift, _ctrl, _alt) {
for(var i = 0; i < self._actionManager.children.length; i++)
{
if(typeof self._actionManager.children[i].shortcut === 'object' &&
self._actionManager.children[i].shortcut &&
_keyCode == self._actionManager.children[i].shortcut.keyCode)
{
return this.executeActionImplementation(
{
"keyEvent": {
"keyCode": _keyCode,
"shift": _shift,
"ctrl": _ctrl,
"alt": _alt
}
}, "popup", EGW_AO_EXEC_SELECTED);
}
}
return egwActionObject.prototype.handleKeyPress.call(this, _keyCode,_shift,_ctrl,_alt);
}
}
this._objectManager.flags = this._objectManager.flags
| EGW_AO_FLAG_DEFAULT_FOCUS | EGW_AO_FLAG_IS_CONTAINER;
this._init_links_dnd();
if(this._selectionMgr)
{
// Need to update the action links for every registered row too
for (var uid in this._selectionMgr._registeredRows)
{
// Get the corresponding entry from the registered rows array
var entry = this._selectionMgr._getRegisteredRowsEntry(uid);
if(entry.ao)
{
entry.ao.updateActionLinks(this._actionLinks);
}
}
}
}
/**
* Automatically add dnd support for linking
*/
_init_links_dnd( )
{
var mgr = this._actionManager;
var self = this;
var drop_action = mgr.getActionById('egw_link_drop');
var drag_action = mgr.getActionById('egw_link_drag');
var drop_cancel = mgr.getActionById('egw_cancel_drop');
if(!this._actionLinks)
{
this._actionLinks = [];
}
if (!drop_cancel)
{
// Create a generic cancel action in order to cancel drop action
// applied for all apps plus file and link action.
drop_cancel = mgr.addAction('drop', 'egw_cancel_drop', this.egw.lang('Cancel'), egw.image('cancel'), function(){},true);
drop_cancel.set_group('99');
drop_cancel.acceptedTypes = drop_cancel.acceptedTypes.concat(Object.keys(egw.user('apps')).concat(['link', 'file']));
this._actionLinks.push (drop_cancel.id);
}
// Check if this app supports linking
if(!egw.link_get_registry(this.dataStorePrefix || this.egw.appName, 'query') ||
egw.link_get_registry(this.dataStorePrefix || this.egw.appName, 'title'))
{
if(drop_action)
{
drop_action.remove();
if(this._actionLinks.indexOf(drop_action.id) >= 0)
{
this._actionLinks.splice(this._actionLinks.indexOf(drop_action.id),1);
}
}
if(drag_action)
{
drag_action.remove();
if(this._actionLinks.indexOf(drag_action.id) >= 0)
{
this._actionLinks.splice(this._actionLinks.indexOf(drag_action.id),1);
}
}
return;
}
// Don't re-add
if(drop_action == null)
{
// Create the drop action that links entries
drop_action = mgr.addAction('drop', 'egw_link_drop', this.egw.lang('Create link'), egw.image('link'), function(action, source, dropped) {
// Extract link IDs
var links = [];
var id = '';
for(var i = 0; i < source.length; i++)
{
if(!source[i].id) continue;
id = source[i].id.split('::');
links.push({app: id[0] == 'filemanager' ? 'link' : id[0], id: id[1]});
}
if(!links.length)
{
return;
}
// Link the entries
self.egw.json("EGroupware\\Api\\Etemplate\\Widget\\Link::ajax_link",
dropped.id.split('::').concat([links]),
function(result) {
if(result)
{
for (var i=0; i < this._objectManager.selectedChildren.length; i++)
{
this._widget.refresh(this._objectManager.selectedChildren[i].id,'update');
}
this._widget.egw().message('Linked');
// Update the target to show the liks
this._widget.refresh(dropped.id,'update');
}
},
self,
true,
self
).sendRequest();
},true);
}
if(this._actionLinks.indexOf(drop_action.id) < 0)
{
this._actionLinks.push(drop_action.id);
}
// Accept other links, and files dragged from the filemanager
// This does not handle files dragged from the desktop. They are
// handled by et2_nextmatch, since it needs DOM stuff
if(drop_action.acceptedTypes.indexOf('link') == -1)
{
drop_action.acceptedTypes.push('link');
}
// Don't re-add
if(drag_action == null)
{
// Create drag action that allows linking
drag_action = mgr.addAction('drag', 'egw_link_drag', this.egw.lang('link'), 'link', function(action, selected) {
// Drag helper - list titles. Arbitrarily limited to 10.
var helper = jQuery(document.createElement("div"));
for(var i = 0; i < selected.length && i < 10; i++)
{
var id = selected[i].id.split('::');
var span = jQuery(document.createElement('span')).appendTo(helper);
self.egw.link_title(id[0],id[1], function(title) {
this.append(title);
this.append('<br />');
}, span);
}
// As we wanted to have a general defaul helper interface, we return null here and not using customize helper for links
// TODO: Need to decide if we need to create a customized helper interface for links anyway
//return helper;
return null;
},true);
}
if(this._actionLinks.indexOf(drag_action.id) < 0)
{
this._actionLinks.push(drag_action.id);
}
drag_action.set_dragType('link');
}
/**
* Set the data cache prefix
* Overridden from the parent to re-check automatically the added link dnd
* since the prefix is used in support detection.
*/
setPrefix( prefix)
{
super.setPrefix(prefix);
this._init_links_dnd();
}
/**
* Overwrites the inherited _destroyCallback function in order to be able
* to free the "rowWidget".
*/
_destroyCallback( _row)
{
// Destroy any widget associated to the row
if (this.entry.widget)
{
this.entry.widget.destroy();
this.entry.widget = null;
}
// Call the inherited function
super._destroyCallback(_row);
}
/**
* Creates the actual data row.
*
* @param _data is an array containing the row data
* @param _tr is the tr into which the data will be inserted
* @param _idx is the index of the row
* @param _entry is the internal row datastructure of the controller, in
* this special case used to store the rowWidget reference, so that it can
* be properly freed.
*/
_rowCallback( _data, _tr, _idx, _entry)
{
// Let the row provider fill in the data row -- store the returned
// rowWidget inside the _entry
_entry.widget = this._rowProvider.getDataRow(
{ "content": _data }, _tr, _idx, this);
}
/**
* Returns the names of action links for a given data row -- currently these are
* always the same links, as we controll enabled/disabled over the row
* classes, unless the row UID is "", then it's an 'empty' row.
*
* The empty row placeholder can still have actions, but nothing that requires
* an actual UID.
*
* @TODO: Currently empty row is just add, need to actually filter somehow. Here
* might not be the right place.
*
* @param _data Object The data for the row
* @param _idx int The row index
* @param _uid String The row's ID
*
* @return Array List of action names that valid for the row
*/
_linkCallback( _data, _idx, _uid)
{
if(_uid.trim() != "")
{
return this._actionLinks;
}
// No UID, so return a filtered list of actions that doesn't need a UID
var links = [];
try {
links = typeof this._widget.options.settings.placeholder_actions != 'undefined' ?
this._widget.options.settings.placeholder_actions : (this._widget.options.add ? ["add"] : []);
// Make sure that placeholder actions are defined and existed in client-side,
// otherwise do not set them as placeholder. for instance actions with
// attribute hideOnMobile do not get sent to client-side.
var action_search = function(current) {
if (typeof this._widget.options.actions[current] !== 'undefined') return true;
// Check children
for(var action in this._widget.options.actions)
{
action = this._widget.options.actions[action];
if( action.children && action.children[current]) return true;
}
return false;
};
links = links.filter(action_search, this);
} catch (e) {
}
return links;
}
/**
* Overridden from the parent to also process any additional data that
* the data source adds, such as readonlys and additonal content.
* For example, non-numeric IDs in rows are added to the content manager
*/
_fetchCallback( _response)
{
var nm = this.self._widget;
if(!nm)
{
// Nextmatch either not connected, or it tried to destroy this
// but the server returned something
return;
}
// Readonlys
// Other stuff
for(var i in _response.rows)
{
if(jQuery.isNumeric(i)) continue;
if(i == 'sel_options')
{
var mgr = nm.getArrayMgr(i);
for(var id in _response.rows.sel_options)
{
mgr.data[id] = _response.rows.sel_options[id];
var select = nm.getWidgetById(id);
if(select && select.set_select_options)
{
select.set_select_options(_response.rows.sel_options[id]);
}
// Clear rowProvider internal cache so it uses new values
if(id == 'cat_id')
{
this.self._rowProvider.categories = null;
}
// update array mgr so select widgets in row also get refreshed options
nm.getParent().getArrayMgr('sel_options').data[id] = _response.rows.sel_options[id];
}
}
else
{
var mgr = nm.getArrayMgr('content');
mgr.data[i] = _response.rows[i];
// It's not enough to just update the data, the widgets need to
// be updated too, if there are matching widgets.
var widget = nm.getWidgetById(i);
if(widget && widget.set_value)
{
widget.set_value(mgr.getEntry(i));
}
}
}
// Might be trying to disable a column
var col_refresh = false;
for(var column_index = 0; column_index < nm.columns.length; column_index++)
{
if(typeof nm.columns[column_index].disabled === 'string' &&
nm.columns[column_index].disabled[0] === '@')
{
col_refresh = true;
nm.dataview.columnMgr.getColumnById('col_'+column_index)
.set_visibility(
nm.getArrayMgr('content').parseBoolExpression(nm.columns[column_index].disabled) ?
et2_dataview_column.ET2_COL_VISIBILITY_DISABLED :
nm.columns[column_index].visible
);
}
}
if(col_refresh)
{
nm.dataview.columnMgr.updated();
nm.dataview._updateColumns();
}
// If we're doing an autorefresh and the count decreases, preserve the
// selection or it will be lost when the grid rows are shuffled. Increases
// are fine though.
if(this.self && this.self.kept_selection == null &&
!this.refresh && this.self._grid.getTotalCount() > _response.total)
{
this.self.keepSelection();
}
// Call the inherited function
super._fetchCallback.apply(this, arguments);
// Restore selection, if passed
if(this.self && this.self.kept_selection && this.self._selectionMgr)
{
if(this.self.kept_selection.all)
{
this.self._selectionMgr.selectAll();
}
for(var i = (this.self.kept_selection.ids.length || 1)-1; i >= 0; i--)
{
// Only keep the selected if they came back in the fetch
if(_response.order.indexOf(this.self.kept_selection.ids[i]) >= 0)
{
this.self._selectionMgr.setSelected(this.self.kept_selection.ids[i],true);
this.self.kept_selection.ids.splice(i,1);
}
else
{
this.self.kept_selection.ids.splice(i,1);
}
}
if(this.self.kept_focus && _response.order.indexOf(this.self.kept_focus) >= 0)
{
this.self._selectionMgr.setFocused(this.self.kept_focus,true);
}
// Re-expanding rows handled in et2_extension_nextmatch_rowProvider
// Expansions might still be valid, so we don't clear them
if(this.self.kept_selection != null && typeof this.self.kept_selection.ids != 'undefined' && this.self.kept_selection.ids.length == 0)
{
this.self.kept_selection = null;
}
this.self.kept_focus = null;
}
}
/**
* Execute the select callback when the row selection changes
*/
_selectCallback(action,senders)
{
if(typeof senders == "undefined")
{
senders = [];
}
if(!this._widget) return;
// inform mobile framework about nm selections, need to update status of header objects on selection
if (egwIsMobile()) framework.nm_onselect_ctrl(this._widget, action, senders);
this._widget.onselect.call(this._widget, action,senders);
}
/** -- Implementation of et2_IDataProvider -- **/
dataFetch( _queriedRange, _callback, _context)
{
// Merge the parent id into the _queriedRange if it is set
if (this._parentId !== null)
{
_queriedRange["parent_id"] = this._parentId;
}
// sub-levels dont have there own _filters object, need to use the one from parent (or it's parents parent)
var obj = this;
while((typeof obj._filters == 'undefined' || jQuery.isEmptyObject(obj._filters)) && obj._parentController)
{
obj = obj._parentController;
}
// Pass the fetch call to the API, multiplex the data about the
// nextmatch instance into the call.
this.egw.dataFetch(
this._widget.getInstanceManager().etemplate_exec_id || this._execId,
_queriedRange,
obj._filters,
this._widgetId,
_callback,
_context);
}
dataRegisterUID( _uid, _callback, _context)
{
this.egw.dataRegisterUID(_uid, _callback, _context,
this._widget.getInstanceManager().etemplate_exec_id || this._execId,
this._widgetId
);
}
dataUnregisterUID( )
{
// Overwritten in the constructor
}
}

View File

@ -1,3 +1,4 @@
"use strict";
/**
* EGroupware eTemplate2 - Class which contains a factory method for rows
*
@ -9,23 +10,36 @@
* @copyright Stylite 2012
* @version $Id$
*/
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
/*egw:uses
/vendor/bower-asset/jquery/dist/jquery.js;
et2_core_inheritance;
et2_core_interfaces;
et2_core_arrayMgr;
et2_core_widget;
et2_dataview_view_rowProvider;
*/
var et2_core_widget_1 = require("./et2_core_widget");
var et2_core_arrayMgr_1 = require("./et2_core_arrayMgr");
/**
* The row provider contains prototypes (full clonable dom-trees)
* for all registered row types.
*
* @augments Class
*/
var et2_nextmatch_rowProvider = (function(){ "use strict"; return ClassWithAttributes.extend(
{
var et2_nextmatch_rowProvider = /** @class */ (function () {
/**
* Creates the nextmatch row provider.
*
@ -34,15 +48,25 @@ var et2_nextmatch_rowProvider = (function(){ "use strict"; return ClassWithAttri
* @param {object} _context
* @memberOf et2_nextmatch_rowProvider
*/
init: function (_rowProvider, _subgridCallback, _context) {
function et2_nextmatch_rowProvider(_rowProvider, _subgridCallback, _context) {
/**
* Match category-ids from class attribute eg. "cat_15" or "123,456,789 "
*
* Make sure to not match numbers inside other class-names.
*
* We can NOT use something like /(^| |,|cat_)([0-9]+)( |,|$)/g as it wont find all cats in "123,456,789 "!
*/
this.cat_regexp = /(^| |,|cat_)([0-9]+)/g;
/**
* Regular expression used to filter out non-nummerical chars from above matches
*/
this.cat_cleanup = /[^0-9]/g;
// Copy the arguments
this._rowProvider = _rowProvider;
this._subgridCallback = _subgridCallback;
this._context = _context;
this._createEmptyPrototype();
},
}
/**
* Creates the data row prototype.
*
@ -51,13 +75,11 @@ var et2_nextmatch_rowProvider = (function(){ "use strict"; return ClassWithAttri
* @param _rootWidget is the parent widget of the data rows (i.e.
* the nextmatch)
*/
setDataRowTemplate: function(_widgets, _rowData, _rootWidget) {
et2_nextmatch_rowProvider.prototype.setDataRowTemplate = function (_widgets, _rowData, _rootWidget) {
// Copy the root widget
this._rootWidget = _rootWidget;
// Create the base row
var row = this._rowProvider.getPrototype("default");
// Copy the row template
var rowTemplate = {
"row": row[0],
@ -67,146 +89,105 @@ var et2_nextmatch_rowProvider = (function(){ "use strict"; return ClassWithAttri
"seperated": null,
"mgrs": _rootWidget.getArrayMgrs()
};
// Create the row widget and insert the given widgets into the row
var rowWidget = new et2_nextmatch_rowWidget(rowTemplate.mgrs, row[0]);
rowWidget._parent = _rootWidget;
rowWidget.createWidgets(_widgets);
// Get the set containing all variable attributes
var variableAttributes = this._getVariableAttributeSet(rowWidget);
// Filter out all widgets which do not implement the et2_IDetachedDOM
// interface or do not support all attributes listed in the et2_IDetachedDOM
// interface. A warning is issued for all those widgets as they heavily
// degrade the performance of the dataview
var seperated = rowTemplate.seperated =
this._seperateWidgets(variableAttributes);
// Remove all DOM-Nodes of all widgets inside the "remaining" slot from
// the row-template, then build the access functions for the detachable
// widgets
this._stripTemplateRow(rowTemplate);
this._buildNodeAccessFuncs(rowTemplate);
// Create the DOM row template
var tmpl = document.createDocumentFragment();
row.children().each(function() { tmpl.appendChild(this); });
row.children().each(function () { tmpl.appendChild(this); });
this._dataRow = tmpl;
this._template = rowTemplate;
},
getDataRow: function(_data, _row, _idx, _controller) {
};
et2_nextmatch_rowProvider.prototype.getDataRow = function (_data, _row, _idx, _controller) {
// Clone the row template
var row = this._dataRow.cloneNode(true);
// Create array managers with the given data merged in
var mgrs = et2_arrayMgrs_expand(rowWidget, this._template.mgrs,
_data, _idx);
var mgrs = et2_core_arrayMgr_1.et2_arrayMgrs_expand(rowWidget, this._template.mgrs, _data, _idx);
// Insert the widgets into the row which do not provide the functions
// to set the _data directly
var rowWidget = null;
if (this._template.seperated.remaining.length > 0)
{
if (this._template.seperated.remaining.length > 0) {
// Transform the variable attributes
for (var i = 0; i < this._template.seperated.remaining.length; i++)
{
for (var i = 0; i < this._template.seperated.remaining.length; i++) {
var entry = this._template.seperated.remaining[i];
for (var j = 0; j < entry.data.length; j++)
{
for (var j = 0; j < entry.data.length; j++) {
var set = entry.data[j];
entry.widget.options[set.attribute] = mgrs["content"].expandName(set.expression);
}
}
// Create the row widget
var rowWidget = new et2_nextmatch_rowTemplateWidget(this._rootWidget,
row);
var rowWidget = new et2_nextmatch_rowTemplateWidget(this._rootWidget, row);
// Let the row widget create the widgets
rowWidget.createWidgets(mgrs, this._template.placeholders);
}
// Update the content of all other widgets
for (var i = 0; i < this._template.seperated.detachable.length; i++)
{
for (var i = 0; i < this._template.seperated.detachable.length; i++) {
var entry = this._template.seperated.detachable[i];
// Parse the attribute expressions
var data = {};
for (var j = 0; j < entry.data.length; j++)
{
for (var j = 0; j < entry.data.length; j++) {
var set = entry.data[j];
data[set.attribute] = mgrs["content"].expandName(set.expression);
}
// Retrieve all DOM-Nodes
var nodes = new Array(entry.nodeFuncs.length);
for (var j = 0; j < nodes.length; j++)
{
for (var j = 0; j < nodes.length; j++) {
// Use the previously compiled node function to get the node
// from the entry
nodes[j] = entry.nodeFuncs[j](row);
}
// Set the array managers first
entry.widget._mgrs = mgrs;
if (typeof data.id != "undefined")
{
if (typeof data.id != "undefined") {
entry.widget.id = data.id;
}
// Adjust data for that row
entry.widget.transformAttributes.call(entry.widget,data);
entry.widget.transformAttributes.call(entry.widget, data);
// Call the setDetachedAttributes function
entry.widget.setDetachedAttributes(nodes, data, _data);
}
// Insert the row into the tr
var tr = _row.getDOMNode();
tr.appendChild(row);
// Make the row expandable
if (typeof _data.content["is_parent"] !== "undefined"
&& _data.content["is_parent"])
{
&& _data.content["is_parent"]) {
_row.makeExpandable(true, function () {
return this._subgridCallback.call(this._context,
_row, _data, _controller);
return this._subgridCallback.call(this._context, _row, _data, _controller);
}, this);
// Check for kept expansion, and set the row up to be re-expanded
// Only the top controller tracks expanded, including sub-grids
var top_controller = _controller;
while(top_controller._parentController != null)
{
while (top_controller._parentController != null) {
top_controller = top_controller._parentController;
}
var expansion_index = top_controller.kept_expansion.indexOf(
top_controller.dataStorePrefix + '::' + _data.content[this._context.settings.row_id]
);
if(top_controller.kept_expansion && expansion_index >=0)
{
top_controller.kept_expansion.splice(expansion_index,1);
var expansion_index = top_controller.kept_expansion.indexOf(top_controller.dataStorePrefix + '::' + _data.content[this._context.settings.row_id]);
if (top_controller.kept_expansion && expansion_index >= 0) {
top_controller.kept_expansion.splice(expansion_index, 1);
// Use a timeout since the DOM nodes might not be finished yet
window.setTimeout(function() {
window.setTimeout(function () {
_row.expansionButton.trigger('click');
},ET2_GRID_INVALIDATE_TIMEOUT);
}, et2_dataview_grid.ET2_GRID_INVALIDATE_TIMEOUT);
}
}
// Set the row data
this._setRowData(this._template.rowData, tr, mgrs);
return rowWidget;
},
};
/**
* Placeholder for empty row
*
@ -214,47 +195,38 @@ var et2_nextmatch_rowProvider = (function(){ "use strict"; return ClassWithAttri
* This allows the user to still have a drop target, or use actions that
* do not require a row ID, such as 'Add new'.
*/
_createEmptyPrototype: function() {
et2_nextmatch_rowProvider.prototype._createEmptyPrototype = function () {
var label = this._context && this._context.options && this._context.options.settings.placeholder;
var placeholder = jQuery(document.createElement("td"))
.attr("colspan",this._rowProvider.getColumnCount())
.css("height","19px")
.attr("colspan", this._rowProvider.getColumnCount())
.css("height", "19px")
.text(typeof label != "undefined" && label ? label : egw().lang("No matches found"));
this._rowProvider._prototypes["empty"] = jQuery(document.createElement("tr"))
.addClass("egwGridView_empty")
.append(placeholder);
},
};
/** -- PRIVATE FUNCTIONS -- **/
/**
* Returns an array containing objects which have variable attributes
*
* @param {et2_widget} _widget
*/
_getVariableAttributeSet: function(_widget) {
et2_nextmatch_rowProvider.prototype._getVariableAttributeSet = function (_widget) {
var variableAttributes = [];
_widget.iterateOver(function(_widget) {
_widget.iterateOver(function (_widget) {
// Create the attribtues
var hasAttr = false;
var widgetData = {
"widget": _widget,
"data": []
};
// Get all attribute values
for (var key in _widget.attributes)
{
for (var key in _widget.attributes) {
if (!_widget.attributes[key].ignore &&
typeof _widget.options[key] != "undefined")
{
typeof _widget.options[key] != "undefined") {
var val = _widget.options[key];
// TODO: Improve detection
if (typeof val == "string" && val.indexOf("$") >= 0)
{
if (typeof val == "string" && val.indexOf("$") >= 0) {
hasAttr = true;
widgetData.data.push({
"attribute": key,
@ -263,233 +235,161 @@ var et2_nextmatch_rowProvider = (function(){ "use strict"; return ClassWithAttri
}
}
}
// Add the entry if there is any data in it
if (hasAttr)
{
if (hasAttr) {
variableAttributes.push(widgetData);
}
}, this);
return variableAttributes;
},
_seperateWidgets: function(_varAttrs) {
};
et2_nextmatch_rowProvider.prototype._seperateWidgets = function (_varAttrs) {
// The detachable array contains all widgets which implement the
// et2_IDetachedDOM interface for all needed attributes
var detachable = [];
// The remaining array creates all widgets which have to be completely
// cloned when the widget tree is created
var remaining = [];
// Iterate over the widgets
for (var i = 0; i < _varAttrs.length; i++)
{
for (var i = 0; i < _varAttrs.length; i++) {
var widget = _varAttrs[i].widget;
// Check whether the widget parents are not allready in the "remaining"
// slot - if this is the case do not include the widget at all.
var insertWidget = true;
var checkWidget = function (_widget) {
if (_widget.parent != null)
{
for (var i = 0; i < remaining.length; i++)
{
if (remaining[i].widget == _widget.parent)
{
if (_widget.parent != null) {
for (var i = 0; i < remaining.length; i++) {
if (remaining[i].widget == _widget.parent) {
insertWidget = false;
return;
}
}
checkWidget(_widget.parent);
}
};
checkWidget(widget);
// Handle the next widget if this one should not be included.
if (!insertWidget)
{
if (!insertWidget) {
continue;
}
// Check whether the widget implements the et2_IDetachedDOM interface
var isDetachable = false;
if (widget.implements(et2_IDetachedDOM))
{
if (widget.implements(et2_IDetachedDOM)) {
// Get all attributes the widgets supports to be set in the
// "detached" mode
var supportedAttrs = [];
widget.getDetachedAttributes(supportedAttrs);
supportedAttrs.push("id");
isDetachable = true;
for (var j = 0; j < _varAttrs[i].data.length/* && isDetachable*/; j++)
{
for (var j = 0; j < _varAttrs[i].data.length /* && isDetachable*/; j++) {
var data = _varAttrs[i].data[j];
var supportsAttr = supportedAttrs.indexOf(data.attribute) != -1;
if (!supportsAttr)
{
if (!supportsAttr) {
egw.debug("warn", "et2_IDetachedDOM widget " +
widget._type + " does not support " + data.attribute);
}
isDetachable &= supportsAttr;
isDetachable = isDetachable && supportsAttr;
}
}
// Insert the widget into the correct slot
if (isDetachable)
{
if (isDetachable) {
detachable.push(_varAttrs[i]);
}
else
{
else {
remaining.push(_varAttrs[i]);
}
}
return {
"detachable": detachable,
"remaining": remaining
};
},
};
/**
* Removes to DOM code for all widgets in the "remaining" slot
*
* @param {object} _rowTemplate
*/
_stripTemplateRow: function(_rowTemplate) {
et2_nextmatch_rowProvider.prototype._stripTemplateRow = function (_rowTemplate) {
_rowTemplate.placeholders = [];
for (var i = 0; i < _rowTemplate.seperated.remaining.length; i++)
{
for (var i = 0; i < _rowTemplate.seperated.remaining.length; i++) {
var entry = _rowTemplate.seperated.remaining[i];
// Issue a warning - widgets which do not implement et2_IDOMNode
// are very slow
egw.debug("warn", "Non-clonable widget '"+ entry.widget._type + "' in dataview row - this " +
egw.debug("warn", "Non-clonable widget '" + entry.widget._type + "' in dataview row - this " +
"might be slow", entry);
// Set the placeholder for the entry to null
entry.placeholder = null;
// Get the outer DOM-Node of the widget
if (entry.widget.implements(et2_IDOMNode))
{
if (entry.widget.implements(et2_IDOMNode)) {
var node = entry.widget.getDOMNode(entry.widget);
if (node && node.parentNode)
{
if (node && node.parentNode) {
// Get the parent node and replace the node with a placeholder
entry.placeholder = document.createElement("span");
node.parentNode.replaceChild(entry.placeholder, node);
_rowTemplate.placeholders.push({
"widget": entry.widget,
"func": this._compileDOMAccessFunc(_rowTemplate.row,
entry.placeholder)
"func": this._compileDOMAccessFunc(_rowTemplate.row, entry.placeholder)
});
}
}
}
},
_nodeIndex: function(_node) {
if(_node.parentNode == null)
{
};
et2_nextmatch_rowProvider.prototype._nodeIndex = function (_node) {
if (_node.parentNode == null) {
return 0;
}
for (var i = 0; i < _node.parentNode.childNodes.length; i++)
{
if (_node.parentNode.childNodes[i] == _node)
{
for (var i = 0; i < _node.parentNode.childNodes.length; i++) {
if (_node.parentNode.childNodes[i] == _node) {
return i;
}
}
return -1;
},
};
/**
* Returns a function which does a relative access on the given DOM-Node
*
* @param {DOMElement} _root
* @param {DOMElement} _target
*/
_compileDOMAccessFunc: function(_root, _target) {
function recordPath(_root, _target, _path)
{
if (typeof _path == "undefined")
{
et2_nextmatch_rowProvider.prototype._compileDOMAccessFunc = function (_root, _target) {
function recordPath(_root, _target, _path) {
if (typeof _path == "undefined") {
_path = [];
}
if (_root != _target && _target)
{
if (_root != _target && _target) {
// Get the index of _target in its parent node
var idx = this._nodeIndex(_target);
if (idx >= 0)
{
if (idx >= 0) {
// Add the access selector
_path.unshift("childNodes[" + idx + "]");
// Record the remaining path
return recordPath.call(this, _root, _target.parentNode, _path);
}
throw("Internal error while compiling DOM access function.");
throw ("Internal error while compiling DOM access function.");
}
else
{
else {
_path.unshift("_node");
return "return " + _path.join(".") + ";";
}
}
return new Function("_node", recordPath.call(this, _root, _target));
},
};
/**
* Builds relative paths to the DOM-Nodes and compiles fast-access functions
*
* @param {object} _rowTemplate
*/
_buildNodeAccessFuncs: function(_rowTemplate) {
for (var i = 0; i < _rowTemplate.seperated.detachable.length; i++)
{
et2_nextmatch_rowProvider.prototype._buildNodeAccessFuncs = function (_rowTemplate) {
for (var i = 0; i < _rowTemplate.seperated.detachable.length; i++) {
var entry = _rowTemplate.seperated.detachable[i];
// Get all needed nodes from the widget
var nodes = entry.widget.getDetachedNodes();
var nodeFuncs = entry.nodeFuncs = new Array(nodes.length);
// Record the path to each DOM-Node
for (var j = 0; j < nodes.length; j++)
{
nodeFuncs[j] = this._compileDOMAccessFunc(_rowTemplate.row,
nodes[j]);
for (var j = 0; j < nodes.length; j++) {
nodeFuncs[j] = this._compileDOMAccessFunc(_rowTemplate.row, nodes[j]);
}
}
},
/**
* Match category-ids from class attribute eg. "cat_15" or "123,456,789 "
*
* Make sure to not match numbers inside other class-names.
*
* We can NOT use something like /(^| |,|cat_)([0-9]+)( |,|$)/g as it wont find all cats in "123,456,789 "!
*/
cat_regexp: /(^| |,|cat_)([0-9]+)/g,
/**
* Regular expression used to filter out non-nummerical chars from above matches
*/
cat_cleanup: /[^0-9]/g,
};
/**
* Applies additional row data (like the class) to the tr
*
@ -497,52 +397,45 @@ var et2_nextmatch_rowProvider = (function(){ "use strict"; return ClassWithAttri
* @param {DOMElement} _tr
* @param {object} _mgrs
*/
_setRowData: function (_data, _tr, _mgrs) {
et2_nextmatch_rowProvider.prototype._setRowData = function (_data, _tr, _mgrs) {
// TODO: Implement other fields than "class"
if (_data["class"])
{
if (_data["class"]) {
var classes = _mgrs["content"].expandName(_data["class"]);
// Get fancy with categories
var cats = [];
// Assume any numeric class is a category
if(_data["class"].indexOf("cat") !== -1 || classes.match(/[0-9]+/))
{
if (_data["class"].indexOf("cat") !== -1 || classes.match(/[0-9]+/)) {
// Accept either cat, cat_id or category as ID, and look there for category settings
var category_location = _data["class"].match(/(cat(_id|egory)?)/);
if(category_location) category_location = category_location[0];
if (category_location)
category_location = category_location[0];
cats = classes.match(this.cat_regexp) || [];
classes = classes.replace(this.cat_regexp, '');
// Set category class
for(var i = 0; i < cats.length; i++)
{
for (var i = 0; i < cats.length; i++) {
// Need cat_, classes can't start with a number
var cat_id = cats[i].replace(this.cat_cleanup, '');
var cat_class = 'cat_'+cat_id;
classes += ' '+cat_class;
var cat_class = 'cat_' + cat_id;
classes += ' ' + cat_class;
}
classes += " row_category";
}
classes += " row";
_tr.setAttribute("class", classes);
}
if(_data['valign'])
{
if (_data['valign']) {
var align = _mgrs["content"].expandName(_data["valign"]);
_tr.setAttribute("valign", align);
}
}
});}).call(this);
};
return et2_nextmatch_rowProvider;
}());
exports.et2_nextmatch_rowProvider = et2_nextmatch_rowProvider;
/**
* @augments et2_widget
*/
var et2_nextmatch_rowWidget = (function(){ "use strict"; return et2_widget.extend(et2_IDOMNode,
{
var et2_nextmatch_rowWidget = /** @class */ (function (_super) {
__extends(et2_nextmatch_rowWidget, _super);
/**
* Constructor
*
@ -550,67 +443,59 @@ var et2_nextmatch_rowWidget = (function(){ "use strict"; return et2_widget.exten
* @param _row
* @memberOf et2_nextmatch_rowWidget
*/
init: function(_mgrs, _row) {
function et2_nextmatch_rowWidget(_mgrs, _row) {
var _this =
// Call the parent constructor with some dummy attributes
this._super(null, {"id": "", "type": "rowWidget"});
_super.call(this, null, { "id": "", "type": "rowWidget" }) || this;
// Initialize some variables
this._widgets = [];
_this._widgets = [];
// Copy the given DOM node and the content arrays
this._mgrs = _mgrs;
this._row = _row;
},
_this._mgrs = _mgrs;
_this._row = _row;
return _this;
}
/**
* Copies the given array manager and clones the given widgets and inserts
* them into the row which has been passed in the constructor.
*
* @param {array} _widgets
*/
createWidgets: function(_widgets) {
et2_nextmatch_rowWidget.prototype.createWidgets = function (_widgets) {
// Clone the given the widgets with this element as parent
this._widgets = new Array(_widgets.length);
for (var i = 0; i < _widgets.length; i++)
{
for (var i = 0; i < _widgets.length; i++) {
// Disabled columns might be missing widget - skip it
if(!_widgets[i]) continue;
if (!_widgets[i])
continue;
this._widgets[i] = _widgets[i].clone(this);
this._widgets[i].loadingFinished();
// Set column alignment from widget
if(this._widgets[i].align)
{
if (this._widgets[i].align) {
this._row.childNodes[i].align = this._widgets[i].align;
}
}
},
};
/**
* Returns the column node for the given sender
*
* @param {et2_widget} _sender
* @return {DOMElement}
*/
getDOMNode: function(_sender) {
for (var i = 0; i < this._widgets.length; i++)
{
if (this._widgets[i] == _sender)
{
et2_nextmatch_rowWidget.prototype.getDOMNode = function (_sender) {
for (var i = 0; i < this._widgets.length; i++) {
if (this._widgets[i] == _sender) {
return this._row.childNodes[i].childNodes[0]; // Return the i-th td tag
}
}
return null;
}
});}).call(this);
};
return et2_nextmatch_rowWidget;
}(et2_core_widget_1.et2_widget));
/**
* @augments et2_widget
*/
var et2_nextmatch_rowTemplateWidget = (function(){ "use strict"; return et2_widget.extend(et2_IDOMNode,
{
var et2_nextmatch_rowTemplateWidget = /** @class */ (function (_super) {
__extends(et2_nextmatch_rowTemplateWidget, _super);
/**
* Constructor
*
@ -618,57 +503,47 @@ var et2_nextmatch_rowTemplateWidget = (function(){ "use strict"; return et2_widg
* @param _row
* @memberOf et2_nextmatch_rowTemplateWidget
*/
init: function(_root, _row) {
function et2_nextmatch_rowTemplateWidget(_root, _row) {
var _this =
// Call the parent constructor with some dummy attributes
this._super(null, {"id": "", "type": "rowTemplateWidget"});
this._root = _root;
this._mgrs = {};
this._row = _row;
_super.call(this, null, { "id": "", "type": "rowTemplateWidget" }) || this;
_this._root = _root;
_this._mgrs = {};
_this._row = _row;
// Set parent to root widget, so sub-widget calls still work
this._parent = _root;
_this._parent = _root;
// Clone the widgets inside the placeholders array
this._widgets = [];
},
createWidgets: function(_mgrs, _widgets) {
_this._widgets = [];
return _this;
}
et2_nextmatch_rowTemplateWidget.prototype.createWidgets = function (_mgrs, _widgets) {
// Set the array managers - don't use setArrayMgrs here as this creates
// an unnecessary copy of the object
this._mgrs = _mgrs;
this._widgets = new Array(_widgets.length);
for (var i = 0; i < _widgets.length; i++)
{
for (var i = 0; i < _widgets.length; i++) {
this._row.childNodes[0].childNodes[0];
this._widgets[i] = {
"widget": _widgets[i].widget.clone(this),
"node": _widgets[i].func(this._row)
};
this._widgets[i].widget.loadingFinished();
}
},
};
/**
* Returns the column node for the given sender
*
* @param {et2_widget} _sender
* @return {DOMElement}
*/
getDOMNode: function(_sender) {
for (var i = 0; i < this._widgets.length; i++)
{
if (this._widgets[i].widget == _sender)
{
et2_nextmatch_rowTemplateWidget.prototype.getDOMNode = function (_sender) {
for (var i = 0; i < this._widgets.length; i++) {
if (this._widgets[i].widget == _sender) {
return this._widgets[i].node;
}
}
return null;
}
});}).call(this);
};
return et2_nextmatch_rowTemplateWidget;
}(et2_core_widget_1.et2_widget));
//# sourceMappingURL=et2_extension_nextmatch_rowProvider.js.map

View File

@ -0,0 +1,706 @@
/**
* EGroupware eTemplate2 - Class which contains a factory method for rows
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package etemplate
* @subpackage api
* @link http://www.egroupware.org
* @author Andreas Stöckel
* @copyright Stylite 2012
* @version $Id$
*/
/*egw:uses
/vendor/bower-asset/jquery/dist/jquery.js;
et2_core_inheritance;
et2_core_interfaces;
et2_core_arrayMgr;
et2_core_widget;
et2_dataview_view_rowProvider;
*/
import {et2_widget} from "./et2_core_widget";
import {et2_arrayMgrs_expand} from "./et2_core_arrayMgr";
import {et2_dataview_rowProvider} from "./et2_dataview_view_rowProvider";
/**
* The row provider contains prototypes (full clonable dom-trees)
* for all registered row types.
*
*/
export class et2_nextmatch_rowProvider
{
private _rowProvider: any;
private _subgridCallback: any;
private _context: any;
private _rootWidget: any;
private _template: any;
/**
* Creates the nextmatch row provider.
*
* @param {et2_nextmatch_rowProvider} _rowProvider
* @param {function} _subgridCallback
* @param {object} _context
* @memberOf et2_nextmatch_rowProvider
*/
constructor( _rowProvider, _subgridCallback, _context)
{
// Copy the arguments
this._rowProvider = _rowProvider;
this._subgridCallback = _subgridCallback;
this._context = _context;
this._createEmptyPrototype();
}
/**
* Creates the data row prototype.
*
* @param _widgets is an array containing the root widget for each column.
* @param _rowData contains the properties of the root "tr" (like its class)
* @param _rootWidget is the parent widget of the data rows (i.e.
* the nextmatch)
*/
setDataRowTemplate( _widgets, _rowData, _rootWidget)
{
// Copy the root widget
this._rootWidget = _rootWidget;
// Create the base row
var row = this._rowProvider.getPrototype("default");
// Copy the row template
var rowTemplate = {
"row": row[0],
"rowData": _rowData,
"widgets": _widgets,
"root": _rootWidget,
"seperated": null,
"mgrs": _rootWidget.getArrayMgrs()
};
// Create the row widget and insert the given widgets into the row
var rowWidget = new et2_nextmatch_rowWidget(rowTemplate.mgrs, row[0]);
rowWidget._parent = _rootWidget;
rowWidget.createWidgets(_widgets);
// Get the set containing all variable attributes
var variableAttributes = this._getVariableAttributeSet(rowWidget);
// Filter out all widgets which do not implement the et2_IDetachedDOM
// interface or do not support all attributes listed in the et2_IDetachedDOM
// interface. A warning is issued for all those widgets as they heavily
// degrade the performance of the dataview
var seperated = rowTemplate.seperated =
this._seperateWidgets(variableAttributes);
// Remove all DOM-Nodes of all widgets inside the "remaining" slot from
// the row-template, then build the access functions for the detachable
// widgets
this._stripTemplateRow(rowTemplate);
this._buildNodeAccessFuncs(rowTemplate);
// Create the DOM row template
var tmpl = document.createDocumentFragment();
row.children().each(function() { tmpl.appendChild(this); });
this._dataRow = tmpl;
this._template = rowTemplate;
}
getDataRow( _data : any, _row, _idx, _controller)
{
// Clone the row template
var row = this._dataRow.cloneNode(true);
// Create array managers with the given data merged in
var mgrs = et2_arrayMgrs_expand(rowWidget, this._template.mgrs,
_data, _idx);
// Insert the widgets into the row which do not provide the functions
// to set the _data directly
var rowWidget : et2_nextmatch_rowTemplateWidget = null;
if (this._template.seperated.remaining.length > 0)
{
// Transform the variable attributes
for (var i = 0; i < this._template.seperated.remaining.length; i++)
{
var entry = this._template.seperated.remaining[i];
for (var j = 0; j < entry.data.length; j++)
{
var set = entry.data[j];
entry.widget.options[set.attribute] = mgrs["content"].expandName(set.expression);
}
}
// Create the row widget
var rowWidget = new et2_nextmatch_rowTemplateWidget(this._rootWidget,
row);
// Let the row widget create the widgets
rowWidget.createWidgets(mgrs, this._template.placeholders);
}
// Update the content of all other widgets
for (var i = 0; i < this._template.seperated.detachable.length; i++)
{
var entry = this._template.seperated.detachable[i];
// Parse the attribute expressions
var data : any = {};
for (var j = 0; j < entry.data.length; j++)
{
var set = entry.data[j];
data[set.attribute] = mgrs["content"].expandName(set.expression);
}
// Retrieve all DOM-Nodes
var nodes = new Array(entry.nodeFuncs.length);
for (var j = 0; j < nodes.length; j++)
{
// Use the previously compiled node function to get the node
// from the entry
nodes[j] = entry.nodeFuncs[j](row);
}
// Set the array managers first
entry.widget._mgrs = mgrs;
if (typeof data.id != "undefined")
{
entry.widget.id = data.id;
}
// Adjust data for that row
entry.widget.transformAttributes.call(entry.widget,data);
// Call the setDetachedAttributes function
entry.widget.setDetachedAttributes(nodes, data, _data);
}
// Insert the row into the tr
var tr = _row.getDOMNode();
tr.appendChild(row);
// Make the row expandable
if (typeof _data.content["is_parent"] !== "undefined"
&& _data.content["is_parent"])
{
_row.makeExpandable(true, function () {
return this._subgridCallback.call(this._context,
_row, _data, _controller);
}, this);
// Check for kept expansion, and set the row up to be re-expanded
// Only the top controller tracks expanded, including sub-grids
var top_controller = _controller;
while(top_controller._parentController != null)
{
top_controller = top_controller._parentController;
}
var expansion_index = top_controller.kept_expansion.indexOf(
top_controller.dataStorePrefix + '::' + _data.content[this._context.settings.row_id]
);
if(top_controller.kept_expansion && expansion_index >=0)
{
top_controller.kept_expansion.splice(expansion_index,1);
// Use a timeout since the DOM nodes might not be finished yet
window.setTimeout(function() {
_row.expansionButton.trigger('click');
},et2_dataview_grid.ET2_GRID_INVALIDATE_TIMEOUT);
}
}
// Set the row data
this._setRowData(this._template.rowData, tr, mgrs);
return rowWidget;
}
/**
* Placeholder for empty row
*
* The empty row placeholder is used when there are no results to display.
* This allows the user to still have a drop target, or use actions that
* do not require a row ID, such as 'Add new'.
*/
_createEmptyPrototype( )
{
var label = this._context && this._context.options && this._context.options.settings.placeholder;
var placeholder = jQuery(document.createElement("td"))
.attr("colspan",this._rowProvider.getColumnCount())
.css("height","19px")
.text(typeof label != "undefined" && label ? label : egw().lang("No matches found"));
this._rowProvider._prototypes["empty"] = jQuery(document.createElement("tr"))
.addClass("egwGridView_empty")
.append(placeholder);
}
/** -- PRIVATE FUNCTIONS -- **/
/**
* Returns an array containing objects which have variable attributes
*
* @param {et2_widget} _widget
*/
_getVariableAttributeSet( _widget)
{
var variableAttributes = [];
_widget.iterateOver(function(_widget) {
// Create the attribtues
var hasAttr = false;
var widgetData = {
"widget": _widget,
"data": []
};
// Get all attribute values
for (var key in _widget.attributes)
{
if (!_widget.attributes[key].ignore &&
typeof _widget.options[key] != "undefined")
{
var val = _widget.options[key];
// TODO: Improve detection
if (typeof val == "string" && val.indexOf("$") >= 0)
{
hasAttr = true;
widgetData.data.push({
"attribute": key,
"expression": val
});
}
}
}
// Add the entry if there is any data in it
if (hasAttr)
{
variableAttributes.push(widgetData);
}
}, this);
return variableAttributes;
}
_seperateWidgets( _varAttrs)
{
// The detachable array contains all widgets which implement the
// et2_IDetachedDOM interface for all needed attributes
var detachable = [];
// The remaining array creates all widgets which have to be completely
// cloned when the widget tree is created
var remaining = [];
// Iterate over the widgets
for (var i = 0; i < _varAttrs.length; i++)
{
var widget = _varAttrs[i].widget;
// Check whether the widget parents are not allready in the "remaining"
// slot - if this is the case do not include the widget at all.
var insertWidget = true;
var checkWidget = function (_widget) {
if (_widget.parent != null)
{
for (var i = 0; i < remaining.length; i++)
{
if (remaining[i].widget == _widget.parent)
{
insertWidget = false;
return;
}
}
checkWidget(_widget.parent);
}
};
checkWidget(widget);
// Handle the next widget if this one should not be included.
if (!insertWidget)
{
continue;
}
// Check whether the widget implements the et2_IDetachedDOM interface
var isDetachable = false;
if (widget.implements(et2_IDetachedDOM))
{
// Get all attributes the widgets supports to be set in the
// "detached" mode
var supportedAttrs = [];
widget.getDetachedAttributes(supportedAttrs);
supportedAttrs.push("id");
isDetachable = true;
for (var j = 0; j < _varAttrs[i].data.length/* && isDetachable*/; j++)
{
var data = _varAttrs[i].data[j];
var supportsAttr = supportedAttrs.indexOf(data.attribute) != -1;
if (!supportsAttr)
{
egw.debug("warn", "et2_IDetachedDOM widget " +
widget._type + " does not support " + data.attribute);
}
isDetachable = isDetachable && supportsAttr;
}
}
// Insert the widget into the correct slot
if (isDetachable)
{
detachable.push(_varAttrs[i]);
}
else
{
remaining.push(_varAttrs[i]);
}
}
return {
"detachable": detachable,
"remaining": remaining
};
}
/**
* Removes to DOM code for all widgets in the "remaining" slot
*
* @param {object} _rowTemplate
*/
_stripTemplateRow( _rowTemplate)
{
_rowTemplate.placeholders = [];
for (var i = 0; i < _rowTemplate.seperated.remaining.length; i++)
{
var entry = _rowTemplate.seperated.remaining[i];
// Issue a warning - widgets which do not implement et2_IDOMNode
// are very slow
egw.debug("warn", "Non-clonable widget '"+ entry.widget._type + "' in dataview row - this " +
"might be slow", entry);
// Set the placeholder for the entry to null
entry.placeholder = null;
// Get the outer DOM-Node of the widget
if (entry.widget.implements(et2_IDOMNode))
{
var node = entry.widget.getDOMNode(entry.widget);
if (node && node.parentNode)
{
// Get the parent node and replace the node with a placeholder
entry.placeholder = document.createElement("span");
node.parentNode.replaceChild(entry.placeholder, node);
_rowTemplate.placeholders.push({
"widget": entry.widget,
"func": this._compileDOMAccessFunc(_rowTemplate.row,
entry.placeholder)
});
}
}
}
}
_nodeIndex( _node)
{
if(_node.parentNode == null)
{
return 0;
}
for (var i = 0; i < _node.parentNode.childNodes.length; i++)
{
if (_node.parentNode.childNodes[i] == _node)
{
return i;
}
}
return -1;
}
/**
* Returns a function which does a relative access on the given DOM-Node
*
* @param {DOMElement} _root
* @param {DOMElement} _target
*/
_compileDOMAccessFunc( _root, _target)
{
function recordPath(_root, _target, _path)
{
if (typeof _path == "undefined")
{
_path = [];
}
if (_root != _target && _target)
{
// Get the index of _target in its parent node
var idx = this._nodeIndex(_target);
if (idx >= 0)
{
// Add the access selector
_path.unshift("childNodes[" + idx + "]");
// Record the remaining path
return recordPath.call(this, _root, _target.parentNode, _path);
}
throw("Internal error while compiling DOM access function.");
}
else
{
_path.unshift("_node");
return "return " + _path.join(".") + ";";
}
}
return new Function("_node", recordPath.call(this, _root, _target));
}
/**
* Builds relative paths to the DOM-Nodes and compiles fast-access functions
*
* @param {object} _rowTemplate
*/
_buildNodeAccessFuncs( _rowTemplate)
{
for (var i = 0; i < _rowTemplate.seperated.detachable.length; i++)
{
var entry = _rowTemplate.seperated.detachable[i];
// Get all needed nodes from the widget
var nodes = entry.widget.getDetachedNodes();
var nodeFuncs = entry.nodeFuncs = new Array(nodes.length);
// Record the path to each DOM-Node
for (var j = 0; j < nodes.length; j++)
{
nodeFuncs[j] = this._compileDOMAccessFunc(_rowTemplate.row,
nodes[j]);
}
}
}
/**
* Match category-ids from class attribute eg. "cat_15" or "123,456,789 "
*
* Make sure to not match numbers inside other class-names.
*
* We can NOT use something like /(^| |,|cat_)([0-9]+)( |,|$)/g as it wont find all cats in "123,456,789 "!
*/
cat_regexp: RegExp = /(^| |,|cat_)([0-9]+)/g;
/**
* Regular expression used to filter out non-nummerical chars from above matches
*/
cat_cleanup: RegExp = /[^0-9]/g;
/**
* Applies additional row data (like the class) to the tr
*
* @param {object} _data
* @param {DOMElement} _tr
* @param {object} _mgrs
*/
_setRowData( _data, _tr, _mgrs)
{
// TODO: Implement other fields than "class"
if (_data["class"])
{
var classes = _mgrs["content"].expandName(_data["class"]);
// Get fancy with categories
var cats = [];
// Assume any numeric class is a category
if(_data["class"].indexOf("cat") !== -1 || classes.match(/[0-9]+/))
{
// Accept either cat, cat_id or category as ID, and look there for category settings
var category_location = _data["class"].match(/(cat(_id|egory)?)/);
if(category_location) category_location = category_location[0];
cats = classes.match(this.cat_regexp) || [];
classes = classes.replace(this.cat_regexp, '');
// Set category class
for(var i = 0; i < cats.length; i++)
{
// Need cat_, classes can't start with a number
var cat_id = cats[i].replace(this.cat_cleanup, '');
var cat_class = 'cat_'+cat_id;
classes += ' '+cat_class;
}
classes += " row_category";
}
classes += " row";
_tr.setAttribute("class", classes);
}
if(_data['valign'])
{
var align = _mgrs["content"].expandName(_data["valign"]);
_tr.setAttribute("valign", align);
}
}
}
/**
* @augments et2_widget
*/
class et2_nextmatch_rowWidget extends et2_widget implements et2_IDOMNode
{
private _widgets: any[];
private _row: any;
/**
* Constructor
*
* @param _mgrs
* @param _row
* @memberOf et2_nextmatch_rowWidget
*/
constructor( _mgrs, _row)
{
// Call the parent constructor with some dummy attributes
super(null, {"id": "", "type": "rowWidget"});
// Initialize some variables
this._widgets = [];
// Copy the given DOM node and the content arrays
this._mgrs = _mgrs;
this._row = _row;
}
/**
* Copies the given array manager and clones the given widgets and inserts
* them into the row which has been passed in the constructor.
*
* @param {array} _widgets
*/
createWidgets( _widgets)
{
// Clone the given the widgets with this element as parent
this._widgets = new Array(_widgets.length);
for (var i = 0; i < _widgets.length; i++)
{
// Disabled columns might be missing widget - skip it
if(!_widgets[i]) continue;
this._widgets[i] = _widgets[i].clone(this);
this._widgets[i].loadingFinished();
// Set column alignment from widget
if(this._widgets[i].align)
{
this._row.childNodes[i].align = this._widgets[i].align;
}
}
}
/**
* Returns the column node for the given sender
*
* @param {et2_widget} _sender
* @return {DOMElement}
*/
getDOMNode( _sender)
{
for (var i = 0; i < this._widgets.length; i++)
{
if (this._widgets[i] == _sender)
{
return this._row.childNodes[i].childNodes[0]; // Return the i-th td tag
}
}
return null;
}
}
/**
* @augments et2_widget
*/
class et2_nextmatch_rowTemplateWidget extends et2_widget implements et2_IDOMNode
{
private _root: any;
private _row: any;
private _widgets: any[];
/**
* Constructor
*
* @param _root
* @param _row
* @memberOf et2_nextmatch_rowTemplateWidget
*/
constructor( _root, _row)
{
// Call the parent constructor with some dummy attributes
super(null, {"id": "", "type": "rowTemplateWidget"});
this._root = _root;
this._mgrs = {};
this._row = _row;
// Set parent to root widget, so sub-widget calls still work
this._parent = _root;
// Clone the widgets inside the placeholders array
this._widgets = [];
}
createWidgets( _mgrs, _widgets : {widget : et2_widget,func(_row: any): any; }[])
{
// Set the array managers - don't use setArrayMgrs here as this creates
// an unnecessary copy of the object
this._mgrs = _mgrs;
this._widgets = new Array(_widgets.length);
for (var i = 0; i < _widgets.length; i++)
{
this._row.childNodes[0].childNodes[0];
this._widgets[i] = {
"widget": _widgets[i].widget.clone(this),
"node": _widgets[i].func(this._row)
};
this._widgets[i].widget.loadingFinished();
}
}
/**
* Returns the column node for the given sender
*
* @param {et2_widget} _sender
* @return {DOMElement}
*/
getDOMNode( _sender: et2_widget): HTMLElement
{
for (var i = 0; i < this._widgets.length; i++)
{
if (this._widgets[i].widget == _sender)
{
return this._widgets[i].node;
}
}
return null;
}
}

View File

@ -64,7 +64,7 @@ declare var et2_nextmatch_header : any;
declare var et2_nextmatch_customfields : any;
declare var et2_nextmatch_controller : any;
declare var et2_dynheight : any;
declare var et2_nextmatch_rowProvider : any;
declare class et2_nextmatch_rowProvider {}
declare var et2_nextmatch_rowWidget : any;
declare var et2_nextmatch_rowTemplateWidget : any;
declare var et2_ajaxSelect : any;

View File

@ -33,21 +33,21 @@ var et2_core_inheritance_1 = require("./et2_core_inheritance");
*
* @augments et2_textbox
*/
var et2_number = /** @class */ (function (_super_1) {
__extends(et2_number, _super_1);
var et2_number = /** @class */ (function (_super) {
__extends(et2_number, _super);
/**
* Constructor
*
* @memberOf et2_number
*/
function et2_number(_parent, _attrs, _child) {
var _this = _super_1.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_number._attributes, _child || {})) || this;
var _this = _super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_number._attributes, _child || {})) || this;
_this.min = null;
_this.max = null;
return _this;
}
et2_number.prototype.transformAttributes = function (_attrs) {
_super_1.prototype.transformAttributes.call(this, _attrs);
_super.prototype.transformAttributes.call(this, _attrs);
if (typeof _attrs.validator == 'undefined') {
_attrs.validator = _attrs.type == 'float' ? '/^-?[0-9]*[,.]?[0-9]*$/' : '/^-?[0-9]*$/';
}
@ -64,7 +64,7 @@ var et2_number = /** @class */ (function (_super_1) {
_messages.push(this.input[0].validationMessage);
ok = false;
}
return _super_1.prototype.isValid.call(this, _messages) && ok;
return _super.prototype.isValid.call(this, _messages) && ok;
};
et2_number.prototype.createInputWidget = function () {
this.input = jQuery(document.createElement("input"));
@ -153,16 +153,16 @@ et2_core_widget_1.et2_register_widget(et2_number, ["int", "integer", "float"]);
* @augments et2_textbox_ro
* @class
*/
var et2_number_ro = /** @class */ (function (_super_1) {
__extends(et2_number_ro, _super_1);
var et2_number_ro = /** @class */ (function (_super) {
__extends(et2_number_ro, _super);
function et2_number_ro() {
return _super_1 !== null && _super_1.apply(this, arguments) || this;
return _super !== null && _super.apply(this, arguments) || this;
}
et2_number_ro.prototype.set_value = function (_value) {
if (typeof this.options.precision != 'undefined' && "" + _value != "") {
_value = parseFloat(_value).toFixed(this.options.precision);
}
this._super.call(this, _value);
_super.prototype.set_value.call(this, _value);
};
et2_number_ro._attributes = {
min: { ignore: true },

View File

@ -179,7 +179,7 @@ class et2_number_ro extends et2_textbox_ro
{
_value = parseFloat(_value).toFixed(this.options.precision);
}
this._super.call(this, _value);
super.set_value(_value);
}
}
et2_register_widget(et2_number_ro, ["int_ro", "integer_ro", "float_ro"]);

View File

@ -297,7 +297,7 @@ var et2_radioGroup = /** @class */ (function (_super) {
et2_radioGroup.prototype.set_options = function (_options) {
// Call the destructor of all children
for (var i = this._children.length - 1; i >= 0; i--) {
this._children[i].free();
this._children[i].destroy();
}
this._children = [];
// create radio buttons for each option

View File

@ -367,7 +367,7 @@ class et2_radioGroup extends et2_valueWidget implements et2_IDetachedDOM
// Call the destructor of all children
for (let i = this._children.length - 1; i >= 0; i--)
{
this._children[i].free();
this._children[i].destroy();
}
this._children = [];
// create radio buttons for each option