summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorAdam Wagner <wbadam@users.noreply.github.com>2017-03-16 20:35:46 +0200
committerHenri Sara <henri.sara@gmail.com>2017-04-12 14:58:11 +0300
commit1ac4f9724106fcf4abaab892210122231710c6be (patch)
treecd63d9a7d1e689b041ca05d25385d4b39929782d /client
parent2df1b373aae547275b566fef957322af0b61b427 (diff)
downloadvaadin-framework-1ac4f9724106fcf4abaab892210122231710c6be.tar.gz
vaadin-framework-1ac4f9724106fcf4abaab892210122231710c6be.zip
Make it possible to drop things on top of Grid rows (#8747)
Fixes #8400
Diffstat (limited to 'client')
-rw-r--r--client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceExtensionConnector.java4
-rw-r--r--client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetExtensionConnector.java119
-rw-r--r--client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java2
-rw-r--r--client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java101
4 files changed, 193 insertions, 33 deletions
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceExtensionConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceExtensionConnector.java
index eaeaffc1d9..b31a2578eb 100644
--- a/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceExtensionConnector.java
+++ b/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceExtensionConnector.java
@@ -29,6 +29,7 @@ import com.vaadin.client.widgets.Escalator;
import com.vaadin.client.widgets.Grid;
import com.vaadin.shared.Range;
import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.dnd.DragSourceState;
import com.vaadin.shared.ui.grid.GridDragSourceExtensionState;
import com.vaadin.ui.GridDragSourceExtension;
@@ -83,8 +84,7 @@ public class GridDragSourceExtensionConnector extends
// Set drag data in DataTransfer object
((NativeEvent) event).getDataTransfer()
- .setData(GridDragSourceExtensionState.DATA_TYPE_DRAG_DATA,
- dragData.toJson());
+ .setData(DragSourceState.DATA_TYPE_TEXT, dragData.toJson());
}
}
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetExtensionConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetExtensionConnector.java
new file mode 100644
index 0000000000..9c25f5acb4
--- /dev/null
+++ b/client/src/main/java/com/vaadin/client/connectors/grid/GridDropTargetExtensionConnector.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2000-2016 Vaadin Ltd.
+ *
+ * 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.
+ */
+package com.vaadin.client.connectors.grid;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.TableRowElement;
+import com.vaadin.client.ServerConnector;
+import com.vaadin.client.extensions.DropTargetExtensionConnector;
+import com.vaadin.client.widget.escalator.RowContainer;
+import com.vaadin.client.widgets.Escalator;
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.grid.GridDropTargetExtensionRpc;
+import com.vaadin.shared.ui.grid.GridDropTargetExtensionState;
+import com.vaadin.shared.ui.grid.GridState;
+import com.vaadin.ui.GridDropTargetExtension;
+
+import elemental.events.Event;
+import elemental.json.JsonObject;
+
+/**
+ * Makes Grid an HTML5 drop target. This is the client side counterpart of
+ * {@link GridDropTargetExtension}.
+ *
+ * @author Vaadin Ltd
+ * @since
+ */
+@Connect(GridDropTargetExtension.class)
+public class GridDropTargetExtensionConnector extends
+ DropTargetExtensionConnector {
+
+ private GridConnector gridConnector;
+
+ @Override
+ protected void extend(ServerConnector target) {
+ gridConnector = (GridConnector) target;
+
+ super.extend(target);
+ }
+
+ @Override
+ protected void sendDropEventToServer(String dataTransferText,
+ Event dropEvent) {
+
+ String rowKey = null;
+ Optional<TableRowElement> targetRow = getTargetRow(
+ (Element) dropEvent.getTarget());
+ if (targetRow.isPresent()) {
+ rowKey = getRowData(targetRow.get())
+ .getString(GridState.JSONKEY_ROWKEY);
+ }
+
+ getRpcProxy(GridDropTargetExtensionRpc.class)
+ .drop(dataTransferText, rowKey);
+ }
+
+ private JsonObject getRowData(TableRowElement row) {
+ int rowIndex = ((Escalator.AbstractRowContainer) getGridBody())
+ .getLogicalRowIndex(row);
+ return gridConnector.getDataSource().getRow(rowIndex);
+ }
+
+ @Override
+ protected void addTargetIndicator(Event event) {
+ getTargetRow(((Element) event.getTarget()))
+ .ifPresent(e -> e.addClassName(CLASS_DRAG_OVER));
+ }
+
+ @Override
+ protected void removeTargetIndicator(Event event) {
+ getTargetRow(((Element) event.getTarget()))
+ .ifPresent(e -> e.removeClassName(CLASS_DRAG_OVER));
+ }
+
+ private Optional<TableRowElement> getTargetRow(Element source) {
+ while (!Objects.equals(source, getGridBody().getElement())) {
+ if (TableRowElement.is(source)) {
+ return Optional.of(source.cast());
+ }
+ source = source.getParentElement();
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ protected Element getDropTargetElement() {
+ return getGridBody().getElement();
+ }
+
+ private Escalator getEscalator() {
+ return gridConnector.getWidget().getEscalator();
+ }
+
+ private RowContainer.BodyRowContainer getGridBody() {
+ return getEscalator().getBody();
+ }
+
+ @Override
+ public GridDropTargetExtensionState getState() {
+ return (GridDropTargetExtensionState) super.getState();
+ }
+}
diff --git a/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java b/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
index 23797ce886..52c70b362b 100644
--- a/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
+++ b/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
@@ -161,7 +161,7 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector {
((NativeEvent) event).getDataTransfer());
assert dropEffect != null : "Drop effect should never be null";
-
+
getRpcProxy(DragSourceRpc.class)
.dragEnd(DropEffect.valueOf(dropEffect.toUpperCase()));
}
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 5f8ca243c7..473b72237e 100644
--- a/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java
+++ b/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java
@@ -15,7 +15,6 @@
*/
package com.vaadin.client.extensions;
-import com.google.gwt.dom.client.BrowserEvents;
import com.google.gwt.dom.client.DataTransfer;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
@@ -42,7 +41,7 @@ import elemental.events.EventTarget;
@Connect(DropTargetExtension.class)
public class DropTargetExtensionConnector extends AbstractExtensionConnector {
- private static final String CLASS_DRAG_OVER = "v-drag-over";
+ protected static final String CLASS_DRAG_OVER = "v-drag-over";
// Create event listeners
private final EventListener dragEnterListener = this::onDragEnter;
@@ -59,35 +58,46 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
protected void extend(ServerConnector target) {
dropTargetWidget = ((ComponentConnector) target).getWidget();
- EventTarget dropTarget = getDropTargetElement().cast();
+ addDropListeners(getDropTargetElement());
+ }
- // dragenter event
- dropTarget.addEventListener(BrowserEvents.DRAGENTER, dragEnterListener);
+ /**
+ * Adds dragenter, dragover, dragleave and drop event listeners to the given
+ * DOM element.
+ *
+ * @param element
+ * DOM element to attach event listeners to.
+ */
+ protected void addDropListeners(Element element) {
+ EventTarget target = element.cast();
- // dragover event
- dropTarget.addEventListener(BrowserEvents.DRAGOVER, dragOverListener);
+ target.addEventListener(Event.DRAGENTER, dragEnterListener);
+ target.addEventListener(Event.DRAGOVER, dragOverListener);
+ target.addEventListener(Event.DRAGLEAVE, dragLeaveListener);
+ target.addEventListener(Event.DROP, dropListener);
+ }
- // dragleave event
- dropTarget.addEventListener(BrowserEvents.DRAGLEAVE, dragLeaveListener);
+ /**
+ * Removes dragenter, dragover, dragleave and drop event listeners from the
+ * given DOM element.
+ *
+ * @param element
+ * DOM element to remove event listeners from.
+ */
+ protected void removeDropListeners(Element element) {
+ EventTarget target = element.cast();
- // drop event
- dropTarget.addEventListener(BrowserEvents.DROP, dropListener);
+ target.removeEventListener(Event.DRAGENTER, dragEnterListener);
+ target.removeEventListener(Event.DRAGOVER, dragOverListener);
+ target.removeEventListener(Event.DRAGLEAVE, dragLeaveListener);
+ target.removeEventListener(Event.DROP, dropListener);
}
@Override
public void onUnregister() {
super.onUnregister();
- EventTarget dropTarget = getDropTargetElement().cast();
-
- // Remove listeners
- dropTarget.removeEventListener(BrowserEvents.DRAGENTER,
- dragEnterListener);
- dropTarget.removeEventListener(BrowserEvents.DRAGOVER,
- dragOverListener);
- dropTarget.removeEventListener(BrowserEvents.DRAGLEAVE,
- dragLeaveListener);
- dropTarget.removeEventListener(BrowserEvents.DROP, dropListener);
+ removeDropListeners(getDropTargetElement());
}
/**
@@ -107,7 +117,7 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
* browser event to be handled
*/
protected void onDragEnter(Event event) {
- addTargetIndicator(getDropTargetElement());
+ addTargetIndicator(event);
}
/**
@@ -126,6 +136,9 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
.valueOf(getState().dropEffect.name()));
}
+ // Add drop target indicator in case the element doesn't have one
+ addTargetIndicator(event);
+
// Prevent default to allow drop
nativeEvent.preventDefault();
nativeEvent.stopPropagation();
@@ -135,7 +148,7 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
.setDropEffect(DataTransfer.DropEffect.NONE);
// Remove drop target indicator
- removeTargetIndicator(getDropTargetElement());
+ removeTargetIndicator(event);
}
}
@@ -164,7 +177,7 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
* browser event to be handled
*/
protected void onDragLeave(Event event) {
- removeTargetIndicator(getDropTargetElement());
+ removeTargetIndicator(event);
}
/**
@@ -182,10 +195,10 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
String dataTransferText = nativeEvent.getDataTransfer().getData(
DragSourceState.DATA_TYPE_TEXT);
- getRpcProxy(DropTargetRpc.class).drop(dataTransferText);
+ sendDropEventToServer(dataTransferText, event);
}
- removeTargetIndicator(getDropTargetElement());
+ removeTargetIndicator(event);
}
private boolean dropAllowed(NativeEvent event) {
@@ -197,12 +210,40 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
return true;
}
- private void addTargetIndicator(Element element) {
- element.addClassName(CLASS_DRAG_OVER);
+ /**
+ * Initiates a server RPC for the drop event.
+ *
+ * @param dataTransferText
+ * Client side textual data that can be set for the drag source and
+ * is transferred to the drop target.
+ * @param dropEvent
+ * Client side drop event.
+ */
+ protected void sendDropEventToServer(String dataTransferText,
+ Event dropEvent) {
+ getRpcProxy(DropTargetRpc.class).drop(dataTransferText);
}
- private void removeTargetIndicator(Element element) {
- element.removeClassName(CLASS_DRAG_OVER);
+ /**
+ * Add class that indicates that the component is a target.
+ *
+ * @param event
+ * The drag enter or dragover event that triggered the indication.
+ */
+ protected void addTargetIndicator(Event event) {
+ getDropTargetElement().addClassName(CLASS_DRAG_OVER);
+ }
+
+ /**
+ * Remove the drag target indicator class name from the target element.
+ * <p>
+ * This is triggered on dragleave, drop and dragover events.
+ *
+ * @param event
+ * the event that triggered the removal of the indicator
+ */
+ protected void removeTargetIndicator(Event event) {
+ getDropTargetElement().removeClassName(CLASS_DRAG_OVER);
}
private native boolean executeScript(NativeEvent event, String script)/*-{