fixed event handling in tree, added tree specific onSelect and onCheck events, implemented !multiple mode and fixed dhtmlxtree to not trigger onSelect if selection is change via set_value (according to their documentation)

This commit is contained in:
Ralf Becker 2013-02-08 13:23:58 +00:00
parent 6de7ab7faf
commit 763279562c
3 changed files with 68 additions and 31 deletions

View File

@ -31,14 +31,10 @@ class etemplate_widget_tree extends etemplate_widget
$this->attrs['type'] = $xml->localName; $this->attrs['type'] = $xml->localName;
parent::set_attrs($xml); parent::set_attrs($xml);
// set attrs[multiple] from attrs[options], unset options only if it just contains number or rows // set attrs[multiple] from attrs[options]
if ($this->attrs['options'] > 1) if ($this->attrs['options'] > 1)
{ {
$this->attrs['multiple'] = (int)$this->attrs['options']; $this->setElementAttribute($this->id, 'multiple', true);
if ((string)$this->attrs['multiple'] == $this->attrs['options'])
{
unset($this->attrs['options']);
}
} }
} }

View File

@ -1,11 +1,13 @@
/** /**
* eGroupWare eTemplate2 - JS Tree object * EGroupware eTemplate2 - JS Tree object
* *
* @link http://community.egroupware.org/egroupware/phpgwapi/js/dhtmlxtree/docsExplorer/dhtmlxtree/
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package etemplate * @package etemplate
* @subpackage api * @subpackage api
* @link http://www.egroupware.org * @link http://www.egroupware.org
* @author Nathan Gray * @author Nathan Gray
* @author Ralf Becker
* @copyright Nathan Gray 2011 * @copyright Nathan Gray 2011
* @version $Id$ * @version $Id$
*/ */
@ -15,7 +17,8 @@
/*egw:uses /*egw:uses
et2_core_inputWidget; et2_core_inputWidget;
/phpgwapi/js/dhtmlxtree/js/dhtmlXCommon.js; /phpgwapi/js/dhtmlxtree/js/dhtmlXCommon.js;
/phpgwapi/js/dhtmlxtree/js/dhtmlXTree.js; // using debugable and fixed source of dhtmltree instead: /phpgwapi/js/dhtmlxtree/js/dhtmlXTree.js;
/phpgwapi/js/dhtmlxtree/dhtmlxTree/sources/dhtmlxtree.js;
/phpgwapi/js/dhtmlxtree/dhtmlxTree/sources/ext/dhtmlxtree_json.js; /phpgwapi/js/dhtmlxtree/dhtmlxTree/sources/ext/dhtmlxtree_json.js;
// /phpgwapi/js/dhtmlxtree/dhtmlxTree/sources/ext/dhtmlxtree_start.js; // /phpgwapi/js/dhtmlxtree/dhtmlxTree/sources/ext/dhtmlxtree_start.js;
*/ */
@ -35,18 +38,25 @@ var et2_tree = et2_inputWidget.extend({
"default": {}, "default": {},
"description": "Used to set the tree options." "description": "Used to set the tree options."
}, },
"onnodeselect": { "onclick": {
"name": "onNodeSelect", "name": "onClick",
"type": "string",
"default": "",
"description": "JS code which gets executed when clicks on text of a node"
},
"onselect": {
"name": "onSelect",
"type": "string", "type": "string",
"default": "", "default": "",
"description": "Javascript executed when user selects a node" "description": "Javascript executed when user selects a node"
}, },
"oncheck": { "oncheck": {
"name": "onNodeSelect", "name": "onCheck",
"type": "string", "type": "string",
"default": "", "default": "",
"description": "Javascript executed when user checks a node" "description": "Javascript executed when user checks a node"
}, },
// onChange event is mapped depending on multiple to onCheck or onSelect
"image_path": { "image_path": {
"name": "Image directory", "name": "Image directory",
"type": "string", "type": "string",
@ -58,6 +68,7 @@ var et2_tree = et2_inputWidget.extend({
"default": {} "default": {}
} }
}, },
init: function() { init: function() {
this._super.apply(this, arguments); this._super.apply(this, arguments);
@ -121,16 +132,37 @@ var et2_tree = et2_inputWidget.extend({
} }
}, },
// overwrite default onclick to do nothing, as we install onclick via dhtmlxtree
onclick: function(_node) {},
createTree: function(widget) { createTree: function(widget) {
widget.input = new dhtmlXTreeObject({ widget.input = new dhtmlXTreeObject({
parent: widget.div[0], parent: widget.div[0],
width: '100%', width: '100%',
height: '100%', height: '100%',
image_path: widget.options.image_path, image_path: widget.options.image_path,
checkbox: true, checkbox: widget.options.multiple,
onCheck: widget.options.oncheck,
}); });
// 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;
});
}
}
}, },
set_select_options: function(options) { set_select_options: function(options) {
@ -200,27 +232,34 @@ var et2_tree = et2_inputWidget.extend({
}, },
set_value: function(new_value) { set_value: function(new_value) {
this.value = this._oldValue = (typeof new_value === 'string' ? new_value.split(',') : new_value); this.value = this._oldValue = (typeof new_value === 'string' && this.options.multiple ? new_value.split(',') : new_value);
if(this.input == null) return; if(this.input == null) return;
// Clear all checked if (this.options.multiple)
var checked = this.input.getAllChecked().split(this.input.dlmtr);
for(var i = 0; i < checked.length; i++)
{ {
this.input.setCheck(checked[i], false); // Clear all checked
} var checked = this.input.getAllChecked().split(this.input.dlmtr);
for(var i = 0; i < checked.length; i++)
{
this.input.setCheck(checked[i], false);
}
// Check selected // Check selected
for(var i = 0; i < this.value.length; i++) for(var i = 0; i < this.value.length; i++)
{
this.input.setCheck(this.value[i], true);
this.input.openItem(this.value[i]);
}
}
else
{ {
this.input.setCheck(this.value[i], true); this.input.selectItem(this.value, false); // false = do not trigger onSelect
this.input.openItem(this.value[i]);
} }
}, },
getValue: function() { getValue: function() {
if(this.input == null) return null; if(this.input == null) return null;
return this.input.getAllChecked().split(this.input.dlmtr); return this.options.multiple ? this.input.getAllChecked().split(this.input.dlmtr) : this.input.getSelectedItemId();
} }
}); });
et2_register_widget(et2_tree, ["tree","tree-cat"]); et2_register_widget(et2_tree, ["tree","tree-cat"]);

