egroupware_official/api/js/etemplate/et2_widget_template.js

239 lines
6.4 KiB
JavaScript
Raw Normal View History

/**
* EGroupware eTemplate2 - JS Template base class
*
* @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 2011
* @version $Id$
*/
/*egw:uses
et2_core_xml;
et2_core_DOMWidget;
*/
/**
* Class which implements the "template" XET-Tag. When the id parameter is set,
* the template class checks whether another template with this id already
* exists. If yes, this template is removed from the DOM tree, copied and
* inserted in place of this template.
*
* @augments et2_DOMWidget
*/
var et2_template = (function(){ "use strict"; return et2_DOMWidget.extend(
{
attributes: {
"template": {
"name": "Template",
"type": "string",
"description": "Name / ID of template with optional cache-buster ('?'+filemtime of template on server)",
"default": et2_no_init
},
"group": {
// TODO: Not implemented
"name": "Group",
"description":"Not implemented",
2013-04-09 09:22:35 +02:00
//"default": 0
"default": et2_no_init
},
"version": {
"name": "Version",
"type": "string",
"description": "Version of the template"
},
"lang": {
"name": "Language",
"type": "string",
"description": "Language the template is written in"
},
"content": {
"name": "Content index",
"default": et2_no_init,
"description": "Used for passing in specific content to the template other than what it would get by ID."
},
url: {
name: "URL of template",
type: "string",
description: "full URL to load template incl. cache-buster"
},
"onload": {
"name": "onload",
"type": "js",
"default": et2_no_init,
"description": "JS code which is executed after the template is loaded."
}
},
createNamespace: true,
Major update of the et2_widget internal structure. The following changes were made: - All attributes of the widgets are now parsed from XML before the widget itself is created. These attributes plus all default values are then added to an associative array. The associative array is passed as second parameter to the init function of et2_widget, but is also available as this.options *after* the constructor of the et2_widget baseclass has been called. The et2_widget constructor also calls a function parseArrayMgrAttrs(_attrs) - in this function widget implementations can read the values from e.g. the content and validation_errors array and merge it into the given _attrs associative array. After the complete internal widgettree is completely loaded and created the "loadingFinished" function gets called and invokes all given setter functions. After that it "glues" the DOM tree together. This should also (I didn't measure it) be a bit faster than before, when the DOM-Tree was created on the fly. Please have a look at the changes of the et2_textbox widget to see how this affects writing widgets. Note: The "id" property is copied to the object scope on the top of the et2_widget constructor. - When widgets are cloned the "options" array gets passed along to the newly created widget. This means that changes made on the widgets during runtime are not automatically copied to the clone - as this didn't happen anyhow it is not a really disadvantage. On the other side there should be no difference between widgets directly inside the "overlay" xet tag and widgets which are inside instanciated templates. - The selbox widget doesn't work anymore - it relied on the loadAttributes function which isn't available anymore. et2_selbox should use the parseArrayMgrAttrs function to access - I've commented out some of the "validator"-code in etemplate2.js as it created some error messages when destroying the widget tree.
2011-08-19 18:00:44 +02:00
/**
* Initializes this template widget as a simple container.
*
* @memberOf et2_template
* @param {et2_widget} _parent
* @param {object} _attrs
*/
init: function(_parent, _attrs) {
// Set this early, so it's available for creating namespace
if(_attrs.content)
{
this.content = _attrs.content;
}
Major update of the et2_widget internal structure. The following changes were made: - All attributes of the widgets are now parsed from XML before the widget itself is created. These attributes plus all default values are then added to an associative array. The associative array is passed as second parameter to the init function of et2_widget, but is also available as this.options *after* the constructor of the et2_widget baseclass has been called. The et2_widget constructor also calls a function parseArrayMgrAttrs(_attrs) - in this function widget implementations can read the values from e.g. the content and validation_errors array and merge it into the given _attrs associative array. After the complete internal widgettree is completely loaded and created the "loadingFinished" function gets called and invokes all given setter functions. After that it "glues" the DOM tree together. This should also (I didn't measure it) be a bit faster than before, when the DOM-Tree was created on the fly. Please have a look at the changes of the et2_textbox widget to see how this affects writing widgets. Note: The "id" property is copied to the object scope on the top of the et2_widget constructor. - When widgets are cloned the "options" array gets passed along to the newly created widget. This means that changes made on the widgets during runtime are not automatically copied to the clone - as this didn't happen anyhow it is not a really disadvantage. On the other side there should be no difference between widgets directly inside the "overlay" xet tag and widgets which are inside instanciated templates. - The selbox widget doesn't work anymore - it relied on the loadAttributes function which isn't available anymore. et2_selbox should use the parseArrayMgrAttrs function to access - I've commented out some of the "validator"-code in etemplate2.js as it created some error messages when destroying the widget tree.
2011-08-19 18:00:44 +02:00
this._super.apply(this, arguments);
this.div = document.createElement("div");
// Deferred object so we can load via AJAX
this.loading = jQuery.Deferred();
// run transformAttributes now, to get server-side modifications (url!)
if (_attrs.template)
{
this.id = _attrs.template;
this.transformAttributes(_attrs);
this.options = et2_cloneObject(_attrs);
_attrs = {};
}
if (this.id != "" || this.options.template)
Major update of the et2_widget internal structure. The following changes were made: - All attributes of the widgets are now parsed from XML before the widget itself is created. These attributes plus all default values are then added to an associative array. The associative array is passed as second parameter to the init function of et2_widget, but is also available as this.options *after* the constructor of the et2_widget baseclass has been called. The et2_widget constructor also calls a function parseArrayMgrAttrs(_attrs) - in this function widget implementations can read the values from e.g. the content and validation_errors array and merge it into the given _attrs associative array. After the complete internal widgettree is completely loaded and created the "loadingFinished" function gets called and invokes all given setter functions. After that it "glues" the DOM tree together. This should also (I didn't measure it) be a bit faster than before, when the DOM-Tree was created on the fly. Please have a look at the changes of the et2_textbox widget to see how this affects writing widgets. Note: The "id" property is copied to the object scope on the top of the et2_widget constructor. - When widgets are cloned the "options" array gets passed along to the newly created widget. This means that changes made on the widgets during runtime are not automatically copied to the clone - as this didn't happen anyhow it is not a really disadvantage. On the other side there should be no difference between widgets directly inside the "overlay" xet tag and widgets which are inside instanciated templates. - The selbox widget doesn't work anymore - it relied on the loadAttributes function which isn't available anymore. et2_selbox should use the parseArrayMgrAttrs function to access - I've commented out some of the "validator"-code in etemplate2.js as it created some error messages when destroying the widget tree.
2011-08-19 18:00:44 +02:00
{
var parts = (this.options.template || this.id).split('?');
var cache_buster = parts.length > 1 ? parts.pop() : null;
var template_name = parts.pop();
// Check to see if XML is known
var xml = null;
var templates = etemplate2.prototype.templates; // use global eTemplate cache
if(!(xml = templates[template_name]))
{
// Check to see if ID is short form --> prepend parent/top-level name
if(template_name.indexOf('.') < 0)
{
var root = _parent ? _parent.getRoot() : null;
var top_name = root && root._inst ? root._inst.name : null;
if (top_name && template_name.indexOf('.') < 0) template_name = top_name+'.'+template_name;
}
xml = templates[template_name];
if(!xml)
{
// Ask server
var url = this.options.url;
if (!this.options.url)
{
var splitted = template_name.split('.');
// use template base url from initial template, to continue using webdav, if that was loaded via webdav
url = this.getRoot()._inst.template_base_url + splitted.shift() + "/templates/default/" +
splitted.join('.')+ ".xet" + (cache_buster ? '?download='+cache_buster : '');
}
// if server did not give a cache-buster, fall back to current time
if (url.indexOf('?') == -1) url += '?download='+(new Date).valueOf();
if(this.options.url || splitted.length)
{
et2_loadXMLFromURL(url, function(_xmldoc) {
// Scan for templates and store them
for(var i = 0; i < _xmldoc.childNodes.length; i++) {
var template = _xmldoc.childNodes[i];
if(template.nodeName.toLowerCase() != "template") continue;
templates[template.getAttribute("id")] = template;
}
// Read the XML structure of the requested template
if (typeof templates[template_name] != 'undefined') this.loadFromXML(templates[template_name]);
// Update flag
this.loading.resolve();
}, this);
}
return;
}
}
if(xml !== null && typeof xml !== "undefined")
{
this.egw().debug("log", "Loading template from XML: ", template_name);
this.loadFromXML(xml);
// Don't call this here - done by caller, or on whole widget tree
//this.loadingFinished();
// But resolve the promise
this.loading.resolve();
}
else
{
this.egw().debug("warn", "Unable to find XML for ", template_name);
this.loading.reject();
}
}
else
{
// No actual template
this.loading.resolve();
}
},
/**
* Override parent to support content attribute
* Templates always have ID set, but seldom do we want them to
* create a namespace based on their ID.
*/
checkCreateNamespace: function() {
if(this.content)
{
var old_id = this.id;
this.id = this.content;
this._super.apply(this, arguments);
this.id = old_id;
}
},
Major update of the et2_widget internal structure. The following changes were made: - All attributes of the widgets are now parsed from XML before the widget itself is created. These attributes plus all default values are then added to an associative array. The associative array is passed as second parameter to the init function of et2_widget, but is also available as this.options *after* the constructor of the et2_widget baseclass has been called. The et2_widget constructor also calls a function parseArrayMgrAttrs(_attrs) - in this function widget implementations can read the values from e.g. the content and validation_errors array and merge it into the given _attrs associative array. After the complete internal widgettree is completely loaded and created the "loadingFinished" function gets called and invokes all given setter functions. After that it "glues" the DOM tree together. This should also (I didn't measure it) be a bit faster than before, when the DOM-Tree was created on the fly. Please have a look at the changes of the et2_textbox widget to see how this affects writing widgets. Note: The "id" property is copied to the object scope on the top of the et2_widget constructor. - When widgets are cloned the "options" array gets passed along to the newly created widget. This means that changes made on the widgets during runtime are not automatically copied to the clone - as this didn't happen anyhow it is not a really disadvantage. On the other side there should be no difference between widgets directly inside the "overlay" xet tag and widgets which are inside instanciated templates. - The selbox widget doesn't work anymore - it relied on the loadAttributes function which isn't available anymore. et2_selbox should use the parseArrayMgrAttrs function to access - I've commented out some of the "validator"-code in etemplate2.js as it created some error messages when destroying the widget tree.
2011-08-19 18:00:44 +02:00
getDOMNode: function() {
return this.div;
},
attachToDOM: function() {
if (this.div)
{
jQuery(this.div)
.off('.et2_template')
.bind("load.et2_template", this, function(e) {
e.data.load.call(e.data, this);
});
}
this._super.apply(this,arguments);
},
/**
* Called after the template is fully loaded to handle any onload handlers
*/
load: function() {
if(typeof this.options.onload == 'function')
{
// Make sure function gets a reference to the widget
var args = Array.prototype.slice.call(arguments);
if(args.indexOf(this) == -1) args.push(this);
return this.options.onload.apply(this, args);
}
},
/**
* Override to return the promise for deferred loading
*/
doLoadingFinished: function() {
// Apply parent now, which actually puts into the DOM
this._super.apply(this, arguments);
// Fire load event when done loading
this.loading.done(jQuery.proxy(function() {jQuery(this).trigger("load");},this.div));
// Not done yet, but widget will let you know
return this.loading.promise();
}
});}).call(this);
et2_register_widget(et2_template, ["template"]);