summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorTeemu Suo-Anttila <tsuoanttila@users.noreply.github.com>2017-03-23 15:28:37 +0200
committerHenri Sara <henri.sara@gmail.com>2017-03-23 15:28:37 +0200
commit6384bc7dee5ccbaaafbbf569b758b3e6fd8a2c8b (patch)
tree419be55a19b6c4ef65876392b6e31091e1ff5c28 /client
parent17b3f23b0e526250dc134df1f7d2e6cd7f149ba5 (diff)
downloadvaadin-framework-6384bc7dee5ccbaaafbbf569b758b3e6fd8a2c8b.tar.gz
vaadin-framework-6384bc7dee5ccbaaafbbf569b758b3e6fd8a2c8b.zip
Add feature to disable collapsing items in TreeGrid (#8879)
Fixes #8846
Diffstat (limited to 'client')
-rw-r--r--client/src/main/java/com/vaadin/client/connectors/treegrid/TreeGridConnector.java41
-rw-r--r--client/src/main/java/com/vaadin/client/renderers/HierarchyRenderer.java133
2 files changed, 118 insertions, 56 deletions
diff --git a/client/src/main/java/com/vaadin/client/connectors/treegrid/TreeGridConnector.java b/client/src/main/java/com/vaadin/client/connectors/treegrid/TreeGridConnector.java
index e96bdffc06..32b5a63840 100644
--- a/client/src/main/java/com/vaadin/client/connectors/treegrid/TreeGridConnector.java
+++ b/client/src/main/java/com/vaadin/client/connectors/treegrid/TreeGridConnector.java
@@ -23,10 +23,8 @@ import com.google.gwt.dom.client.BrowserEvents;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.Event;
-import com.google.web.bindery.event.shared.HandlerRegistration;
import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.connectors.grid.GridConnector;
-import com.vaadin.client.renderers.ClickableRenderer;
import com.vaadin.client.renderers.HierarchyRenderer;
import com.vaadin.client.widget.grid.EventCellReference;
import com.vaadin.client.widget.grid.GridEventHandler;
@@ -54,9 +52,6 @@ public class TreeGridConnector extends GridConnector {
private HierarchyRenderer hierarchyRenderer;
- // Expander click event handling
- private HandlerRegistration expanderClickHandlerRegistration;
-
@Override
public TreeGrid getWidget() {
return (TreeGrid) super.getWidget();
@@ -121,7 +116,7 @@ public class TreeGridConnector extends GridConnector {
private HierarchyRenderer getHierarchyRenderer() {
if (hierarchyRenderer == null) {
- hierarchyRenderer = new HierarchyRenderer();
+ hierarchyRenderer = new HierarchyRenderer(this::setCollapsed);
}
return hierarchyRenderer;
}
@@ -130,20 +125,6 @@ public class TreeGridConnector extends GridConnector {
protected void init() {
super.init();
- expanderClickHandlerRegistration = getHierarchyRenderer()
- .addClickHandler(
- new ClickableRenderer.RendererClickHandler<JsonObject>() {
- @Override
- public void onClick(
- ClickableRenderer.RendererClickEvent<JsonObject> event) {
- toggleCollapse(getRowKey(event.getRow()),
- event.getCell().getRowIndex(),
- !isCollapsed(event.getRow()));
- event.stopPropagation();
- event.preventDefault();
- }
- });
-
// Swap Grid's CellFocusEventHandler to this custom one
// The handler is identical to the original one except for the child
// widget check
@@ -158,13 +139,6 @@ public class TreeGridConnector extends GridConnector {
new TreeGridClickEvent(getWidget(), getEventCell(getWidget())));
}
- @Override
- public void onUnregister() {
- super.onUnregister();
-
- expanderClickHandlerRegistration.removeHandler();
- }
-
private native void replaceCellFocusEventHandler(Grid<?> grid,
GridEventHandler<?> eventHandler)
/*-{
@@ -188,9 +162,10 @@ public class TreeGridConnector extends GridConnector {
return cell.getColumn().getRenderer() instanceof HierarchyRenderer;
}
- private void toggleCollapse(String rowKey, int rowIndex, boolean collapse) {
+ private void setCollapsed(int rowIndex, boolean collapsed) {
+ String rowKey = getRowKey(getDataSource().getRow(rowIndex));
getRpcProxy(NodeCollapseRpc.class).setNodeCollapsed(rowKey, rowIndex,
- collapse);
+ collapsed);
}
/**
@@ -273,15 +248,15 @@ public class TreeGridConnector extends GridConnector {
switch (domEvent.getKeyCode()) {
case KeyCodes.KEY_RIGHT:
if (!leaf && collapsed) {
- toggleCollapse(getRowKey(rowData),
- event.getCell().getRowIndex(), true);
+ setCollapsed(event.getCell().getRowIndex(),
+ !collapsed);
}
break;
case KeyCodes.KEY_LEFT:
if (!collapsed) {
// collapse node
- toggleCollapse(getRowKey(rowData),
- event.getCell().getRowIndex(), false);
+ setCollapsed(event.getCell().getRowIndex(),
+ !collapsed);
}
break;
}
diff --git a/client/src/main/java/com/vaadin/client/renderers/HierarchyRenderer.java b/client/src/main/java/com/vaadin/client/renderers/HierarchyRenderer.java
index 205f7929e4..206491f75b 100644
--- a/client/src/main/java/com/vaadin/client/renderers/HierarchyRenderer.java
+++ b/client/src/main/java/com/vaadin/client/renderers/HierarchyRenderer.java
@@ -15,6 +15,8 @@
*/
package com.vaadin.client.renderers;
+import java.util.function.BiConsumer;
+
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
@@ -35,21 +37,55 @@ import elemental.json.JsonObject;
/**
* A renderer for displaying hierarchical columns in TreeGrid.
- *
+ *
* @author Vaadin Ltd
* @since 8.1
*/
public class HierarchyRenderer extends ClickableRenderer<Object, Widget> {
-
+
private static final String CLASS_TREE_GRID_NODE = "v-tree-grid-node";
private static final String CLASS_TREE_GRID_EXPANDER = "v-tree-grid-expander";
private static final String CLASS_TREE_GRID_CELL_CONTENT = "v-tree-grid-cell-content";
private static final String CLASS_COLLAPSED = "collapsed";
+ private static final String CLASS_COLLAPSE_DISABLED = "collapse-disabled";
private static final String CLASS_EXPANDED = "expanded";
private static final String CLASS_DEPTH = "depth-";
private Renderer innerRenderer;
+ /**
+ * Constructs a HierarchyRenderer with given collapse callback. Callback is
+ * called when user clicks on the expander of a row. Callback is given the
+ * row index and the target collapsed state.
+ *
+ * @param collapseCallback
+ * the callback for collapsing nodes with row index
+ */
+ public HierarchyRenderer(BiConsumer<Integer, Boolean> collapseCallback) {
+ addClickHandler(event -> {
+ try {
+ JsonObject row = (JsonObject) event.getRow();
+ // Row needs to have hierarchy description
+ if (!hasHierarchyData(row)) {
+ return;
+ }
+
+ JsonObject hierarchyData = getHierarchyData(row);
+ if ((!isCollapsed(hierarchyData)
+ && !isCollapseAllowed(hierarchyData))
+ || isLeaf(hierarchyData)) {
+ return;
+ }
+
+ collapseCallback.accept(event.getCell().getRowIndex(),
+ !isCollapsed(hierarchyData));
+ } finally {
+ event.stopPropagation();
+ event.preventDefault();
+ }
+ });
+ }
+
@Override
public Widget createWidget() {
return new HierarchyItem(CLASS_TREE_GRID_NODE);
@@ -63,18 +99,15 @@ public class HierarchyRenderer extends ClickableRenderer<Object, Widget> {
int depth = 0;
boolean leaf = false;
boolean collapsed = false;
- if (row.hasKey(
- TreeGridCommunicationConstants.ROW_HIERARCHY_DESCRIPTION)) {
- JsonObject rowDescription = row.getObject(
- TreeGridCommunicationConstants.ROW_HIERARCHY_DESCRIPTION);
-
- depth = (int) rowDescription
- .getNumber(TreeGridCommunicationConstants.ROW_DEPTH);
- leaf = rowDescription
- .getBoolean(TreeGridCommunicationConstants.ROW_LEAF);
+ boolean collapseAllowed = true;
+ if (hasHierarchyData(row)) {
+ JsonObject rowDescription = getHierarchyData(row);
+
+ depth = getDepth(rowDescription);
+ leaf = isLeaf(rowDescription);
if (!leaf) {
- collapsed = rowDescription.getBoolean(
- TreeGridCommunicationConstants.ROW_COLLAPSED);
+ collapsed = isCollapsed(rowDescription);
+ collapseAllowed = isCollapseAllowed(rowDescription);
}
}
@@ -89,22 +122,64 @@ public class HierarchyRenderer extends ClickableRenderer<Object, Widget> {
cellWidget.setExpanderState(ExpanderState.EXPANDED);
}
- // Render the contents of the inner renderer. For non widget renderers
- // the cell reference needs to be wrapped so that its getElement method
+ cellWidget.setCollapseAllowed(collapseAllowed);
+
+ // Render the contents of the inner renderer. For non widget
+ // renderers
+ // the cell reference needs to be wrapped so that its getElement
+ // method
// returns the correct element we want to render.
if (innerRenderer instanceof WidgetRenderer) {
- ((WidgetRenderer) innerRenderer).render(cell, data, ((HierarchyItem) widget).content);
+ ((WidgetRenderer) innerRenderer).render(cell, data,
+ ((HierarchyItem) widget).content);
} else {
- innerRenderer.render(new HierarchyRendererCellReferenceWrapper(cell,
- ((HierarchyItem) widget).content.getElement()), data);
+ innerRenderer.render(
+ new HierarchyRendererCellReferenceWrapper(cell,
+ ((HierarchyItem) widget).content.getElement()),
+ data);
}
}
+ private int getDepth(JsonObject rowDescription) {
+ return (int) rowDescription
+ .getNumber(TreeGridCommunicationConstants.ROW_DEPTH);
+ }
+
+ private JsonObject getHierarchyData(JsonObject row) {
+ return row.getObject(
+ TreeGridCommunicationConstants.ROW_HIERARCHY_DESCRIPTION);
+ }
+
+ private boolean hasHierarchyData(JsonObject row) {
+ return row.hasKey(
+ TreeGridCommunicationConstants.ROW_HIERARCHY_DESCRIPTION);
+ }
+
+ private boolean isLeaf(JsonObject rowDescription) {
+ boolean leaf;
+ leaf = rowDescription
+ .getBoolean(TreeGridCommunicationConstants.ROW_LEAF);
+ return leaf;
+ }
+
+ private boolean isCollapseAllowed(JsonObject row) {
+ return row.getBoolean(
+ TreeGridCommunicationConstants.ROW_COLLAPSE_ALLOWED);
+ }
+
+ private boolean isCollapsed(JsonObject rowDescription) {
+ boolean collapsed;
+ collapsed = rowDescription
+ .getBoolean(TreeGridCommunicationConstants.ROW_COLLAPSED);
+ return collapsed;
+ }
+
/**
- * Sets the renderer to be wrapped. This is the original renderer before hierarchy is applied.
+ * Sets the renderer to be wrapped. This is the original renderer before
+ * hierarchy is applied.
*
* @param innerRenderer
- * Renderer to be wrapped.
+ * Renderer to be wrapped.
*/
public void setInnerRenderer(Renderer innerRenderer) {
this.innerRenderer = innerRenderer;
@@ -166,11 +241,13 @@ public class HierarchyRenderer extends ClickableRenderer<Object, Widget> {
}
private void setDepth(int depth) {
- String classNameToBeReplaced = getFullClassName(CLASS_DEPTH, panel.getElement().getClassName());
+ String classNameToBeReplaced = getFullClassName(CLASS_DEPTH,
+ panel.getElement().getClassName());
if (classNameToBeReplaced == null) {
panel.getElement().addClassName(CLASS_DEPTH + depth);
} else {
- panel.getElement().replaceClassName(classNameToBeReplaced, CLASS_DEPTH + depth);
+ panel.getElement().replaceClassName(classNameToBeReplaced,
+ CLASS_DEPTH + depth);
}
}
@@ -178,7 +255,8 @@ public class HierarchyRenderer extends ClickableRenderer<Object, Widget> {
int start = classNameList.indexOf(prefix);
int end = start + prefix.length();
if (start > -1) {
- while (end < classNameList.length() && classNameList.charAt(end) != ' ') {
+ while (end < classNameList.length()
+ && classNameList.charAt(end) != ' ') {
end++;
}
return classNameList.substring(start, end);
@@ -203,6 +281,15 @@ public class HierarchyRenderer extends ClickableRenderer<Object, Widget> {
}
}
+ private void setCollapseAllowed(boolean collapseAllowed) {
+ if (expander.getElement().hasClassName(CLASS_EXPANDED)
+ && !collapseAllowed) {
+ expander.getElement().addClassName(CLASS_COLLAPSE_DISABLED);
+ } else {
+ expander.getElement().removeClassName(CLASS_COLLAPSE_DISABLED);
+ }
+ }
+
private class Expander extends Widget implements HasClickHandlers {
private Expander() {