forked from extern/egroupware
changed signature of on* event handlers: 1. event, 2. widget (context is DOM node), event handlers have now type "js" in attribute description and get automatic converted to a function, no more need to call et2_compileLegacyJS
This commit is contained in:
parent
71c2a554bd
commit
0163442f37
@ -17,10 +17,6 @@
|
||||
app.admin = AppJS.extend(
|
||||
{
|
||||
appname: 'admin',
|
||||
/**
|
||||
* et2 widget container
|
||||
*/
|
||||
et2: null,
|
||||
/**
|
||||
* reference to splitter
|
||||
*/
|
||||
@ -47,7 +43,6 @@ app.admin = AppJS.extend(
|
||||
*/
|
||||
destroy: function()
|
||||
{
|
||||
delete this.et2;
|
||||
// call parent
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
@ -64,8 +59,6 @@ app.admin = AppJS.extend(
|
||||
// call parent
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.et2 = _et2.widgetContainer;
|
||||
|
||||
var iframe = this.iframe = this.et2.getWidgetById('iframe');
|
||||
if (iframe)
|
||||
{
|
||||
|
@ -43,7 +43,7 @@
|
||||
</grid>
|
||||
</template>
|
||||
<template id="admin.index" template="" lang="" group="0" version="1.9.001">
|
||||
<tree autoloading="admin_ui::ajax_tree" id="tree" onclick="app.admin.run(widget.event_args[0],widget);" parent_node="admin_tree_target" std_images="orange-ball"/>
|
||||
<tree autoloading="admin_ui::ajax_tree" id="tree" onclick="app.admin.run" parent_node="admin_tree_target" std_images="orange-ball"/>
|
||||
<description id="msg" class="message"/>
|
||||
<split dock_side="topDock" id="splitter" orientation="h">
|
||||
<nextmatch id="nm" template="admin.index.rows"/>
|
||||
|
@ -42,7 +42,7 @@ var et2_baseWidget = et2_DOMWidget.extend(et2_IAligned,
|
||||
},
|
||||
"onclick": {
|
||||
"name": "onclick",
|
||||
"type": "string",
|
||||
"type": "js",
|
||||
"description": "JS code which is executed when the element is clicked."
|
||||
}
|
||||
},
|
||||
@ -233,19 +233,20 @@ var et2_baseWidget = et2_DOMWidget.extend(et2_IAligned,
|
||||
return this.getDOMNode(this);
|
||||
},
|
||||
|
||||
click: function(_node) {
|
||||
if (this.onclick)
|
||||
/**
|
||||
* Click handler calling custom handler set via onclick attribute to this.onclick
|
||||
*
|
||||
* @param _ev
|
||||
* @returns
|
||||
*/
|
||||
click: function(_ev) {
|
||||
if(typeof this.onclick == 'function')
|
||||
{
|
||||
if(typeof this.onclick == '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.onclick.apply(this, args);
|
||||
} else {
|
||||
return (et2_compileLegacyJS(this.options.onclick, this, _node))();
|
||||
}
|
||||
// Make sure function gets a reference to the widget, splice it in as 2. argument if not
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
if(args.indexOf(this) == -1) args.splice(1, 0, this);
|
||||
|
||||
return this.onclick.apply(this, args);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -84,8 +84,13 @@ function et2_form_name(_cname,_name)
|
||||
* Checks whether the given value is of the given type. Strings are converted
|
||||
* into the corresponding type. The (converted) value is returned. All supported
|
||||
* types are listed in the et2_validTypes array.
|
||||
*
|
||||
* @param mixed _val value
|
||||
* @param string _type a valid type eg. "string" or "js"
|
||||
* @param string _attr attribute name
|
||||
* @param object _widget
|
||||
*/
|
||||
function et2_checkType(_val, _type, _attr, _cname)
|
||||
function et2_checkType(_val, _type, _attr, _widget)
|
||||
{
|
||||
if (typeof _attr == "undefined")
|
||||
{
|
||||
@ -241,10 +246,15 @@ function et2_checkType(_val, _type, _attr, _cname)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof _val == "string")
|
||||
{
|
||||
return _val; // get compiled later in widgets own initAttributes, as widget is not yet initialised
|
||||
}
|
||||
}
|
||||
|
||||
// We should never come here
|
||||
throw("Invalid type identifier '" + _attr + ": " + _type + "' supplied by '" + _cname + "'");
|
||||
throw("Invalid type identifier '" + _attr + ": " + _type);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -403,7 +403,7 @@
|
||||
}
|
||||
|
||||
var val = et2_checkType(_value, this.attributes[_name].type,
|
||||
_name);
|
||||
_name, this);
|
||||
|
||||
if (typeof this["set_" + _name] == "function")
|
||||
{
|
||||
@ -438,7 +438,7 @@
|
||||
if (!this.attributes[key].ignore)
|
||||
{
|
||||
_attrs[key] = et2_checkType(_attrs[key], this.attributes[key].type,
|
||||
key);
|
||||
key, this);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -36,12 +36,12 @@ var et2_inputWidget = et2_valueWidget.extend([et2_IInput,et2_ISubmitListener],
|
||||
},
|
||||
"onchange": {
|
||||
"name": "onchange",
|
||||
"type": "string",
|
||||
"type": "js",
|
||||
"description": "JS code which is executed when the value changes."
|
||||
},
|
||||
"onfocus": {
|
||||
"name": "onfocus",
|
||||
"type": "string",
|
||||
"type": "js",
|
||||
"description": "JS code which get executed when wiget receives focus."
|
||||
},
|
||||
"validation_error": {
|
||||
@ -150,20 +150,13 @@ var et2_inputWidget = et2_valueWidget.extend([et2_IInput,et2_ISubmitListener],
|
||||
|
||||
focus: function(_node)
|
||||
{
|
||||
if (this.options.onfocus)
|
||||
if(typeof this.options.onfocus == 'function')
|
||||
{
|
||||
if(typeof this.options.onfocus == '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);
|
||||
// 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.onfocus.apply(this, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (et2_compileLegacyJS(this.options.onfocus, this, _node))();
|
||||
}
|
||||
return this.options.onfocus.apply(this, args);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -129,9 +129,9 @@
|
||||
// Code is app.appname.function, add the arguments so it can be executed
|
||||
if (typeof _code == 'string' && _code.indexOf('app') == 0 && _code.split('.').length >= 3 && _code.indexOf('(') == -1)
|
||||
{
|
||||
_code += '(egw,widget,window,document)';
|
||||
_code += '(ev,widget)';
|
||||
}
|
||||
var func = new Function('egw', 'widget', 'window', 'document', _code);
|
||||
var func = new Function('ev', 'widget', _code);
|
||||
} catch(e) {
|
||||
_widget.egw().debug('error', 'Error while compiling JS code ', _code);
|
||||
return (function() {return false;});
|
||||
@ -139,16 +139,12 @@
|
||||
|
||||
// Execute the code and return its results, pass the egw instance and
|
||||
// the widget
|
||||
return function() {
|
||||
// Get the egw reference
|
||||
var egw = _widget.egw();
|
||||
|
||||
return function(ev) {
|
||||
// Dump the executed code for debugging
|
||||
egw.debug('log', 'Executing legacy JS code: ', _code);
|
||||
|
||||
// Return the result of the called function
|
||||
return func.call(context, egw, _widget, egw.window,
|
||||
egw.window.document);
|
||||
return func.call(context, ev, _widget);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -752,6 +752,32 @@ var et2_widget = Class.extend(
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The initAttributes function sets the attributes to their default
|
||||
* values. The attributes are not overwritten, which means, that the
|
||||
* default is only set, if either a setter exists or this[propName] does
|
||||
* not exist yet.
|
||||
*
|
||||
* Overwritten here to compile legacy JS code in attributes of type "js"
|
||||
*/
|
||||
initAttributes: function(_attrs) {
|
||||
for (var key in _attrs)
|
||||
{
|
||||
if (typeof this.attributes[key] != "undefined" && !this.attributes[key].ignore && !(_attrs[key] == undefined))
|
||||
{
|
||||
var val = _attrs[key];
|
||||
// compile string values of attribute type "js" to functions
|
||||
if (this.attributes[key].type == 'js' && typeof _attrs[key] == 'string')
|
||||
{
|
||||
val = et2_compileLegacyJS(val, this,
|
||||
this.instanceOf(et2_inputWidget) ? this.getInputNode() :
|
||||
(this.implements(et2_IDOMNode) ? this.getDOMNode() : null));
|
||||
}
|
||||
this.setAttribute(key, val, false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
doLoadingFinished: function() {
|
||||
return true;
|
||||
|
@ -94,7 +94,7 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
|
||||
},
|
||||
"onselect": {
|
||||
"name": "onselect",
|
||||
"type": "string",
|
||||
"type": "js",
|
||||
"description": "JS code which gets executed when rows are selected. Can also be a app.appname.func(selected) style method"
|
||||
},
|
||||
"onfiledrop": {
|
||||
@ -485,26 +485,9 @@ var et2_nextmatch = et2_DOMWidget.extend([et2_IResizeable, et2_IInput],
|
||||
*/
|
||||
onselect: function(action,senders) {
|
||||
// Execute the JS code connected to the event handler
|
||||
if (this.options.onselect)
|
||||
if (typeof this.options.onselect == 'function')
|
||||
{
|
||||
if (typeof this.options.onselect == "string" &&
|
||||
this.options.onselect.substr(0,4) == "app." && window.app)
|
||||
{
|
||||
var parts = this.options.onselect.split(".");
|
||||
if(parts.length == 3 && typeof window.app[parts[1]] == "object" &&
|
||||
typeof window.app[parts[1]][parts[2]] == "function")
|
||||
{
|
||||
// Call as Action callback
|
||||
//window.app[parts[1]][parts[2]].apply( window.app[parts[1]], arguments);
|
||||
window.app[parts[1]][parts[2]].apply( window.app[parts[1]], [this,this.getSelection().ids]);
|
||||
}
|
||||
}
|
||||
|
||||
// Exectute the legacy JS code
|
||||
else if (!(et2_compileLegacyJS(this.options.onselect, this, this.div))())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this.options.onselect.call(this, this.getSelection().ids, this);
|
||||
}
|
||||
},
|
||||
|
||||
@ -1949,11 +1932,6 @@ var et2_nextmatch_header = et2_baseWidget.extend(et2_INextmatchHeader,
|
||||
"type": "string",
|
||||
"description": "Caption for the nextmatch header",
|
||||
"translate": true
|
||||
},
|
||||
"onchange": {
|
||||
"name": "onchange",
|
||||
"type": "string",
|
||||
"description": "JS code which is executed when the value changes."
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -43,7 +43,7 @@ var et2_button = et2_baseWidget.extend([et2_IInput, et2_IDetachedDOM],
|
||||
},
|
||||
"onclick": {
|
||||
"name": "onclick",
|
||||
"type": "string",
|
||||
"type": "js",
|
||||
"description": "JS code which gets executed when the button is clicked"
|
||||
},
|
||||
"accesskey": {
|
||||
@ -177,18 +177,19 @@ var et2_button = et2_baseWidget.extend([et2_IInput, et2_IDetachedDOM],
|
||||
return this.btn ? this.btn[0] : (this.image ? this.image[0] : null);
|
||||
},
|
||||
|
||||
onclick: function(_node) {
|
||||
/**
|
||||
* Overwritten to maintain an internal clicked attribute
|
||||
*
|
||||
* @param _ev
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
click: function(_ev) {
|
||||
this.clicked = true;
|
||||
|
||||
// Execute the JS code connected to the event handler
|
||||
if (this.options.onclick)
|
||||
if (!this._super.apply(this, arguments))
|
||||
{
|
||||
// Exectute the legacy JS code
|
||||
if (!(et2_compileLegacyJS(this.options.onclick, this, _node))())
|
||||
{
|
||||
this.clicked = false;
|
||||
return false;
|
||||
}
|
||||
this.clicked = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Submit the form
|
||||
@ -197,6 +198,7 @@ var et2_button = et2_baseWidget.extend([et2_IInput, et2_IDetachedDOM],
|
||||
this.getInstanceManager().submit(this); //TODO: this only needs to be passed if it's in a datagrid
|
||||
}
|
||||
this.clicked = false;
|
||||
return true;
|
||||
},
|
||||
|
||||
set_label: function(_value) {
|
||||
|
@ -60,7 +60,7 @@ var et2_dropdown_button = et2_inputWidget.extend(
|
||||
},
|
||||
"onclick": {
|
||||
"name": "onclick",
|
||||
"type": "string",
|
||||
"type": "js",
|
||||
"description": "JS code which gets executed when the button is clicked"
|
||||
},
|
||||
"select_options": {
|
||||
@ -272,21 +272,28 @@ var et2_dropdown_button = et2_inputWidget.extend(
|
||||
}
|
||||
},
|
||||
|
||||
onclick: function(_node) {
|
||||
/**
|
||||
* Overwritten to maintain an internal clicked attribute
|
||||
*
|
||||
* @param _ev
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
click: function(_ev) {
|
||||
this.clicked = true;
|
||||
|
||||
// Execute the JS code connected to the event handler
|
||||
if (this.options.onclick)
|
||||
if (!this._super.apply(this, arguments))
|
||||
{
|
||||
// Exectute the legacy JS code
|
||||
if (!(et2_compileLegacyJS(this.options.onclick, this, _node))())
|
||||
{
|
||||
this.clicked = false;
|
||||
return false;
|
||||
}
|
||||
this.clicked = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Submit the form
|
||||
if (this._type != "buttononly")
|
||||
{
|
||||
this.getInstanceManager().submit(this); //TODO: this only needs to be passed if it's in a datagrid
|
||||
}
|
||||
this.clicked = false;
|
||||
return true;
|
||||
},
|
||||
|
||||
onselect: function(event, selected_node) {
|
||||
|
@ -47,11 +47,6 @@ var et2_progress = et2_valueWidget.extend([et2_IDetachedDOM],
|
||||
"type": "string",
|
||||
"description": "The label is displayed as the title. The label can contain variables, as descript for name. If the label starts with a '@' it is replaced by the value of the content-array at this index (with the '@'-removed and after expanding the variables).",
|
||||
"translate": true
|
||||
},
|
||||
"onchange": {
|
||||
"name": "onchange",
|
||||
"type": "string",
|
||||
"description": "JS code which is executed when the value changes."
|
||||
}
|
||||
},
|
||||
legacyOptions: ["href", "extra_link_target", "imagemap", "extra_link_popup", "id"],
|
||||
|
@ -48,20 +48,17 @@ var et2_tree = et2_inputWidget.extend(
|
||||
},
|
||||
"onclick": {
|
||||
"name": "onClick",
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"type": "js",
|
||||
"description": "JS code which gets executed when clicks on text of a node"
|
||||
},
|
||||
"onselect": {
|
||||
"name": "onSelect",
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"type": "js",
|
||||
"description": "Javascript executed when user selects a node"
|
||||
},
|
||||
"oncheck": {
|
||||
"name": "onCheck",
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"type": "js",
|
||||
"description": "Javascript executed when user checks a node"
|
||||
},
|
||||
// onChange event is mapped depending on multiple to onCheck or onSelect
|
||||
@ -167,7 +164,7 @@ var et2_tree = et2_inputWidget.extend(
|
||||
},
|
||||
|
||||
// overwrite default onclick to do nothing, as we install onclick via dhtmlxtree
|
||||
onclick: function(_node) {},
|
||||
click: function(_node) {},
|
||||
|
||||
createTree: function(widget) {
|
||||
widget.input = new dhtmlXTreeObject({
|
||||
@ -184,26 +181,6 @@ var et2_tree = et2_inputWidget.extend(
|
||||
// Add in the callback so we can keep the two in sync
|
||||
widget.input.AJAX_callback = function() { widget._dhtmlxtree_json_callback(JSON.parse(this.response), widget.input.lastLoadedXMLId);};
|
||||
|
||||
// attach all event handlers (attributs starting with "on"), if they are set
|
||||
for(var name in widget.options)
|
||||
{
|
||||
if (name.substr(0,2) == 'on' && widget.options[name])
|
||||
{
|
||||
// automatic convert onChange event to oncheck or onSelect depending on multiple is used or not
|
||||
if (name == 'onchange') name = widget.options.multiple ? 'oncheck' : 'onselect';
|
||||
widget.input.attachEvent(widget.attributes[name].name, function(_args){
|
||||
var _widget = widget; // closure to pass in et2 widget (1. param of event handler)
|
||||
// use widget attributes to pass arguments and name of event to handler
|
||||
_widget.event_args = arguments;
|
||||
_widget.event_name = this.callEvent.arguments[0].substr(3);
|
||||
var _js = _widget.options[_widget.event_name] || _widget.options.onchange;
|
||||
(et2_compileLegacyJS(_js, _widget, this))();
|
||||
delete _widget.event_args;
|
||||
delete _widget.event_name;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
if (widget.options.autoloading)
|
||||
{
|
||||
var url = widget.options.autoloading;
|
||||
@ -217,6 +194,34 @@ var et2_tree = et2_inputWidget.extend(
|
||||
widget.input.setDataMode('JSON');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Install event handlers on tree
|
||||
*
|
||||
* @param _name
|
||||
* @param _handler
|
||||
*/
|
||||
_install_handler: function(_name, _handler)
|
||||
{
|
||||
if (typeof _handler == 'function')
|
||||
{
|
||||
if(this.input == null) this.createTree(this);
|
||||
// automatic convert onChange event to oncheck or onSelect depending on multiple is used or not
|
||||
if (_name == 'onchange') _name = this.options.multiple ? 'oncheck' : 'onselect';
|
||||
var handler = _handler;
|
||||
var widget = this;
|
||||
this.input.attachEvent(_name, function(_id){
|
||||
var args = jQuery.makeArray(arguments);
|
||||
// splice in widget as 2. parameter, 1. is new node-id, now 3. is old node id
|
||||
args.splice(1, 0, widget);
|
||||
handler.apply(this, args);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
set_onchange: function(_handler) { this._install_handler('onchange', _handler); },
|
||||
set_onclick: function(_handler) { this._install_handler('onclick', _handler); },
|
||||
set_onselect: function(_handler) { this._install_handler('onselect', _handler); },
|
||||
|
||||
set_select_options: function(options)
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ app.mail = AppJS.extend(
|
||||
/**
|
||||
* Initialize javascript for this application
|
||||
*
|
||||
* @memberOf app.mail
|
||||
* @memberOf mail
|
||||
*/
|
||||
init: function() {
|
||||
this._super.apply(this,arguments);
|
||||
@ -428,7 +428,7 @@ app.mail = AppJS.extend(
|
||||
* @param nextmatch et2_nextmatch The widget whose row was selected
|
||||
* @param selected Array Selected row IDs. May be empty if user unselected all rows.
|
||||
*/
|
||||
mail_preview: function(nextmatch, selected) {
|
||||
mail_preview: function(selected, nextmatch) {
|
||||
//console.log("mail_preview",nextmatch, selected);
|
||||
// Empty values, just in case selected is empty (user cleared selection)
|
||||
var dataElem = {data:{subject:"",fromaddress:"",toaddress:"",date:"",subject:""}};
|
||||
|
@ -38,7 +38,7 @@
|
||||
</grid>
|
||||
</template>
|
||||
<template id="mail.index" template="" lang="" group="0" version="1.9.001">
|
||||
<tree autoloading="mail.mail_ui.ajax_foldertree" id="nm[foldertree]" onclick="app.mail.mail_changeFolder(widget.event_args[0],widget);" parent_node="mail-tree_target"/>
|
||||
<tree autoloading="mail.mail_ui.ajax_foldertree" id="nm[foldertree]" onclick="app.mail.mail_changeFolder" parent_node="mail-tree_target"/>
|
||||
<html id="msg"/>
|
||||
<buttononly id="button[mailcreate]" onclick="app.mail.mail_compose(false);" label="Compose" parent_node="mail-index_buttonmailcreate"/>
|
||||
<buttononly id="button[testhtmlarea]" onclick="app.mail.mail_testhtmlarea(false);" label="Test HTML Area" parent_node="mail-index_buttontesthtmlarea"/>
|
||||
|
Loading…
Reference in New Issue
Block a user