From 1066d9897be1bdd2d52e46654a5fd7b246d54ab5 Mon Sep 17 00:00:00 2001 From: Pekka Hyvönen Date: Wed, 15 Nov 2017 09:56:27 +0200 Subject: Add new drop mode ON_GRID for GridDropTarget (#10296) * Add new drop mode ON_GRID for GridDropTarget Also adds a way to not accept drops on rows when the user has sorted the grid. This way the bad UX can be avoided for showing the drop indicator for the wrong place when the grid has been sorted. This has not been made default behavior to GridDropTarget since it would change behavior compared to 8.1. Instead if is triggerable via API in GridDropTarget. * Refactor sorted grid drop logic to server side * Block setDropMode calls Blocking setDropMode set values if the grid has been sorted and drop on sorted rows is not allowed. The value is used once the grid is not sorted anymore or the drops are allowed on sorted rows. --- .../connectors/grid/GridDropTargetConnector.java | 63 ++++++++++++++++------ 1 file changed, 47 insertions(+), 16 deletions(-) (limited to 'client/src') diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetConnector.java index 3d8164b63f..da27ba65ec 100644 --- a/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetConnector.java +++ b/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetConnector.java @@ -79,7 +79,8 @@ public class GridDropTargetConnector extends DropTargetExtensionConnector { private String styleDragBottom; /** - * Class name to apply when dragged over an empty grid. + * Class name to apply when dragged over an empty grid, or when dropping on + * rows is not possible (see {@link #isDroppingOnRowsPossible()}). */ private String styleDragEmpty; @@ -99,28 +100,47 @@ public class GridDropTargetConnector extends DropTargetExtensionConnector { super.extend(target); } + /** + * Inspects whether the current drop would happen on the whole grid instead + * of specific row as the drop target. This is based on used drop mode, + * whether dropping on sorted grid rows is allowed (determined on server + * side and automatically updated to drop mode) and whether the grid is + * empty. + * + * @return {@code true} when the drop target is the whole grid, or + * {@code false} when it is one of the rows + */ + protected boolean isDroppingOnRowsPossible() { + if (getState().dropMode == DropMode.ON_GRID) { + return false; + } + + if (getEscalator().getVisibleRowRange().isEmpty()) { + return false; + } + + return true; + } + @Override protected void sendDropEventToServer(List types, Map data, String dropEffect, NativeEvent dropEvent) { + Element targetElement = getTargetElement( + (Element) dropEvent.getEventTarget().cast()); + + DropLocation dropLocation = getDropLocation(targetElement, dropEvent); + MouseEventDetails mouseEventDetails = MouseEventDetailsBuilder + .buildMouseEventDetails(dropEvent, targetElement); String rowKey = null; - DropLocation dropLocation = null; - Element targetElement = getTargetElement( - (Element) dropEvent.getEventTarget().cast()); - // the target element is either the tablewrapper or one of the body rows + // the target is either on a row element or the table wrapper if (TableRowElement.is(targetElement)) { rowKey = getRowData(targetElement.cast()) .getString(GridState.JSONKEY_ROWKEY); - dropLocation = getDropLocation(targetElement, dropEvent); - } else { - dropLocation = DropLocation.EMPTY; } - MouseEventDetails mouseEventDetails = MouseEventDetailsBuilder - .buildMouseEventDetails(dropEvent, targetElement); - getRpcProxy(GridDropTargetRpc.class).drop(types, data, dropEffect, rowKey, dropLocation, mouseEventDetails); } @@ -145,8 +165,13 @@ public class GridDropTargetConnector extends DropTargetExtensionConnector { * drop target element * @param event * drop event + * @return the drop location to use */ protected DropLocation getDropLocation(Element target, NativeEvent event) { + if (!isDroppingOnRowsPossible()) { + return DropLocation.EMPTY; + } + if (TableRowElement.is(target)) { if (getState().dropMode == DropMode.BETWEEN) { if (getRelativeY(target, @@ -266,6 +291,10 @@ public class GridDropTargetConnector extends DropTargetExtensionConnector { final BodyRowContainer gridBody = getGridBody(); final Range visibleRowRange = getEscalator().getVisibleRowRange(); + if (!isDroppingOnRowsPossible()) { + return tableWrapper; + } + while (!Objects.equals(source, tableWrapper)) { // the drop might happen on top of header, body or footer rows if (TableRowElement.is(source)) { @@ -296,11 +325,9 @@ public class GridDropTargetConnector extends DropTargetExtensionConnector { } source = source.getParentElement(); } - // the drag is on top of the tablewrapper - // if no rows in grid, or if the drop mode is ON_TOP, then there is no - // target row for the drop - if (visibleRowRange.isEmpty() - || getState().dropMode == DropMode.ON_TOP) { + // the drag is on top of the tablewrapper, if the drop mode is ON_TOP, + // then there is no target row for the drop + if (getState().dropMode == DropMode.ON_TOP) { return tableWrapper; } // if dragged under the last row to empty space, drop target @@ -328,6 +355,10 @@ public class GridDropTargetConnector extends DropTargetExtensionConnector { return getEscalator().getBody(); } + private boolean isGridSortedByUser() { + return !gridConnector.getWidget().getSortOrder().isEmpty(); + } + @Override public GridDropTargetState getState() { return (GridDropTargetState) super.getState(); -- cgit v1.2.3