diff options
author | Adam Wagner <wbadam@users.noreply.github.com> | 2017-03-16 10:32:22 +0200 |
---|---|---|
committer | Henri Sara <henri.sara@gmail.com> | 2017-04-12 14:58:11 +0300 |
commit | 2df1b373aae547275b566fef957322af0b61b427 (patch) | |
tree | 74085469535986808d5111f5164e1aaf3c4a38d9 | |
parent | c4f8524ea881e6a946ac9e9e1911fd2873f484e9 (diff) | |
download | vaadin-framework-2df1b373aae547275b566fef957322af0b61b427.tar.gz vaadin-framework-2df1b373aae547275b566fef957322af0b61b427.zip |
Make all selected rows draggable (#8746)
Fixes #8397
3 files changed, 100 insertions, 3 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 f402f2396d..eaeaffc1d9 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 @@ -15,19 +15,28 @@ */ package com.vaadin.client.connectors.grid; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + 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.widget.grid.selection.SelectionModel; 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.grid.GridDragSourceExtensionState; import com.vaadin.ui.GridDragSourceExtension; import elemental.events.Event; +import elemental.json.Json; +import elemental.json.JsonArray; import elemental.json.JsonObject; +import elemental.json.JsonValue; /** * Adds HTML5 drag and drop functionality to a {@link com.vaadin.client.widgets.Grid @@ -66,11 +75,78 @@ public class GridDragSourceExtensionConnector extends JsonObject rowData = gridConnector.getDataSource().getRow(rowIndex); + // Generate drag data. Dragged row or all the selected rows + JsonValue dragData = dragMultipleRows(rowData) ? toJsonArray( + getSelectedVisibleRows().stream().map(this::getDragData) + .collect(Collectors.toList())) + : getDragData(rowData); + // Set drag data in DataTransfer object ((NativeEvent) event).getDataTransfer() .setData(GridDragSourceExtensionState.DATA_TYPE_DRAG_DATA, - getDragData(rowData).toJson()); + dragData.toJson()); + } + } + + /** + * Tells if multiple rows are dragged. Returns true if multiple selection is + * allowed and a selected row is dragged. + * + * @param draggedRow + * Data of dragged row. + * @return {@code true} if multiple rows are dragged, {@code false} + * otherwise. + */ + private boolean dragMultipleRows(JsonObject draggedRow) { + SelectionModel<JsonObject> selectionModel = getGrid() + .getSelectionModel(); + return selectionModel.isSelectionAllowed() + && selectionModel instanceof MultiSelectionModelConnector.MultiSelectionModel + && selectionModel.isSelected(draggedRow); + } + + /** + * Collects the data of all selected visible rows. + * + * @return List of data of all selected visible rows. + */ + private List<JsonObject> getSelectedVisibleRows() { + return getSelectedRowsInRange(getEscalator().getVisibleRowRange()); + } + + /** + * Get all selected rows from a subset of rows defined by {@code range}. + * + * @param range + * Range of indexes. + * @return List of data of all selected rows in the given range. + */ + private List<JsonObject> getSelectedRowsInRange(Range range) { + List<JsonObject> selectedRows = new ArrayList<>(); + + for (int i = range.getStart(); i < range.getEnd(); i++) { + JsonObject row = gridConnector.getDataSource().getRow(i); + if (SelectionModel.isItemSelected(row)) { + selectedRows.add(row); + } + } + + return selectedRows; + } + + /** + * Converts a list of {@link JsonObject}s to a {@link JsonArray}. + * + * @param objects + * List of json objects. + * @return Json array containing all json objects. + */ + private JsonArray toJsonArray(List<JsonObject> objects) { + JsonArray array = Json.createArray(); + for (int i = 0; i < objects.size(); i++) { + array.set(i, objects.get(i)); } + return array; } /** @@ -104,8 +180,12 @@ public class GridDragSourceExtensionConnector extends getGridBody().setNewEscalatorRowCallback(null); } + private Grid<JsonObject> getGrid() { + return gridConnector.getWidget(); + } + private Escalator getEscalator() { - return gridConnector.getWidget().getEscalator(); + return getGrid().getEscalator(); } private RowContainer.BodyRowContainer getGridBody() { diff --git a/server/src/main/java/com/vaadin/ui/GridDragSourceExtension.java b/server/src/main/java/com/vaadin/ui/GridDragSourceExtension.java index 9f7e9ec67d..908cfdb504 100644 --- a/server/src/main/java/com/vaadin/ui/GridDragSourceExtension.java +++ b/server/src/main/java/com/vaadin/ui/GridDragSourceExtension.java @@ -26,6 +26,9 @@ import elemental.json.JsonObject; /** * Makes a Grid's rows draggable for HTML5 drag and drop functionality. + * <p> + * When dragging a selected row, all the visible selected rows are dragged. Note + * that ONLY visible rows are taken into account. * * @param <T> * The Grid bean type. 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 32c147f15f..a6036acac8 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 @@ -16,13 +16,16 @@ package com.vaadin.tests.components.grid; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.stream.IntStream; +import com.vaadin.annotations.Widgetset; import com.vaadin.event.dnd.DropTargetExtension; import com.vaadin.server.VaadinRequest; import com.vaadin.shared.ui.grid.GridDragSourceExtensionState; import com.vaadin.tests.components.AbstractTestUIWithLog; +import com.vaadin.ui.ComboBox; import com.vaadin.ui.Grid; import com.vaadin.ui.GridDragSourceExtension; import com.vaadin.ui.HorizontalLayout; @@ -32,6 +35,7 @@ import com.vaadin.ui.Layout; import elemental.json.Json; import elemental.json.JsonObject; +@Widgetset("com.vaadin.DefaultWidgetSet") public class GridDragAndDrop extends AbstractTestUIWithLog { @Override protected void setup(VaadinRequest request) { @@ -62,7 +66,17 @@ public class GridDragAndDrop extends AbstractTestUIWithLog { Layout layout = new HorizontalLayout(); layout.addComponents(dragSourceComponent, dropTargetComponent); - addComponent(layout); + // Selection mode combo box + ComboBox<Grid.SelectionMode> selectionModeSwitch = new ComboBox<>( + "Change selection mode"); + selectionModeSwitch.setItems(Arrays.asList(Grid.SelectionMode.SINGLE, + Grid.SelectionMode.MULTI)); + selectionModeSwitch.setEmptySelectionAllowed(false); + selectionModeSwitch.addValueChangeListener(event -> dragSourceComponent + .setSelectionMode(event.getValue())); + selectionModeSwitch.setSelectedItem(Grid.SelectionMode.SINGLE); + + addComponents(selectionModeSwitch, layout); } private List<Bean> createItems(int num) { |