mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 06:30:59 +01:00
Get nextmatch rendering, sort of
This commit is contained in:
parent
4eca12001a
commit
3f8bd1b494
@ -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
|
@ -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 = {};
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
1128
api/js/etemplate/et2_dataview_controller.ts
Normal file
1128
api/js/etemplate/et2_dataview_controller.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
720
api/js/etemplate/et2_dataview_controller_selection.ts
Normal file
720
api/js/etemplate/et2_dataview_controller_selection.ts
Normal 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();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
@ -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"]);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
203
api/js/etemplate/et2_dataview_view_row.ts
Normal file
203
api/js/etemplate/et2_dataview_view_row.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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
|
139
api/js/etemplate/et2_dataview_view_rowProvider.ts
Normal file
139
api/js/etemplate/et2_dataview_view_rowProvider.ts
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
112
api/js/etemplate/et2_dataview_view_spacer.ts
Normal file
112
api/js/etemplate/et2_dataview_view_spacer.ts
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
107
api/js/etemplate/et2_dataview_view_tile.ts
Normal file
107
api/js/etemplate/et2_dataview_view_tile.ts
Normal 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)));
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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')
|
||||
|
@ -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
|
769
api/js/etemplate/et2_extension_nextmatch_controller.ts
Normal file
769
api/js/etemplate/et2_extension_nextmatch_controller.ts
Normal 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
|
||||
}
|
||||
|
||||
}
|
@ -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
|
706
api/js/etemplate/et2_extension_nextmatch_rowProvider.ts
Normal file
706
api/js/etemplate/et2_extension_nextmatch_rowProvider.ts
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
2
api/js/etemplate/et2_types.d.ts
vendored
2
api/js/etemplate/et2_types.d.ts
vendored
@ -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;
|
||||
|
@ -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 },
|
||||
|
@ -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"]);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user