View File

@ -1227,16 +1227,18 @@ SELECTION
* @desc: visual select item in tree * @desc: visual select item in tree
* @type: private * @type: private
* @param: node - tree item object * @param: node - tree item object
* @param: mode - true suppress onSelect
* @edition: Professional * @edition: Professional
* @topic: 0 * @topic: 0
*/ */
dhtmlXTreeObject.prototype._selectItem=function(node,e){ dhtmlXTreeObject.prototype._selectItem=function(node,e,mode){
if (this.checkEvent("onSelect")) this._onSSCFold=this.getSelectedItemId(); if (typeof mode == 'undefined') mode=false;
if (!mode && this.checkEvent("onSelect")) this._onSSCFold=this.getSelectedItemId();
this._unselectItems(); this._unselectItems();
this._markItem(node); this._markItem(node);
if (this.checkEvent("onSelect")) { if (!mode && this.checkEvent("onSelect")) {
var z=this.getSelectedItemId(); var z=this.getSelectedItemId();
if (z!=this._onSSCFold) if (z!=this._onSSCFold)
this.callEvent("onSelect",[z]); this.callEvent("onSelect",[z]);
@ -1329,7 +1331,7 @@ SELECTION
var lastId=that.getSelectedItemId(); var lastId=that.getSelectedItemId();
if ((!e)||(!e.skipUnSel)) if ((!e)||(!e.skipUnSel))
that._selectItem(obj,e); that._selectItem(obj,e,mode);
if (!mode) { if (!mode) {
if (obj.actionHandler) obj.actionHandler(obj.id,lastId); if (obj.actionHandler) obj.actionHandler(obj.id,lastId);