From f2fc558e19bb3dbb6c7d1037843e4a224c51c5d7 Mon Sep 17 00:00:00 2001 From: Nathan Gray Date: Tue, 12 Feb 2013 15:46:14 +0000 Subject: [PATCH] - Add static methods to get into etemplate2 widget context from outside. Call etemplate2.getByApplication(app) or etemplate2.getByTemplate(name) for a list of etemplate2 objects - Add register_app_refresh() function to allow applications to specify a more intelligent way to refresh them - Change egw_refresh() to call registered refresh function, or if etemplate2 is available try that over reloading the whole page --- etemplate/js/etemplate2.js | 109 +++++++++++++++++++++++++++++++++++++ phpgwapi/js/jsapi/jsapi.js | 56 ++++++++++++++++++- 2 files changed, 164 insertions(+), 1 deletion(-) diff --git a/etemplate/js/etemplate2.js b/etemplate/js/etemplate2.js index 542ad2371f..ec7d4a014a 100644 --- a/etemplate/js/etemplate2.js +++ b/etemplate/js/etemplate2.js @@ -113,6 +113,19 @@ etemplate2.prototype.clear = function() this.widgetContainer.free(); this.widgetContainer = null; } + + // Remove self from the index + for(name in this.templates) + { + if(typeof etemplate2._byTemplate[name] == "undefined") continue; + for(var i = 0; i < etemplate2._byTemplate[name].length; i++) + { + if(etemplate2._byTemplate[name][i] == this) + { + etemplate2._byTemplate[name].splice(i,1); + } + } + } this.templates = {}; } @@ -196,6 +209,13 @@ etemplate2.prototype.load = function(_name, _url, _data) // Insert the document fragment to the DOM Container this.DOMContainer.appendChild(frag); + // Add into indexed list + if(typeof etemplate2._byTemplate[_name] == "undefined") + { + etemplate2._byTemplate[_name] = []; + } + etemplate2._byTemplate[_name].push(this); + // Trigger the "resize" event this.resize(); }, this); @@ -445,6 +465,95 @@ etemplate2.prototype.getValues = function(_root) return result; } + +/** + * "Intelligently" refresh the template based on the given ID + * + * Rather than blindly re-load the entire template, we try to be a little smarter about it. + * If there's a message provided, we try to find where it goes and set it directly. Then + * we look for a nextmatch widget, and tell it to refresh its data based on that ID. + * + * @param msg String Message to try to display. eg: "Entry added" + * @param id String|null Application specific entry ID to try to refresh + * @param type String|null Type of change. One of 'edit', 'delete', 'add' or null + * + * @see jsapi.egw_refresh() + * @see egw_fw.egw_refresh() + */ +etemplate2.prototype.refresh = function(msg, id, type) +{ + // We use et2_baseWidget in case the app uses something like HTML instead of label + this.widgetContainer.iterateOver(function(_widget) { + if (_widget.id == "msg" || _widget.id == "message") + { + _widget.set_Value(msg); + } + }, this, et2_baseWidget); + + + this.widgetContainer.iterateOver(function(_widget) { + // TODO: This is not quite right - will restrict to just this one row + /* + if(_widget.options.settings && _widget.options.settings.row_id) + { + _widget.activeFilters[_widget.options.settings.row_id] = id; + } + */ + // Trigger refresh + _widget.applyFilters(); + }, this, et2_nextmatch); +} + +// Some static things to make getting into widget context a little easier // + +/** + * List of etemplates by loaded template + */ +etemplate2._byTemplate = {}; + +/** + * Get a list of etemplate2 objects that loaded the given template name + * + * @param template String Name of the template that was loaded + * + * @return Array list of etemplate2 that have that template + */ + +etemplate2.getByTemplate = function(template) +{ + if(typeof etemplate2._byTemplate[template] != "undefined") + { + return etemplate2._byTemplate[template]; + } + else + { + // Return empty array so you can always iterate over results + return []; + } +}; + +/** + * Get a list of etemplate2 objects that are associated with the given application + * + * "Associated" is determined by the first part of the template + * + * @param template String Name of the template that was loaded + * + * @return Array list of etemplate2 that have that app as the first part of their loaded template + */ +etemplate2.getByApplication = function(app) +{ + var list = []; + for(var name in etemplate2._byTemplate) + { + if(name.indexOf(app + ".") == 0) + { + list = list.concat(etemplate2._byTemplate[name]); + } + } + return list; +} + function etemplate2_handle_load(_type, _response) { // Check the parameters diff --git a/phpgwapi/js/jsapi/jsapi.js b/phpgwapi/js/jsapi/jsapi.js index 3884066ac8..15df86cae2 100644 --- a/phpgwapi/js/jsapi/jsapi.js +++ b/phpgwapi/js/jsapi/jsapi.js @@ -235,11 +235,23 @@ function egw_refresh(_msg, _app, _id, _type, _targetapp, _replace, _with) var win = typeof _targetapp != 'undefined' ? egw_appWindow(_targetapp) : window; // if window defines an app_refresh method, just call it - if (typeof win.app_refresh != 'undefined') + if (typeof win.app_refresh != 'undefined' && win.app_refresh.registered(_app)) { win.app_refresh(_msg, _app, _id, _type); return; } + + // etemplate2 specific to avoid reloading whole page + if(etemplate2 && etemplate2.getByApplication) + { + var et2 = etemplate2.getByApplication(_app); + for(var i = 0; i < et2.length; i++) + { + et2[i].refresh(_msg,_id,_type); + } + return; + } + var href = win.location.href; if (typeof _replace != 'undefined') @@ -296,6 +308,48 @@ window.egw_getFramework = function() } } +/** + * Register a custom method to refresh an application in an intelligent way + * + * This function will be called any time the application needs to be refreshed. + * The default is to just reload, but with more detailed knowledge of the application + * internals, it should be possible to only refresh what is needed. + * + * The refresh function signature is: + * function (_msg, _app, _id, _type); + * returns void + * @see egw_refresh() + * + * @param appname String Name of the application + * @param refresh_func function to call when refreshing + */ +window.register_app_refresh = function(appname, refresh_func) +{ + var framework = window.egw_getFramework(); + if(framework != null && typeof framework.register_app_refresh == "function") + { + framework.register_app_refresh(appname,refresh_func); + } + else + { + if(typeof window.app_refresh != "function") + { + // Define the app_refresh stuff here + window.app_refresh = function(_msg, appname, _id, _type) { + if(window.app_refresh.registry[appname]) + { + window.app_refresh.registry[appname].call(this,_msg,appname,_id,_type); + } + }; + window.app_refresh.registry = {}; + window.app_refresh.registered = function(appname) { + return (typeof window.app_refresh.registry[appname] == "function"); + }; + } + window.app_refresh.registry[appname] = refresh_func; + } +} + function egw_set_checkbox_multiselect_enabled(_id, _enabled) {