summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorAdam Wagner <wbadam@users.noreply.github.com>2017-02-28 09:41:04 +0200
committerHenri Sara <henri.sara@gmail.com>2017-04-12 14:58:11 +0300
commitc4f8524ea881e6a946ac9e9e1911fd2873f484e9 (patch)
tree05a175054cd7e3728b8ce6d80a2d6954a6494cc8 /client
parent8b94b1aeca0e8d7cdd2d13d2f9ba32264b310ac2 (diff)
downloadvaadin-framework-c4f8524ea881e6a946ac9e9e1911fd2873f484e9.tar.gz
vaadin-framework-c4f8524ea881e6a946ac9e9e1911fd2873f484e9.zip
Make Grid rows draggable (#8690)
It is possible to customize the drag data for each row. (#8706) Fixes #8396
Diffstat (limited to 'client')
-rw-r--r--client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceExtensionConnector.java119
-rw-r--r--client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java61
-rw-r--r--client/src/main/java/com/vaadin/client/widget/escalator/RowContainer.java14
-rw-r--r--client/src/main/java/com/vaadin/client/widgets/Escalator.java18
4 files changed, 200 insertions, 12 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
new file mode 100644
index 0000000000..f402f2396d
--- /dev/null
+++ b/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceExtensionConnector.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 com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.dom.client.TableRowElement;
+import com.vaadin.client.ServerConnector;
+import com.vaadin.client.extensions.DragSourceExtensionConnector;
+import com.vaadin.client.widget.escalator.RowContainer;
+import com.vaadin.client.widgets.Escalator;
+import com.vaadin.shared.Range;
+import com.vaadin.shared.ui.Connect;
+import com.vaadin.shared.ui.grid.GridDragSourceExtensionState;
+import com.vaadin.ui.GridDragSourceExtension;
+
+import elemental.events.Event;
+import elemental.json.JsonObject;
+
+/**
+ * Adds HTML5 drag and drop functionality to a {@link com.vaadin.client.widgets.Grid
+ * Grid}'s rows. This is the client side counterpart of {@link
+ * GridDragSourceExtension}.
+ *
+ * @author Vaadin Ltd
+ * @since
+ */
+@Connect(GridDragSourceExtension.class)
+public class GridDragSourceExtensionConnector extends
+ DragSourceExtensionConnector {
+
+ private GridConnector gridConnector;
+
+ @Override
+ protected void extend(ServerConnector target) {
+ this.gridConnector = (GridConnector) target;
+
+ // Set newly added rows draggable
+ getGridBody().setNewEscalatorRowCallback(
+ rows -> rows.forEach(this::setDraggable));
+
+ // Add drag listeners to body element
+ addDragListeners(getGridBody().getElement());
+ }
+
+ @Override
+ protected void onDragStart(Event event) {
+ super.onDragStart(event);
+
+ if (event.getTarget() instanceof TableRowElement) {
+ TableRowElement row = (TableRowElement) event.getTarget();
+ int rowIndex = ((Escalator.AbstractRowContainer) getGridBody())
+ .getLogicalRowIndex(row);
+
+ JsonObject rowData = gridConnector.getDataSource().getRow(rowIndex);
+
+ // Set drag data in DataTransfer object
+ ((NativeEvent) event).getDataTransfer()
+ .setData(GridDragSourceExtensionState.DATA_TYPE_DRAG_DATA,
+ getDragData(rowData).toJson());
+ }
+ }
+
+ /**
+ * Gets drag data from the row data if exists or returns complete row data
+ * otherwise.
+ *
+ * @param row
+ * Row data.
+ * @return Drag data if present or row data otherwise.
+ */
+ private JsonObject getDragData(JsonObject row) {
+ return row.hasKey(GridDragSourceExtensionState.JSONKEY_DRAG_DATA)
+ ? row.getObject(GridDragSourceExtensionState.JSONKEY_DRAG_DATA)
+ : row;
+ }
+
+ @Override
+ public void onUnregister() {
+ super.onUnregister();
+
+ // Remove draggable from all row elements in the escalator
+ Range visibleRange = getEscalator().getVisibleRowRange();
+ for (int i = visibleRange.getStart(); i < visibleRange.getEnd(); i++) {
+ removeDraggable(getGridBody().getRowElement(i));
+ }
+
+ // Remove drag listeners from body element
+ removeDragListeners(getGridBody().getElement());
+
+ // Remove callback for newly added rows
+ getGridBody().setNewEscalatorRowCallback(null);
+ }
+
+ private Escalator getEscalator() {
+ return gridConnector.getWidget().getEscalator();
+ }
+
+ private RowContainer.BodyRowContainer getGridBody() {
+ return getEscalator().getBody();
+ }
+
+ @Override
+ public GridDragSourceExtensionState getState() {
+ return (GridDragSourceExtensionState) 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 3094042826..23797ce886 100644
--- a/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
+++ b/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
@@ -56,29 +56,66 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector {
protected void extend(ServerConnector target) {
dragSourceWidget = ((ComponentConnector) target).getWidget();
- Element dragSourceElement = getDraggableElement();
+ setDraggable(getDraggableElement());
+ addDragListeners(getDraggableElement());
+ }
+
+ /**
+ * Sets the given element draggable and adds class name.
+ *
+ * @param element
+ * Element to be set draggable.
+ */
+ protected void setDraggable(Element element) {
+ element.setDraggable(Element.DRAGGABLE_TRUE);
+ element.addClassName(CLASS_DRAGGABLE);
+ }
+
+ /**
+ * Removes draggable and class name from the given element.
+ *
+ * @param element
+ * Element to remove draggable from.
+ */
+ protected void removeDraggable(Element element) {
+ element.setDraggable(Element.DRAGGABLE_FALSE);
+ element.removeClassName(CLASS_DRAGGABLE);
+ }
- dragSourceElement.setDraggable(Element.DRAGGABLE_TRUE);
- dragSourceElement.addClassName(CLASS_DRAGGABLE);
+ /**
+ * Adds dragstart and dragend event listeners to the given DOM element.
+ *
+ * @param element
+ * DOM element to attach event listeners to.
+ */
+ protected void addDragListeners(Element element) {
+ EventTarget target = element.cast();
- EventTarget dragSource = dragSourceElement.cast();
+ target.addEventListener(Event.DRAGSTART, dragStartListener);
+ target.addEventListener(Event.DRAGEND, dragEndListener);
+ }
- // dragstart
- dragSource.addEventListener(Event.DRAGSTART, dragStartListener);
+ /**
+ * Removes dragstart and dragend event listeners from the given DOM element.
+ *
+ * @param element
+ * DOM element to remove event listeners from.
+ */
+ protected void removeDragListeners(Element element) {
+ EventTarget target = element.cast();
- // dragend
- dragSource.addEventListener(Event.DRAGEND, dragEndListener);
+ target.removeEventListener(Event.DRAGSTART, dragStartListener);
+ target.removeEventListener(Event.DRAGEND, dragEndListener);
}
@Override
public void onUnregister() {
super.onUnregister();
- EventTarget dragSource = (EventTarget) getDraggableElement();
+ Element dragSource = getDraggableElement();
- // Remove listeners
- dragSource.removeEventListener(Event.DRAGSTART, dragStartListener);
- dragSource.removeEventListener(Event.DRAGEND, dragEndListener);
+ removeDraggable(dragSource);
+ removeDragListeners(dragSource);
}
/**
diff --git a/client/src/main/java/com/vaadin/client/widget/escalator/RowContainer.java b/client/src/main/java/com/vaadin/client/widget/escalator/RowContainer.java
index 0105aa687c..ca00ca9b63 100644
--- a/client/src/main/java/com/vaadin/client/widget/escalator/RowContainer.java
+++ b/client/src/main/java/com/vaadin/client/widget/escalator/RowContainer.java
@@ -16,6 +16,9 @@
package com.vaadin.client.widget.escalator;
+import java.util.List;
+import java.util.function.Consumer;
+
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.dom.client.TableSectionElement;
@@ -116,6 +119,17 @@ public interface RowContainer {
@Override
public void removeRows(int index, int numberOfRows)
throws IndexOutOfBoundsException, IllegalArgumentException;
+
+ /**
+ * Sets a callback function that is executed when new rows are added to
+ * the escalator.
+ *
+ * @param consumer
+ * A Consumer function that receives the newly added table row
+ * elements.
+ */
+ public void setNewEscalatorRowCallback(
+ Consumer<List<TableRowElement>> consumer);
}
/**
diff --git a/client/src/main/java/com/vaadin/client/widgets/Escalator.java b/client/src/main/java/com/vaadin/client/widgets/Escalator.java
index 7bb078a94a..1f223c1d85 100644
--- a/client/src/main/java/com/vaadin/client/widgets/Escalator.java
+++ b/client/src/main/java/com/vaadin/client/widgets/Escalator.java
@@ -25,7 +25,9 @@ import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Optional;
import java.util.TreeMap;
+import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -2401,6 +2403,12 @@ public class Escalator extends Widget
@Deprecated
private int topRowLogicalIndex = 0;
+ /**
+ * A callback function to be executed after new rows are added to the
+ * escalator.
+ */
+ private Consumer<List<TableRowElement>> newEscalatorRowCallback;
+
private void setTopRowLogicalIndex(int topRowLogicalIndex) {
if (LogConfiguration.loggingIsEnabled(Level.INFO)) {
Logger.getLogger("Escalator.BodyRowContainer")
@@ -2992,6 +3000,10 @@ public class Escalator extends Widget
y += spacerContainer.getSpacerHeight(i);
}
+ // Execute the registered callback function for newly created rows
+ Optional.ofNullable(newEscalatorRowCallback)
+ .ifPresent(callback -> callback.accept(addedRows));
+
return addedRows;
} else {
return Collections.emptyList();
@@ -3982,6 +3994,12 @@ public class Escalator extends Widget
int padding) {
spacerContainer.scrollToSpacer(spacerIndex, destination, padding);
}
+
+ @Override
+ public void setNewEscalatorRowCallback(
+ Consumer<List<TableRowElement>> callback) {
+ this.newEscalatorRowCallback = callback;
+ }
}
private class ColumnConfigurationImpl implements ColumnConfiguration {