diff options
author | vt512 <vt512@users.noreply.github.com> | 2018-12-05 10:53:34 +0100 |
---|---|---|
committer | Sun Zhe <31067185+ZheSun88@users.noreply.github.com> | 2018-12-05 11:53:34 +0200 |
commit | ea22a7d17dcc82d2e28dbb0051fbb6904fd7c98d (patch) | |
tree | 89f5187a78616b6744c5b3f5015840dc24241709 | |
parent | 10bfb3995258018186aee1711af07e67aaf8c525 (diff) | |
download | vaadin-framework-ea22a7d17dcc82d2e28dbb0051fbb6904fd7c98d.tar.gz vaadin-framework-ea22a7d17dcc82d2e28dbb0051fbb6904fd7c98d.zip |
Add more context information to criteriaScript in GridDropTargetConnector (#11321)
* Add more context information to criteriaScript in GridDropTargetConnector
When using drag and drop in Grids and TreeGrids a criteriaScript can be specified.
However, this criteriaScript only gets an event as input parameter.
It would be helpful if the criteriaScript would get more information:
- the DropLocation
- the targetElement which is used as a base for the DropLocation
This change provides a protected method in DropTargetExtensionConnector
which decides, if the drop is allowed by the criteriaScript.
This method is overriden in GridDropTargetConnector to
provide the both parameters dropLocation and targetElement.
* add Test UI for criteriaScript with targetElement and dropLocation
* add some description for the Test UI
3 files changed, 125 insertions, 6 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 98c4100159..011b98654c 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 @@ -100,6 +100,25 @@ public class GridDropTargetConnector extends DropTargetExtensionConnector { super.extend(target); } + @Override + protected boolean isDropAllowedByCriteriaScript(NativeEvent event) { + final String criteriaScript = getState().criteriaScript; + if (criteriaScript == null) { + return true; + } + return executeScript(event, + getTargetElement(event.getEventTarget().cast()), + getDropLocation(getTargetElement(event.getEventTarget().cast()), + event).name(), + criteriaScript); + } + + private native boolean executeScript(NativeEvent event, + Element targetElement, String dropLocation, String script) + /*-{ + return new Function('event', 'targetElement', 'dropLocation', script)(event, targetElement, dropLocation); + }-*/; + /** * 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, 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 2bd0ae81f3..a2c221be44 100644 --- a/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java +++ b/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java @@ -326,13 +326,8 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector { // Currently Safari, Edge and IE don't follow the spec by allowing drop // if those don't match - // Allow by default when criteria not set - boolean allowed = true; - // Execute criteria script - if (getState().criteriaScript != null) { - allowed = executeScript(event, getState().criteriaScript); - } + boolean allowed = isDropAllowedByCriteriaScript(event); // Execute criterion defined via API if (allowed && getState().criteria != null @@ -366,6 +361,25 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector { } /** + * Checks if a criteria script exists and, if yes, executes it. This method + * is protected, so subclasses as e.g. GridDropTargetConnector can override + * it to add additional script parameters. + * + * @param event + * browser event (dragEnter, dragOver, drop) that should be + * evaluated by the criteria script + * @return {@code true} if no script was given or if the script returned + * true, {@code false} otherwise. + */ + protected boolean isDropAllowedByCriteriaScript(NativeEvent event) { + final String criteriaScript = getState().criteriaScript; + if (criteriaScript == null) { + return true; + } + return executeScript(event, criteriaScript); + } + + /** * Tells if the given array of types contains files. * <p> * According to HTML specification, if any files are being dragged, {@code diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridDropCriteriaScript.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridDropCriteriaScript.java new file mode 100644 index 0000000000..3d036a3d3b --- /dev/null +++ b/uitest/src/main/java/com/vaadin/tests/components/grid/GridDropCriteriaScript.java @@ -0,0 +1,86 @@ +package com.vaadin.tests.components.grid; + +import com.vaadin.annotations.Theme; +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.shared.ui.ContentMode; +import com.vaadin.shared.ui.grid.DropLocation; +import com.vaadin.shared.ui.grid.DropMode; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Grid; +import com.vaadin.ui.Label; +import com.vaadin.ui.components.grid.GridDragSource; +import com.vaadin.ui.components.grid.GridDropTarget; + +import java.util.ArrayList; +import java.util.List; + +@Theme("valo") +@Widgetset("com.vaadin.DefaultWidgetSet") +public class GridDropCriteriaScript extends AbstractTestUI { + + class GridItem { + public final String caption; + public final DropLocation dropLocation; + + public GridItem(String caption, DropLocation dropLocation) { + this.caption = caption; + this.dropLocation = dropLocation; + } + + public String getCaption() { + return caption; + } + + public DropLocation getDropLocation() { + return dropLocation; + } + } + + @Override + protected void setup(VaadinRequest request) { + getUI().setMobileHtml5DndEnabled(true); + + final Label label = new Label("<h1>Test for existance of targetElement " + + "and dropLocation in criteriaScript</h1>" + + "<p>Drag one of the grid items.</p>" + + "<p>While dragging, hints in form of lines show " + + "where the item is allowed to be dropped.</p>" + + "<p>Test passed:" + "<ul>" + + "<li>ABOVE: Only a line above the item is displayed while dragging over the item</li>" + + "<li>BELOW: Only a line below the item is displayed while dragging over the item</li>" + + "<li>ON_TOP: Only a border around the item is displayed while dragging over the item</li>" + + "</ul>" + "</p>" + "<p>Test failed:" + "<ul>" + + "<li>otherwise</li>" + "</ul>" + "</p>", ContentMode.HTML); + + final Grid<GridItem> grid = new Grid<>(); + grid.addColumn(GridItem::getCaption); + grid.setStyleGenerator( + gridItem -> "dropLocation-" + gridItem.getDropLocation()); + + new GridDragSource<>(grid); + + final GridDropTarget<GridItem> dropTarget = new GridDropTarget<>(grid, + DropMode.ON_TOP_OR_BETWEEN); + dropTarget.setDropCriteriaScript( + "return targetElement.classList.contains('dropLocation-' + dropLocation);"); + + grid.setItems(createItems()); + + addComponents(label, grid); + } + + private List<GridItem> createItems() { + final ArrayList<GridItem> list = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + for (DropLocation dropLocation : new DropLocation[] { + DropLocation.ON_TOP, DropLocation.ABOVE, + DropLocation.BELOW }) { + list.add(new GridItem(i + ": " + dropLocation.name(), + dropLocation)); + } + } + return list; + } + +} |