diff options
author | Teemu Suo-Anttila <tsuoanttila@users.noreply.github.com> | 2017-03-23 15:28:37 +0200 |
---|---|---|
committer | Henri Sara <henri.sara@gmail.com> | 2017-03-23 15:28:37 +0200 |
commit | 6384bc7dee5ccbaaafbbf569b758b3e6fd8a2c8b (patch) | |
tree | 419be55a19b6c4ef65876392b6e31091e1ff5c28 /client | |
parent | 17b3f23b0e526250dc134df1f7d2e6cd7f149ba5 (diff) | |
download | vaadin-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.java | 41 | ||||
-rw-r--r-- | client/src/main/java/com/vaadin/client/renderers/HierarchyRenderer.java | 133 |
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() { |