You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2012/11/19 17:54:13 UTC
[6/9] git commit: Rewrite Tree: basic node expansion
Rewrite Tree: basic node expansion
Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/23a69ca7
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/23a69ca7
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/23a69ca7
Branch: refs/heads/5.4-js-rewrite
Commit: 23a69ca7b052669dd4f3c3fcb1fba14079679ad6
Parents: fa70aae
Author: Howard M. Lewis Ship <hl...@apache.org>
Authored: Sun Nov 18 00:09:58 2012 +0000
Committer: Howard M. Lewis Ship <hl...@apache.org>
Committed: Sun Nov 18 00:09:58 2012 +0000
----------------------------------------------------------------------
.../coffeescript/META-INF/modules/core/tree.coffee | 72 +++++++++
.../apache/tapestry5/corelib/components/Tree.java | 118 +++++++++------
.../apache/tapestry5/corelib/components/Tree.tml | 16 +-
3 files changed, 150 insertions(+), 56 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/23a69ca7/tapestry-core/src/main/coffeescript/META-INF/modules/core/tree.coffee
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/coffeescript/META-INF/modules/core/tree.coffee b/tapestry-core/src/main/coffeescript/META-INF/modules/core/tree.coffee
new file mode 100644
index 0000000..9242165
--- /dev/null
+++ b/tapestry-core/src/main/coffeescript/META-INF/modules/core/tree.coffee
@@ -0,0 +1,72 @@
+# Copyright 2012 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http:#www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# ## core/tree
+#
+# Handlers to support to the core/Tree Tapestry component
+define ["core/dom", "core/ajax", "core/zone"],
+ (dom, ajax) ->
+
+ TREE = "[data-component-type=core/Tree]"
+ NODE_ID = "data-node-id"
+ SELECTOR = "#{TREE} [#{NODE_ID}]"
+
+ LOADING = "tree-children-loading"
+ LOADED = "tree-children-loaded"
+
+ loadChildren = (node) ->
+
+ # Ignore duplicate requests to load the children.
+
+ return if node.meta LOADING
+
+ container = node.findContainer TREE
+ url = container.attribute "data-tree-action-url"
+
+ node.meta LOADING, true
+
+ node.addClass "t-empty-node"
+ node.update "<span class='t-ajax-wait'/>"
+
+ ajax url,
+ parameters:
+ "t:action": "expand"
+ "t:nodeid": node.attribute NODE_ID
+ onsuccess: (reply) ->
+ node.update("").removeClass "t-empty-node"
+
+ label = node.findContainer("li").findFirst(".t-tree-label")
+
+ label.insertAfter reply.responseJSON.content
+
+ node.meta LOADING, false
+ node.meta LOADED, true
+
+ clickHandler = ->
+
+ # First case is dynamically loaded due to user action; second case
+ # is rendered with overall page due to server-side expansion model.
+ loaded = (this.meta LOADED) or (this.attribute "data-node-expanded")
+
+ if (not loaded) and (not this.hasClass "t-empty-node")
+ loadChildren this
+ return false
+
+ return false
+
+ dom.onDocument "click", SELECTOR, clickHandler
+
+
+ return null
+
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/23a69ca7/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Tree.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Tree.java b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Tree.java
index fd639f4..4fd8ee8 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Tree.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Tree.java
@@ -1,4 +1,4 @@
-// Copyright 2011 The Apache Software Foundation
+// Copyright 2011, 2012 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -38,15 +38,22 @@ import java.util.List;
* <p/>
* The Tree component uses special tricks to support recursive rendering of the Tree as necessary.
*
- * @since 5.3
* @tapestrydoc
+ * @since 5.3
*/
@SuppressWarnings(
{"rawtypes", "unchecked", "unused"})
@Events({EventConstants.NODE_SELECTED, EventConstants.NODE_UNSELECTED})
+@Import(module = "core/tree")
public class Tree
{
/**
+ * Name of query parameter that stores the node id of the node being operated on
+ * (expanded, collapsed, etc.).
+ */
+ private static final String NODE_ID = "t:nodeid";
+
+ /**
* The model that drives the tree, determining top level nodes and making revealing the overall structure of the
* tree.
*/
@@ -134,8 +141,10 @@ public class Tree
* This is a mix of immediate rendering, and queuing up various Blocks and Render commands
* to do the rest. May recursively render child nodes of the active node.
*
- * @param node to render
- * @param isLast if true, add "t-last" attribute to the LI element
+ * @param node
+ * to render
+ * @param isLast
+ * if true, add "t-last" attribute to the LI element
* @return command to render the node
*/
private RenderCommand toRenderCommand(final TreeNode node, final boolean isLast)
@@ -153,58 +162,31 @@ public class Tree
writer.element("li");
if (isLast)
+ {
writer.attributes("class", "t-last");
+ }
Element e = writer.element("span", "class", "t-tree-icon");
if (node.isLeaf())
+ {
e.addClassName("t-leaf-node");
- else if (!node.getHasChildren())
+ } else if (!node.getHasChildren())
+ {
e.addClassName("t-empty-node");
+ }
boolean hasChildren = !node.isLeaf() && node.getHasChildren();
boolean expanded = hasChildren && expansionModel.isExpanded(node);
- String clientId = jss.allocateClientId(resources);
-
- JSONObject spec = new JSONObject("clientId", clientId);
-
- e.attribute("id", clientId);
+ writer.attributes("data-node-id", node.getId());
- spec.put("leaf", node.isLeaf());
-
- if (hasChildren)
- {
- Link expandChildren = resources.createEventLink("expandChildren", node.getId());
- Link markExpanded = resources.createEventLink("markExpanded", node.getId());
- Link markCollapsed = resources.createEventLink("markCollapsed", node.getId());
-
- spec.put("expandChildrenURL", expandChildren.toString())
- .put("markExpandedURL", markExpanded.toString())
- .put("markCollapsedURL", markCollapsed.toString());
-
- if (expanded)
- spec.put("expanded", true);
- } else
+ if (expanded)
{
- if (selectionModel != null)
- {
- // May need to address this in the future; in other tree implementations I've constructed,
- // folders are selectable, and selections even propagate up and down the tree.
-
- Link selectLeaf = resources.createEventLink("select", node.getId());
-
- spec.put("selectURL", selectLeaf.toString());
- if (selectionModel.isSelected(node))
- {
- spec.put("selected", true);
- }
- }
+ writer.attributes("data-node-expanded", true);
}
- jss.addInitializerCall("treeNode", spec);
-
- writer.end(); // span.tx-tree-icon
+ writer.end(); // span.t-tree-icon
// From here on in, we're pushing things onto the queue. Remember that
// execution order is reversed from order commands are pushed.
@@ -212,7 +194,6 @@ public class Tree
queue.push(RENDER_CLOSE_TAG); // li
if (expanded)
-
{
queue.push(new RenderNodes(node.getChildren()));
}
@@ -222,9 +203,7 @@ public class Tree
queue.push(RENDER_LABEL_SPAN);
}
- }
-
- ;
+ };
}
/**
@@ -264,7 +243,43 @@ public class Tree
return className == null ? "t-tree-container" : "t-tree-container " + className;
}
- Object onExpandChildren(String nodeId)
+ public Link getTreeActionLink()
+ {
+ return resources.createEventLink("treeAction");
+ }
+
+ Object onTreeAction(@RequestParameter(NODE_ID) String nodeId,
+ @RequestParameter("t:action") String action)
+ {
+ if (action.equalsIgnoreCase("expand"))
+ {
+ return doExpandChildren(nodeId);
+ }
+
+ if (action.equalsIgnoreCase("markExpanded"))
+ {
+ return doMarkExpanded(nodeId);
+ }
+
+ if (action.equalsIgnoreCase("markCollapsed"))
+ {
+ return doMarkCollapsed(nodeId);
+ }
+
+ if (action.equalsIgnoreCase("selected"))
+ {
+ return doUpdateSelected(nodeId, true);
+ }
+
+ if (action.equalsIgnoreCase("deselect"))
+ {
+ return doUpdateSelected(nodeId, false);
+ }
+
+ throw new IllegalArgumentException(String.format("Unexpected action: '%s' for Tree component.", action));
+ }
+
+ Object doExpandChildren(String nodeId)
{
TreeNode container = model.getById(nodeId);
@@ -273,21 +288,22 @@ public class Tree
return new RenderNodes(container.getChildren());
}
- Object onMarkExpanded(String nodeId)
+ Object doMarkExpanded(@RequestParameter(NODE_ID) String nodeId)
{
expansionModel.markExpanded(model.getById(nodeId));
return new JSONObject();
}
- Object onMarkCollapsed(String nodeId)
+
+ Object doMarkCollapsed(@RequestParameter(NODE_ID) String nodeId)
{
expansionModel.markCollapsed(model.getById(nodeId));
return new JSONObject();
}
- Object onSelect(String nodeId, @RequestParameter("t:selected") boolean selected)
+ Object doUpdateSelected(String nodeId, boolean selected)
{
TreeNode node = model.getById(nodeId);
@@ -312,7 +328,9 @@ public class Tree
final Object result = callback.getResult();
if (result != null)
+ {
return result;
+ }
return new JSONObject();
}
@@ -320,7 +338,9 @@ public class Tree
public TreeExpansionModel getDefaultTreeExpansionModel()
{
if (defaultTreeExpansionModel == null)
+ {
defaultTreeExpansionModel = new DefaultTreeExpansionModel();
+ }
return defaultTreeExpansionModel;
}
http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/23a69ca7/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Tree.tml
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Tree.tml b/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Tree.tml
index e7cebc5..8be548a 100644
--- a/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Tree.tml
+++ b/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Tree.tml
@@ -1,11 +1,13 @@
-<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd" xmlns:p="tapestry:parameter">
+<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
- <div class="${containerClass}">
- <t:delegate to="renderRootNodes"/>
- </div>
+ <div class="${containerClass}"
+ data-component-type="core/Tree"
+ data-tree-action-url="${treeActionLink}">
+ <t:delegate to="renderRootNodes"/>
+ </div>
- <t:block id="defaultRenderTreeNodeLabel">
- ${node.label}
- </t:block>
+ <t:block id="defaultRenderTreeNodeLabel">
+ ${node.label}
+ </t:block>
</t:container>
\ No newline at end of file