Author: nbelaevski
Date: 2007-04-26 16:09:27 -0400 (Thu, 26 Apr 2007)
New Revision: 580
Added:
trunk/richfaces/tree/src/main/config/component/commonTreeClientListeners.ent
Modified:
trunk/richfaces-samples/tree-demo/src/main/webapp/pages/index.jsp
trunk/richfaces/tree/src/main/config/component/tree.xml
trunk/richfaces/tree/src/main/config/component/treeNode.xml
trunk/richfaces/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree-item.js
trunk/richfaces/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree-selection.js
trunk/richfaces/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree.js
trunk/richfaces/tree/src/main/templates/htmlTree.jspx
trunk/richfaces/tree/src/main/templates/htmlTreeNode.jspx
Log:
http://jira.jboss.com/jira/browse/RF-102 fixed
Selection prevention implemented for onselected event handlers that returned false
onselected, onexpand, oncollapse events handling added to treeNode
Test case updated
Added: trunk/richfaces/tree/src/main/config/component/commonTreeClientListeners.ent
===================================================================
--- trunk/richfaces/tree/src/main/config/component/commonTreeClientListeners.ent
(rev 0)
+++
trunk/richfaces/tree/src/main/config/component/commonTreeClientListeners.ent 2007-04-26
20:09:27 UTC (rev 580)
@@ -0,0 +1,15 @@
+ <property>
+ <name>onselected</name>
+ <classname>java.lang.String</classname>
+ <description>HTML: script expression to invoke on node
selection</description>
+ </property>
+ <property>
+ <name>onexpand</name>
+ <classname>java.lang.String</classname>
+ <description>HTML: script expression to invoke on node
expansion</description>
+ </property>
+ <property>
+ <name>oncollapse</name>
+ <classname>java.lang.String</classname>
+ <description>HTML: script expression to invoke on node
collapsion</description>
+ </property>
Modified: trunk/richfaces/tree/src/main/config/component/tree.xml
===================================================================
--- trunk/richfaces/tree/src/main/config/component/tree.xml 2007-04-26 20:04:02 UTC (rev
579)
+++ trunk/richfaces/tree/src/main/config/component/tree.xml 2007-04-26 20:09:27 UTC (rev
580)
@@ -3,6 +3,7 @@
[
<!ENTITY attributes SYSTEM "commonTreeAttributes.ent">
<!ENTITY listeners SYSTEM "commonTreeListeners.ent">
+<!ENTITY commonTreeClientListeners SYSTEM
"commonTreeClientListeners.ent">
]
@@ -109,22 +110,8 @@
<classname>java.lang.String</classname>
<description>Attribute contains a name providing an access to data defined with
value.</description>
</property>
+ &commonTreeClientListeners;
<property>
- <name>onselected</name>
- <classname>java.lang.String</classname>
- <description>An action to be fired when selecting a node</description>
- </property>
- <property>
- <name>onexpand</name>
- <classname>java.lang.String</classname>
- <description>An action to be fired when expanding a node</description>
- </property>
- <property>
- <name>oncollapse</name>
- <classname>java.lang.String</classname>
- <description>An action to be fired when collapsing a node</description>
- </property>
- <property>
<name>showConnectingLines</name>
<classname>boolean</classname>
<description>If true, connecting lines are show</description>
Modified: trunk/richfaces/tree/src/main/config/component/treeNode.xml
===================================================================
--- trunk/richfaces/tree/src/main/config/component/treeNode.xml 2007-04-26 20:04:02 UTC
(rev 579)
+++ trunk/richfaces/tree/src/main/config/component/treeNode.xml 2007-04-26 20:09:27 UTC
(rev 580)
@@ -3,6 +3,7 @@
[
<!ENTITY attributes SYSTEM "commonTreeAttributes.ent">
<!ENTITY listeners SYSTEM "commonTreeListeners.ent">
+<!ENTITY commonTreeClientListeners SYSTEM
"commonTreeClientListeners.ent">
]
@@ -97,6 +98,8 @@
<classname>java.lang.String</classname>
<description>An icon for component leaves.</description>
</property>
+ &commonTreeClientListeners;
+
<property hidden="true">
<name>dragValue</name>
</property>
Modified:
trunk/richfaces/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree-item.js
===================================================================
---
trunk/richfaces/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree-item.js 2007-04-26
20:04:02 UTC (rev 579)
+++
trunk/richfaces/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree-item.js 2007-04-26
20:09:27 UTC (rev 580)
@@ -79,6 +79,22 @@
this.tree.addItem(child);
},
+ fireExpansionEvent: function() {
+ var props = new Object();
+ props[Richfaces.TreeExpandEvent] = true;
+ props["expandedNode"] = this.id;
+ props["treeItem"] = this;
+ Richfaces.createEvent("click", this.tree.element, null, props).fire();
+ },
+
+ fireCollapsionEvent: function() {
+ var props = new Object();
+ props[Richfaces.TreeCollapseEvent] = true;
+ props["collapsedNode"] = this.id;
+ props["treeItem"] = this;
+ Richfaces.createEvent("click", this.tree.element, null, props).fire();
+ },
+
toggleCollapsion: function() {
if (this.hasChilds()) Element.toggle(this.elements.row);
@@ -96,10 +112,8 @@
Element.removeClassName(this.elements.icon, Tree.CLASS_ITEM_EXPANDED);
Element.addClassName(this.elements.icon, Tree.CLASS_ITEM_COLLAPSED);
}
- var props = new Object();
- props[Richfaces.TreeCollapseEvent] = true;
- props["collapsedNode"] = this.id;
- Richfaces.createEvent("click", this.tree.element, null, props).fire();
+
+ this.fireCollapsionEvent();
} else {
this.elements.handleImgExpanded.style.display="";
this.elements.handleImgCollapsed.style.display="none";
@@ -107,14 +121,16 @@
Element.removeClassName(this.elements.icon, Tree.CLASS_ITEM_COLLAPSED);
Element.addClassName(this.elements.icon, Tree.CLASS_ITEM_EXPANDED);
}
- var props = new Object();
- props[Richfaces.TreeExpandEvent] = true;
- props["expandedNode"] = this.id;
- Richfaces.createEvent("click", this.tree.element, null, props).fire();
+
+ this.fireExpansionEvent();
}
},
+ getRichAttribute: function(name) {
+ return Richfaces.getNSAttribute(name, this.elements.icon);
+ },
+
collapse: function() {
if (!this.isCollapsed() && this.switchType!="client") {
this.elements.handle.onclick();
@@ -128,10 +144,8 @@
Element.addClassName(this.elements.icon, Tree.CLASS_ITEM_COLLAPSED);
}
}
- var props = new Object();
- props[Richfaces.TreeCollapseEvent] = true;
- props["collapsedNode"] = this.id;
- Richfaces.createEvent("click", this.tree.element, null, props).fire();
+
+ this.fireCollapsionEvent();
},
expand: function() {
@@ -147,10 +161,8 @@
Element.addClassName(this.elements.icon, Tree.CLASS_ITEM_EXPANDED);
}
}
- var props = new Object();
- props[Richfaces.TreeExpandEvent] = true;
- props["expandedNode"] = this.id;
- Richfaces.createEvent("click", this.tree.element, null, props).fire();
+
+ this.fireExpansionEvent();
},
isCollapsed: function() {
@@ -194,31 +206,7 @@
},
toggleSelection: function(e) {
- this.tree.deselectAll();
-
- /*
- var attr = this.elements.text.attributes;
- var s = "";
- for (var i = 0; i < attr.length; i++) {
- s += attr[i].nodeName + ": " + attr[i].nodeValue + "; ";
- }
-
- alert(s);
- */
-
- var sClass = Richfaces.getNSAttribute("selectedclass", this.elements.text);
- if (sClass) {
-
- var classNames = sClass.split(' ')
- for (var i = 0; i < classNames.length; i++) {
- Element.addClassName(this.elements.text, classNames[i]);
- }
- this.tree.input.value = this.id;
- this.tree.selectionManager.activeItem = this;
-
- if (this.tree.options.onSelection) this.tree.options.onSelection(this.id);
- this.tree.showNode(this.elements.text.parentNode);
-
+ if (e && !e[Richfaces.TreeSelectEvent] &&
!Richfaces.eventIsSynthetic(e)) {
if (e && e.type == "mousedown" /* can be keydown */) {
if(Event.isLeftClick(e)) {
var src = Event.element(e);
@@ -230,24 +218,60 @@
src.tagName=='TEXTAREA')) return;
Event.stop(e);
+ } else {
+ //do not process non-left clicks
+ return ;
+ }
+ }
+
+ var props = new Object();
+ props[Richfaces.TreeSelectEvent] = true;
+ props["originatingEventType"] = e.type;
+ props["treeItem"] = this;
+ props["selectedNode"] = this.id;
+ var evt = Richfaces.createEvent("click", this.tree.element, null, props);
+ evt.fire();
+
+ return !evt.event["cancelSelection"];
+ } else {
+ this.tree.deselectAll();
+ /*
+ var attr = this.elements.text.attributes;
+ var s = "";
+ for (var i = 0; i < attr.length; i++) {
+ s += attr[i].nodeName + ": " + attr[i].nodeValue + "; ";
+ }
+
+ alert(s);
+ */
+
+ var sClass = Richfaces.getNSAttribute("selectedclass", this.elements.text);
+ if (sClass) {
+
+ var classNames = sClass.split(' ')
+ for (var i = 0; i < classNames.length; i++) {
+ Element.addClassName(this.elements.text, classNames[i]);
+ }
+ this.tree.input.value = this.id;
+ this.tree.selectionManager.activeItem = this;
+
+ if (this.tree.options.onSelection) this.tree.options.onSelection(this.id);
+ this.tree.showNode(this.elements.text.parentNode);
+
+ if (e && e["originatingEventType"] == "mousedown" /* can
be keydown */) {
Event.observe(this.elements.icon, "mousemove", this.listenDragBound);
Event.observe(this.elements.text, "mousemove", this.listenDragBound);
-
+
Event.observe(this.elements.icon, "mouseup", this.stopListenDragBound);
Event.observe(this.elements.text, "mouseup", this.stopListenDragBound);
}
}
+
+ return true;
}
},
- fireSelectEvent: function() {
- var props = new Object();
- props[Richfaces.TreeSelectEvent] = true;
- props["selectedNode"] = this.id;
- Richfaces.createEvent("click", this.tree.element, null, props).fire();
- },
-
isSelected: function() {
return Element.hasClassName(this.elements.text, Tree.CLASS_ITEM_SELECTED);
},
@@ -293,10 +317,6 @@
},
stopListenDrag: function(e) {
- if (e) {
- this.fireSelectEvent();
- }
-
Event.stopObserving(this.elements.icon, "mousemove", this.listenDragBound);
Event.stopObserving(this.elements.text, "mousemove", this.listenDragBound);
Modified:
trunk/richfaces/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree-selection.js
===================================================================
---
trunk/richfaces/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree-selection.js 2007-04-26
20:04:02 UTC (rev 579)
+++
trunk/richfaces/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree-selection.js 2007-04-26
20:09:27 UTC (rev 580)
@@ -86,8 +86,23 @@
case Event.KEY_UP:
if (this.inFocus) {
if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
- this.activeItem = this.getPreviousItemForSelection();
- this.activeItem.toggleSelection(event);
+
+ var item = this.activeItem;
+ do {
+ var newItem = this.getPreviousItemForSelection(item);
+
+ if (newItem && newItem != item) {
+ item = newItem;
+
+ if (item.toggleSelection(event)) {
+ this.activeItem = item;
+ item = null;
+ }
+ } else {
+ item = null;
+ }
+ } while (item);
+
}
noDefault = true;
}
@@ -95,8 +110,24 @@
case Event.KEY_DOWN:
if (this.inFocus) {
if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
- this.activeItem = this.getNextItemForSelection();
- this.activeItem.toggleSelection(event);
+
+ var item = this.activeItem;
+ do {
+ var newItem = this.getNextItemForSelection(item);
+
+ if (newItem && newItem != item) {
+ item = newItem;
+
+ if (item.toggleSelection(event)) {
+ this.activeItem = item;
+ item = null;
+ }
+
+ } else {
+ item = null;
+ }
+ } while (item);
+
}
noDefault = true;
}
@@ -126,31 +157,31 @@
}
},
- getNextItemForSelection: function() {
- if (!this.activeItem.isCollapsed() && this.activeItem.hasChilds()) {
- return this.activeItem.childs.first();
+ getNextItemForSelection: function(item) {
+ if (!item.isCollapsed() && item.hasChilds()) {
+ return item.childs.first();
} else {
- var next = this.activeItem.next();
- if (next != this.activeItem) {
+ var next = item.next();
+ if (next != item) {
return next;
} else {
- var next = this.activeItem.parent.next();
- if (next != this.activeItem.parent) {
+ var next = item.parent.next();
+ if (next != item.parent) {
return next;
} else {
- return this.activeItem;
+ return item;
}
}
}
},
- getPreviousItemForSelection: function() {
- var prev = this.activeItem.previous();
- if (prev == this.activeItem) {
+ getPreviousItemForSelection: function(item) {
+ var prev = item.previous();
+ if (prev == item) {
if (prev.parent == this.tree) {
- prev = this.activeItem;
+ prev = item;
} else {
- prev = this.activeItem.parent;
+ prev = item.parent;
}
} else if (!prev.isCollapsed() && prev.hasChilds()) {
prev = prev.childs.last();
Modified:
trunk/richfaces/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree.js
===================================================================
---
trunk/richfaces/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree.js 2007-04-26
20:04:02 UTC (rev 579)
+++
trunk/richfaces/tree/src/main/resources/org/richfaces/renderkit/html/scripts/tree.js 2007-04-26
20:09:27 UTC (rev 580)
@@ -27,7 +27,7 @@
this.id = id;
this.switchType = switchType;
this.dragIndicatorId = dragIndicatorId;
- this.onselect = new Function('event', events.onselect);
+ this.onselect = new Function('event', (events.onselect ? events.onselect :
"") + "; return true;");
this.onexpand = new Function('event', events.onexpand);
this.oncollapse = new Function('event', events.oncollapse);
this.onAjaxSelect = onAjaxSelect;
@@ -49,19 +49,49 @@
Event.observe(this.element, "click", function(event) {
if (Richfaces.eventIsSynthetic(event)) {
+ var treeItem = event["treeItem"];
+
if (event[Richfaces.TreeSelectEvent]){
Event.stop(event);
- this.onselect(event);
+ var itemOnSelect = treeItem.getRichAttribute("onselected");
+ itemOnSelect = new Function('event', (itemOnSelect ? itemOnSelect :
"") + "; return true;");
+
+ var selectResult = itemOnSelect(event);
+ if (!selectResult) {
+ event["cancelSelection"] = true;
+ return ;
+ }
+
+ selectResult = this.onselect(event);
+ if (!selectResult) {
+ event["cancelSelection"] = true;
+ return ;
+ }
+
+ treeItem.toggleSelection(event);
+
var attr = Richfaces.getNSAttribute("ajaxselectedlistener",
$(event.selectedNode + Tree.ID_DEVIDER + Tree.ID_ICON));
if (attr) {
this.onAjaxSelect(event);
}
} else if (event[Richfaces.TreeExpandEvent]){
Event.stop(event);
+
+ var handler = treeItem.getRichAttribute("onexpand");
+ if (handler) {
+ new Function('event', handler).call(Event.element(event), event);
+ }
+
this.onexpand(event);
} else if (event[Richfaces.TreeCollapseEvent]){
Event.stop(event);
+
+ var handler = treeItem.getRichAttribute("oncollapse");
+ if (handler) {
+ new Function('event', handler).call(Event.element(event), event);
+ }
+
this.oncollapse(event);
}
}
Modified: trunk/richfaces/tree/src/main/templates/htmlTree.jspx
===================================================================
--- trunk/richfaces/tree/src/main/templates/htmlTree.jspx 2007-04-26 20:04:02 UTC (rev
579)
+++ trunk/richfaces/tree/src/main/templates/htmlTree.jspx 2007-04-26 20:09:27 UTC (rev
580)
@@ -16,6 +16,7 @@
<h:scripts>
new org.ajax4jsf.framework.resource.PrototypeScript(),
/org/ajax4jsf/framework/ajax/scripts/AJAX.js,
+ /org/richfaces/renderkit/html/scripts/utils.js,
/org/ajax4jsf/renderkit/html/scripts/form.js,
/org/richfaces/renderkit/html/scripts/events.js,
/org/richfaces/renderkit/html/scripts/tree.js,
Modified: trunk/richfaces/tree/src/main/templates/htmlTreeNode.jspx
===================================================================
--- trunk/richfaces/tree/src/main/templates/htmlTreeNode.jspx 2007-04-26 20:04:02 UTC (rev
579)
+++ trunk/richfaces/tree/src/main/templates/htmlTreeNode.jspx 2007-04-26 20:09:27 UTC (rev
580)
@@ -69,6 +69,9 @@
rich:draggableoptions="#{this:getDraggableScriptOptions(context,
component)}"
rich:dropzoneoptions="#{this:getDropzoneScriptOptions(context, component)}"
rich:oncontextmenu="#{component.attributes['oncontextmenu']}"
+ rich:onselected="#{component.attributes['onselected']}"
+ rich:onexpand="#{component.attributes['onexpand']}"
+ rich:oncollapse="#{component.attributes['oncollapse']}"
class="dr-tree-h-ic #{lineFirst}" id="#{clientId}:icon">
<jsp:scriptlet>
<![CDATA[
Modified: trunk/richfaces-samples/tree-demo/src/main/webapp/pages/index.jsp
===================================================================
--- trunk/richfaces-samples/tree-demo/src/main/webapp/pages/index.jsp 2007-04-26 20:04:02
UTC (rev 579)
+++ trunk/richfaces-samples/tree-demo/src/main/webapp/pages/index.jsp 2007-04-26 20:09:27
UTC (rev 580)
@@ -59,7 +59,7 @@
nodeFace="#{data.name != 'param-value' ? 'input' :
'text'}"
changeExpandListener="#{bean.onExpand}"
nodeSelectListener="#{bean.onSelect}" binding="#{bean.tree}"
- onselected="window.status='selectedNode: '+event.selectedNode"
+ onselected="window.status='selectedNode: '+event.selectedNode;"
onexpand="window.status='expandedNode: '+event.expandedNode"
oncollapse="window.status='collapsedNode: '+event.collapsedNode"
ajaxSubmitSelection="true" reRender="outputText,
selectOneListbox"
@@ -79,7 +79,7 @@
<dnd:dndParam name="treeParam" value="Tree Parameter" />
<dnd:dndParam name="accept" value="accept" />
- <rich:treeNode type="input"
dropListener="#{bean.processDrop}">
+ <rich:treeNode type="input"
dropListener="#{bean.processDrop}"
oncollapse="alert('collapse')"
onexpand="alert('expand')">
<h:outputText value="#{data} : " />
<h:inputText value="#{data.name}" required="true"
styleClass="inputs">
</h:inputText>
@@ -87,7 +87,7 @@
<dnd:dndParam name="nodeParam" value="Node Parameter" />
</rich:treeNode>
- <rich:treeNode type="text" nodeClass="customNode"
acceptedTypes="file2">
+ <rich:treeNode type="text" nodeClass="customNode"
acceptedTypes="file2" onselected="return false;">
<h:outputText value="#{data}" />
</rich:treeNode>
</rich:tree>