mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-27 09:09:04 +01:00
Support changing nextmatch template after initial load (ie: in get_rows callback)
This commit is contained in:
parent
df660bea3c
commit
17e8fa094d
@ -277,7 +277,8 @@ class etemplate_widget_nextmatch extends etemplate_widget
|
||||
{
|
||||
$value = ($value) ? array($value) : array();
|
||||
}
|
||||
$value = array_merge($value, $filters);
|
||||
$value = $value_in = array_merge($value, $filters);
|
||||
|
||||
//error_log(__METHOD__."('".substr($exec_id,0,10)."...', range=".array2string($queriedRange).', filters='.array2string($filters).", '$form_name', knownUids=".array2string($knownUids).", lastModified=$lastModified) parent_id=$value[parent_id], is_parent=$value[is_parent]");
|
||||
|
||||
$result = array();
|
||||
@ -323,6 +324,30 @@ class etemplate_widget_nextmatch extends etemplate_widget
|
||||
egw_json_response::get()->apply('egw_app_header', array($GLOBALS['egw_info']['flags']['app_header']));
|
||||
}
|
||||
|
||||
// Check for anything changed in the query
|
||||
// Tell the client about the changes
|
||||
$request_value =& self::get_array(self::$request->content, $form_name,true);
|
||||
$no_rows = false;
|
||||
foreach($value_in as $key => $original_value)
|
||||
{
|
||||
// These keys are ignored
|
||||
if(in_array($key, array('col_filter','start','num_rows','order','sort'))) continue;
|
||||
if($original_value == $value[$key]) continue;
|
||||
|
||||
// These keys we don't send row data back, as they cause a partial reload
|
||||
if(in_array($key, array('template'))) $no_rows = true;
|
||||
|
||||
$request_value[$key] = $value[$key];
|
||||
|
||||
egw_json_response::get()->generic('assign', array(
|
||||
'etemplate_exec_id' => self::$request->id(),
|
||||
'id' => $form_name,
|
||||
'key' => $key,
|
||||
'value' => $value[$key],
|
||||
));
|
||||
}
|
||||
if($no_rows) $rows = Array();
|
||||
|
||||
$row_id = isset($value['row_id']) ? $value['row_id'] : 'id';
|
||||
$row_modified = $value['row_modified'];
|
||||
$is_parent = $value['is_parent'];
|
||||
@ -406,6 +431,12 @@ class etemplate_widget_nextmatch extends etemplate_widget
|
||||
|
||||
//foreach($result as $name => $value) if ($name != 'readonlys') error_log(__METHOD__."() result['$name']=".array2string($name == 'data' ? array_keys($value) : $value));
|
||||
egw_json_response::get()->data($result);
|
||||
|
||||
// If etemplate_exec_id has changed, update the client side
|
||||
if (($new_id = self::$request->id()) != $id)
|
||||
{
|
||||
egw_json_response::get()->assign('etemplate_exec_id','value',$new_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -344,6 +344,14 @@ var et2_widget = Class.extend(
|
||||
|
||||
_node._parent = this;
|
||||
this._children.splice(_idx, 0, _node);
|
||||
|
||||
if(_node.implements(et2_IDOMNode) && this.implements(et2_IDOMNode) && _node.parentNode)
|
||||
{
|
||||
_node.detachFromDOM();
|
||||
_node.parentNode = this.getDOMNode(_node);
|
||||
_node.attachToDOM();
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -147,8 +147,7 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
|
||||
.addClass("et2_nextmatch");
|
||||
|
||||
|
||||
this.header = new et2_nextmatch_header_bar(this, this.div);
|
||||
|
||||
this.header = et2_createWidget("nextmatch_header_bar", {}, this);
|
||||
this.innerDiv = $j(document.createElement("div"))
|
||||
.appendTo(this.div);
|
||||
|
||||
@ -802,8 +801,6 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
|
||||
continue;
|
||||
}
|
||||
|
||||
// Append the widget to this container
|
||||
this.addChild(_row[x].widget);
|
||||
}
|
||||
|
||||
// Remove action column
|
||||
@ -817,6 +814,12 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
|
||||
// Create the column manager and update the grid container
|
||||
this.dataview.setColumns(columnData);
|
||||
|
||||
for (var x = 0; x < _row.length; x++)
|
||||
{
|
||||
// Append the widget to this container
|
||||
this.addChild(_row[x].widget);
|
||||
}
|
||||
|
||||
// Create the nextmatch row provider
|
||||
this.rowProvider = new et2_nextmatch_rowProvider(
|
||||
this.dataview.rowProvider, this._getSubgrid, this);
|
||||
@ -832,6 +835,11 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
|
||||
};
|
||||
|
||||
// Register handler for column selection popup, or disable
|
||||
if(this.selectPopup)
|
||||
{
|
||||
this.selectPopup.remove();
|
||||
this.selectPopup = null;
|
||||
}
|
||||
if(this.options.settings.no_columnselection)
|
||||
{
|
||||
this.dataview.selectColumnsClick = function() {return false;};
|
||||
@ -921,6 +929,7 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
|
||||
_grid.colData);
|
||||
}
|
||||
}
|
||||
this.resize();
|
||||
},
|
||||
|
||||
_getSubgrid: function (_row, _data, _controller) {
|
||||
@ -1180,9 +1189,23 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
|
||||
* that template and to fetch the grid which is inside of it. It then calls
|
||||
*/
|
||||
set_template: function(_value) {
|
||||
if (!this.template)
|
||||
if(this.template)
|
||||
{
|
||||
// Load the template
|
||||
// Free the grid components - they'll be re-created as the template is processed
|
||||
this.dataview.free();
|
||||
this.rowProvider.free();
|
||||
this.controller.free();
|
||||
|
||||
// Clear this setting if it's the same as the template, or
|
||||
// the columns will not be loaded
|
||||
if(this.template == this.options.settings.columnselection_pref)
|
||||
{
|
||||
this.options.settings.columnselection_pref = _value;
|
||||
}
|
||||
this.dataview = new et2_dataview(this.innerDiv, this.egw());
|
||||
}
|
||||
|
||||
// Create the template
|
||||
var template = et2_createWidget("template", {"id": _value}, this);
|
||||
|
||||
if (!template)
|
||||
@ -1192,6 +1215,12 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
|
||||
return;
|
||||
}
|
||||
|
||||
// Deferred parse function - template might not be fully loaded
|
||||
var parse = function(template)
|
||||
{
|
||||
// Keep the name of the template, as we'll free up the widget after parsing
|
||||
this.template = _value;
|
||||
|
||||
// Fetch the grid element and parse it
|
||||
var definitionGrid = template.getChildren()[0];
|
||||
if (definitionGrid && definitionGrid instanceof et2_grid)
|
||||
@ -1206,7 +1235,9 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
|
||||
}
|
||||
|
||||
// Free the template again, but don't remove it
|
||||
setTimeout(function() {
|
||||
template.free();
|
||||
},1);
|
||||
|
||||
// Call the "setNextmatch" function of all registered
|
||||
// INextmatchHeader widgets.
|
||||
@ -1223,9 +1254,29 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
|
||||
|
||||
// Start auto-refresh
|
||||
this._set_autorefresh(this._get_autorefresh());
|
||||
};
|
||||
if(template.getChildren().length == 0)
|
||||
{
|
||||
// Template might not be loaded yet, defer parsing
|
||||
$j(template.getDOMNode()).on("load",
|
||||
jQuery.proxy(function() {
|
||||
parse.call(this, template);
|
||||
//this.loadingFinished();
|
||||
this.resize();
|
||||
}, this)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(this.isAttached())
|
||||
{
|
||||
template.loadingFinished();
|
||||
}
|
||||
parse.call(this, template)
|
||||
}
|
||||
},
|
||||
|
||||
// Some accessors to match conventions
|
||||
set_hide_header: function(hide) {
|
||||
(hide ? this.header.div.hide() : this.header.div.show());
|
||||
},
|
||||
@ -1236,6 +1287,26 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
|
||||
set_header_right: function(template) {
|
||||
this.header._build_left_right("right",template);
|
||||
},
|
||||
set_no_filter: function(bool, filter_name) {
|
||||
if(typeof filter_name == 'undefined')
|
||||
{
|
||||
filter_name = 'filter'
|
||||
}
|
||||
|
||||
var filter = this.header[filter_name];
|
||||
if(filter)
|
||||
{
|
||||
filter.set_disabled(bool);
|
||||
}
|
||||
else if (bool)
|
||||
{
|
||||
filter = this.header._build_select(filter_name, 'select',
|
||||
this.settings[filter_name], this.settings[filter_name+'_no_lang']);
|
||||
}
|
||||
},
|
||||
set_no_filter2: function(bool) {
|
||||
this.set_no_filter(bool,'filter2');
|
||||
},
|
||||
|
||||
/**
|
||||
* Actions are handled by the controller, so ignore these
|
||||
@ -1344,10 +1415,13 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
|
||||
{
|
||||
return this.div[0];
|
||||
}
|
||||
|
||||
if (_sender == this.header)
|
||||
{
|
||||
return this.header.div[0];
|
||||
}
|
||||
for (var i = 0; i < this.columns.length; i++)
|
||||
{
|
||||
if (_sender == this.columns[i].widget)
|
||||
if (this.columns[i] && this.columns[i].widget && _sender == this.columns[i].widget)
|
||||
{
|
||||
return this.dataview.getHeaderContainerNode(i);
|
||||
}
|
||||
@ -1447,7 +1521,6 @@ var et2_nextmatch_header_bar = et2_DOMWidget.extend(et2_INextmatchHeader,
|
||||
*/
|
||||
init: function(nextmatch, nm_div) {
|
||||
this._super.apply(this, [nextmatch,nextmatch.options.settings]);
|
||||
this.nextmatch = nextmatch;
|
||||
|
||||
this.div = jQuery(document.createElement("div"))
|
||||
.addClass("nextmatch_header");
|
||||
@ -1461,9 +1534,17 @@ var et2_nextmatch_header_bar = et2_DOMWidget.extend(et2_INextmatchHeader,
|
||||
},
|
||||
|
||||
setNextmatch: function(nextmatch) {
|
||||
if(this.div) this.div.remove();
|
||||
var create_once = (this.nextmatch == null);
|
||||
this.nextmatch = nextmatch;
|
||||
if(create_once)
|
||||
{
|
||||
this._createHeader();
|
||||
}
|
||||
|
||||
// Bind row count
|
||||
this.nextmatch.dataview.grid.setInvalidateCallback(function () {
|
||||
this.count_total.text(this.nextmatch.dataview.grid.getTotalCount() + "");
|
||||
}, this);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1492,9 +1573,6 @@ var et2_nextmatch_header_bar = et2_DOMWidget.extend(et2_INextmatchHeader,
|
||||
|
||||
// Set up so if row count changes, display is updated
|
||||
// Register the handler which will update the "totalCount" display
|
||||
this.nextmatch.dataview.grid.setInvalidateCallback(function () {
|
||||
this.count_total.text(this.nextmatch.dataview.grid.getTotalCount() + "");
|
||||
}, this);
|
||||
|
||||
// Left & Right headers
|
||||
this.headers = [];
|
||||
@ -1624,32 +1702,6 @@ var et2_nextmatch_header_bar = et2_DOMWidget.extend(et2_INextmatchHeader,
|
||||
var header = et2_createWidget("template", {"id": template_name}, this);
|
||||
jQuery(header.getDOMNode()).addClass(left_or_right == "left" ? "et2_hbox_left":"et2_hbox_right").addClass("nm_header");
|
||||
this.headers.push(header);
|
||||
|
||||
// Bind onChange to update filter, and refresh if needed.
|
||||
// We need to do on load because the template file might have to be
|
||||
// fetched from the server, which is async
|
||||
var self = this;
|
||||
$j(header.getDOMNode()).on("load", jQuery.proxy(function() {
|
||||
var header = this;
|
||||
header.iterateOver(function(_widget) {
|
||||
// Previously set change function
|
||||
var widget_change = _widget.change;
|
||||
_widget.change = function(_node) {
|
||||
// Call previously set change function
|
||||
var result = widget_change.call(_widget,_node);
|
||||
|
||||
// Update filters
|
||||
if(result && _widget.isDirty()) {
|
||||
var value = this.getInstanceManager().getValues(header);
|
||||
// Filter now
|
||||
self.nextmatch.applyFilters(value[self.nextmatch.id]);
|
||||
}
|
||||
};
|
||||
|
||||
// Set activeFilters to current value
|
||||
//self.nextmatch.activeFilters[_widget.id] = _widget.getValue();
|
||||
}, this, et2_inputWidget);
|
||||
}, header));
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1851,11 +1903,36 @@ var et2_nextmatch_header_bar = et2_DOMWidget.extend(et2_INextmatchHeader,
|
||||
}
|
||||
for(var i = 0; i < this.headers.length; i++)
|
||||
{
|
||||
if(_sender == this.headers[i]) return this.header_div[0];
|
||||
if(_sender.id == this.headers[i].id && _sender._parent == this) return this.header_div[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
doLoadingFinished: function() {
|
||||
this._super.apply(this,arguments);
|
||||
var header = this;
|
||||
|
||||
// Add change handlers to input widgets in the header
|
||||
this.iterateOver(function(_widget) {
|
||||
// Previously set change function
|
||||
var widget_change = _widget.change;
|
||||
_widget.change = function(_node) {
|
||||
// Call previously set change function
|
||||
var result = widget_change.call(_widget,_node);
|
||||
|
||||
// Update filters
|
||||
if(result && _widget.isDirty()) {
|
||||
var value = this.getInstanceManager().getValues(header);
|
||||
// Filter now
|
||||
header.nextmatch.applyFilters(value[header.nextmatch.id]);
|
||||
}
|
||||
};
|
||||
|
||||
// Set activeFilters to current value
|
||||
//self.nextmatch.activeFilters[_widget.id] = _widget.getValue();
|
||||
}, this, et2_inputWidget);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
et2_register_widget(et2_nextmatch_header_bar, ["nextmatch_header_bar"]);
|
||||
|
||||
|
@ -234,7 +234,12 @@ var et2_nextmatch_controller = et2_dataview_controller.extend(et2_IDataProvider,
|
||||
*/
|
||||
_fetchCallback: function (_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)
|
||||
|
Loading…
Reference in New Issue
Block a user