* 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 UItags/8.7.0.alpha1
@@ -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, |
@@ -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 | |||
@@ -365,6 +360,25 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector { | |||
return allowed; | |||
} | |||
/** | |||
* 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> |
@@ -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; | |||
} | |||
} |