summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetConnector.java4
-rw-r--r--client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java64
-rw-r--r--documentation/advanced/advanced-dragndrop.asciidoc11
-rw-r--r--server/src/main/java/com/vaadin/ui/components/grid/GridDropEvent.java8
-rw-r--r--themes/src/main/themes/VAADIN/themes/valo/components/_grid.scss6
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/grid/GridDragAndDrop.java17
6 files changed, 86 insertions, 24 deletions
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 2ee5c253a9..974e63b9f2 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
@@ -149,7 +149,7 @@ public class GridDropTargetConnector extends DropTargetExtensionConnector {
}
@Override
- protected void addTargetClassIndicator(NativeEvent event) {
+ protected void addDragOverStyle(NativeEvent event) {
getTargetRow(((Element) event.getEventTarget().cast()))
.ifPresent(target -> {
@@ -187,7 +187,7 @@ public class GridDropTargetConnector extends DropTargetExtensionConnector {
}
@Override
- protected void removeTargetClassIndicator(NativeEvent event) {
+ protected void removeDragOverStyle(NativeEvent event) {
// Remove all possible style names
getTargetRow((Element) event.getEventTarget().cast()).ifPresent(e -> {
diff --git a/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java b/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java
index 060f2a5167..060a12f658 100644
--- a/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java
+++ b/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java
@@ -65,6 +65,11 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
*/
protected static final String STYLE_SUFFIX_DRAG_BOTTOM = "-drag-bottom";
+ /**
+ * Style name suffix for indicating that the element is drop target.
+ */
+ protected static final String STYLE_SUFFIX_DROPTARGET = "-droptarget";
+
// Create event listeners
private final EventListener dragEnterListener = this::onDragEnter;
private final EventListener dragOverListener = this::onDragOver;
@@ -95,6 +100,9 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
addDropListeners(getDropTargetElement());
((AbstractComponentConnector) target).onDropTargetAttached();
+
+ // Add drop target indicator to the drop target element
+ addDropTargetStyle();
}
/**
@@ -135,6 +143,9 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
removeDropListeners(getDropTargetElement());
((AbstractComponentConnector) getParent()).onDropTargetDetached();
+
+ // Remove drop target indicator
+ removeDropTargetStyle();
}
/**
@@ -164,7 +175,7 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
+ STYLE_SUFFIX_DRAG_CENTER;
if (isDropAllowed(nativeEvent)) {
- addTargetClassIndicator(nativeEvent);
+ addDragOverStyle(nativeEvent);
setDropEffect(nativeEvent);
@@ -218,8 +229,8 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
if (isDropAllowed(nativeEvent)) {
setDropEffect(nativeEvent);
- // Add drop target indicator in case the element doesn't have one
- addTargetClassIndicator(nativeEvent);
+ // Add drag over indicator in case the element doesn't have one
+ addDragOverStyle(nativeEvent);
// Prevent default to allow drop
nativeEvent.preventDefault();
@@ -229,8 +240,8 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
nativeEvent.getDataTransfer()
.setDropEffect(DataTransfer.DropEffect.NONE);
- // Remove drop target indicator
- removeTargetClassIndicator(nativeEvent);
+ // Remove drag over indicator
+ removeDragOverStyle(nativeEvent);
}
}
@@ -244,7 +255,7 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
* browser event to be handled
*/
protected void onDragLeave(Event event) {
- removeTargetClassIndicator((NativeEvent) event);
+ removeDragOverStyle((NativeEvent) event);
}
/**
@@ -276,7 +287,7 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
.getDropEffect(nativeEvent.getDataTransfer()), nativeEvent);
}
- removeTargetClassIndicator(nativeEvent);
+ removeDragOverStyle(nativeEvent);
}
private boolean isDropAllowed(NativeEvent event) {
@@ -316,7 +327,33 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
}
/**
- * Add class that indicates that the component is a target.
+ * Add class name for the drop target element indicating that data can be
+ * dropped onto it. The class name has the following format:
+ * <pre>
+ * [primaryStyleName]-droptarget
+ * </pre>
+ * The added class name is update
+ * automatically by the framework when the primary style name changes.
+ */
+ protected void addDropTargetStyle() {
+ getDropTargetElement().addClassName(
+ getStylePrimaryName(getDropTargetElement())
+ + STYLE_SUFFIX_DROPTARGET);
+ }
+
+ /**
+ * Remove class name from the drop target element indication that data can
+ * be dropped onto it.
+ */
+ protected void removeDropTargetStyle() {
+ getDropTargetElement().removeClassName(
+ getStylePrimaryName(getDropTargetElement())
+ + STYLE_SUFFIX_DROPTARGET);
+ }
+
+ /**
+ * Add class that indicates that the component is a target while data is
+ * being dragged over it.
* <p>
* This is triggered on {@link #onDragEnter(Event) dragenter} and
* {@link #onDragOver(Event) dragover} events pending if the drop is
@@ -327,12 +364,12 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
* @param event
* the dragenter or dragover event that triggered the indication.
*/
- protected void addTargetClassIndicator(NativeEvent event) {
+ protected void addDragOverStyle(NativeEvent event) {
getDropTargetElement().addClassName(styleDragCenter);
}
/**
- * Remove the drag target indicator class name from the target element.
+ * Remove the drag over indicator class name from the target element.
* <p>
* This is triggered on {@link #onDrop(Event) drop},
* {@link #onDragLeave(Event) dragleave} and {@link #onDragOver(Event)
@@ -344,7 +381,7 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
* @param event
* the event that triggered the removal of the indicator
*/
- protected void removeTargetClassIndicator(NativeEvent event) {
+ protected void removeDragOverStyle(NativeEvent event) {
getDropTargetElement().removeClassName(styleDragCenter);
}
@@ -358,6 +395,11 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
return new Function('event', script)(event);
}-*/;
+ private native boolean getStylePrimaryName(Element element)
+ /*-{
+ return @com.google.gwt.user.client.ui.UIObject::getStylePrimaryName(Lcom/google/gwt/dom/client/Element;)(element);
+ }-*/;
+
@Override
public DropTargetState getState() {
return (DropTargetState) super.getState();
diff --git a/documentation/advanced/advanced-dragndrop.asciidoc b/documentation/advanced/advanced-dragndrop.asciidoc
index d7ef80ac33..2db6e0f18b 100644
--- a/documentation/advanced/advanced-dragndrop.asciidoc
+++ b/documentation/advanced/advanced-dragndrop.asciidoc
@@ -153,7 +153,9 @@ TODO Add an example of drop criteria
=== CSS Style Rules
-When dragging data over a drop target and the drag over criteria passes, a style name is applied to indicate that the element accepts drops. This style name is the primary style name with `-drag-center` suffix, e.g. `v-label-drag-center`.
+Each drop target element have an applied style name, the primary style name with `-droptarget` suffix, e.g. `v-label-droptarget`, to indicate that it is a potential target for data to be dropped onto it.
+
+When dragging data over a drop target and the drag over criteria passes, a style name is applied to indicate that the element accepts the drop. This style name is the primary style name with `-drag-center` suffix, e.g. `v-label-drag-center`.
////
@@ -321,8 +323,11 @@ dropTarget.addGridDropListener(event -> {
List<Person> items = (List<Person>) dataProvider.getItems();
// Calculate the target row's index
- int index = items.indexOf(event.getDropTargetRow()) + (
+ int index = items.size();
+ if (event.getDropTargetRow().isPresent()) {
+ index = items.indexOf(event.getDropTargetRow().get()) + (
event.getDropLocation() == DropLocation.BELOW ? 1 : 0);
+ }
// Add dragged items to the target Grid
items.addAll(index, draggedItems);
@@ -337,6 +342,8 @@ dropTarget.addGridDropListener(event -> {
==== CSS Style Rules
+A drop target Grid's body has the style name `v-grid-body-droptarget` to indicate that it is a potential target for data to be dropped.
+
When dragging data over a drop target Grid's row, depending on the drop mode and the mouse position relative to the row, a style name is applied to the row to indicate the drop location.
`v-grid-row-drag-center` indicates ON_TOP, `v-grid-row-drag-top` indicates ABOVE and `v-grid-row-drag-bottom` indicates BELOW locations.
diff --git a/server/src/main/java/com/vaadin/ui/components/grid/GridDropEvent.java b/server/src/main/java/com/vaadin/ui/components/grid/GridDropEvent.java
index 08d0dad956..80eab4d1fd 100644
--- a/server/src/main/java/com/vaadin/ui/components/grid/GridDropEvent.java
+++ b/server/src/main/java/com/vaadin/ui/components/grid/GridDropEvent.java
@@ -16,6 +16,7 @@
package com.vaadin.ui.components.grid;
import java.util.Map;
+import java.util.Optional;
import com.vaadin.shared.ui.dnd.DropEffect;
import com.vaadin.shared.ui.grid.DropLocation;
@@ -69,10 +70,11 @@ public class GridDropEvent<T> extends DropEvent<Grid<T>> {
/**
* Get the row item source of this event.
*
- * @return The row item this event was originated from.
+ * @return The optional row item if the event was originated from a row,
+ * otherwise an empty optional.
*/
- public T getDropTargetRow() {
- return dropTargetRow;
+ public Optional<T> getDropTargetRow() {
+ return Optional.ofNullable(dropTargetRow);
}
/**
diff --git a/themes/src/main/themes/VAADIN/themes/valo/components/_grid.scss b/themes/src/main/themes/VAADIN/themes/valo/components/_grid.scss
index 06376d6a6e..541c38c314 100644
--- a/themes/src/main/themes/VAADIN/themes/valo/components/_grid.scss
+++ b/themes/src/main/themes/VAADIN/themes/valo/components/_grid.scss
@@ -876,6 +876,12 @@ $v-grid-drag-indicator-color: $v-focus-color;
background: darken($v-grid-drag-indicator-color, 10%);
}
}
+
+ // Expand Grid's body to cover the whole Grid
+ .#{$primary-stylename}-body-droptarget {
+ width: 100%;
+ height: 100%;
+ }
}
diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridDragAndDrop.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridDragAndDrop.java
index 9bda8c3a05..ad13e2177a 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/grid/GridDragAndDrop.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/grid/GridDragAndDrop.java
@@ -55,7 +55,7 @@ public class GridDragAndDrop extends AbstractTestUIWithLog {
GridDragSource<Person> dragSource = applyDragSource(left);
// Drop target Grid
- Grid<Person> right = createGridAndFillWithData(5);
+ Grid<Person> right = createGridAndFillWithData(0);
GridDropTarget<Person> dropTarget = applyDropTarget(right);
// Layout the two grids
@@ -158,9 +158,12 @@ public class GridDragAndDrop extends AbstractTestUIWithLog {
List<Person> items = (List<Person>) dataProvider.getItems();
// Calculate the target row's index
- int index = items.indexOf(event.getDropTargetRow())
- + (event.getDropLocation() == DropLocation.BELOW ? 1
- : 0);
+ int index = items.size();
+ if (event.getDropTargetRow().isPresent()) {
+ index = items.indexOf(event.getDropTargetRow().get())
+ + (event.getDropLocation() == DropLocation.BELOW
+ ? 1 : 0);
+ }
// Add dragged items to the target Grid
items.addAll(index, draggedItems);
@@ -170,8 +173,10 @@ public class GridDragAndDrop extends AbstractTestUIWithLog {
+ ", dragDataJson="
+ event.getDataTransferData("application/json")
+ ", target="
- + event.getDropTargetRow().getFirstName() + " "
- + event.getDropTargetRow().getLastName()
+ + (event.getDropTargetRow().isPresent() ?
+ event.getDropTargetRow().get().getFirstName() + " "
+ + event.getDropTargetRow().get()
+ .getLastName() : "[BODY]")
+ ", location=" + event.getDropLocation());
}
});