diff options
author | Adam Wagner <wbadam@users.noreply.github.com> | 2017-07-03 13:36:17 +0200 |
---|---|---|
committer | Henri Sara <henri.sara@gmail.com> | 2017-07-03 14:36:17 +0300 |
commit | 6ecef502864ed201b468a68c00676beb401f21c7 (patch) | |
tree | 2f96341ebcb02bced9092e4d3196266ee2eb2740 /server | |
parent | 4d085fd8b3589db4fbbdcd52643cee4b20f70e31 (diff) | |
download | vaadin-framework-6ecef502864ed201b468a68c00676beb401f21c7.tar.gz vaadin-framework-6ecef502864ed201b468a68c00676beb401f21c7.zip |
Add criteria API to make it easier to set acceptance criteria for drag and drop (#9605)
Fixes #9600
Diffstat (limited to 'server')
3 files changed, 210 insertions, 23 deletions
diff --git a/server/src/main/java/com/vaadin/ui/dnd/DragSourceExtension.java b/server/src/main/java/com/vaadin/ui/dnd/DragSourceExtension.java index 42c29f738a..d123700be9 100644 --- a/server/src/main/java/com/vaadin/ui/dnd/DragSourceExtension.java +++ b/server/src/main/java/com/vaadin/ui/dnd/DragSourceExtension.java @@ -23,10 +23,12 @@ import java.util.Objects; import com.vaadin.server.AbstractExtension; import com.vaadin.server.Resource; import com.vaadin.shared.Registration; +import com.vaadin.shared.ui.dnd.criteria.ComparisonOperator; import com.vaadin.shared.ui.dnd.DragSourceRpc; import com.vaadin.shared.ui.dnd.DragSourceState; import com.vaadin.shared.ui.dnd.DropEffect; import com.vaadin.shared.ui.dnd.EffectAllowed; +import com.vaadin.shared.ui.dnd.criteria.Payload; import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.dnd.event.DragEndEvent; import com.vaadin.ui.dnd.event.DragEndListener; @@ -38,7 +40,7 @@ import com.vaadin.ui.dnd.event.DragStartListener; * functionality. * * @param <T> - * Type of the component to be extended. + * Type of the component to be extended. * @author Vaadin Ltd * @since 8.1 */ @@ -58,7 +60,7 @@ public class DragSourceExtension<T extends AbstractComponent> * Extends {@code target} component and makes it a drag source. * * @param target - * Component to be extended. + * Component to be extended. */ public DragSourceExtension(T target) { super.extend(target); @@ -125,7 +127,7 @@ public class DragSourceExtension<T extends AbstractComponent> * side. Fires the {@link DragEndEvent}. * * @param dropEffect - * the drop effect on the dragend + * the drop effect on the dragend */ protected void onDragEnd(DropEffect dropEffect) { DragEndEvent<T> event = new DragEndEvent<>(getParent(), dropEffect); @@ -150,7 +152,7 @@ public class DragSourceExtension<T extends AbstractComponent> * equivalent to {@link EffectAllowed#ALL}. * * @param effect - * Effects to allow for this draggable element. Cannot be {@code + * Effects to allow for this draggable element. Cannot be {@code * null}. */ public void setEffectAllowed(EffectAllowed effect) { @@ -294,6 +296,73 @@ public class DragSourceExtension<T extends AbstractComponent> } /** + * Sets payload for this drag source to use with acceptance criterion. The + * payload is transferred as data type in the data transfer object in the + * following format: {@code "v-item:string:key:value"}. The given value is + * compared to the criterion value when the drag source is dragged on top of + * a drop target that has the suitable criterion. + * <p> + * Note that setting payload in Internet Explorer 11 is not possible due to + * the browser's limitations. + * + * @param key + * key of the payload to be transferred + * @param value + * value of the payload to be transferred + * @see DropTargetExtension#setDropCriterion(String, String) + */ + public void setPayload(String key, String value) { + setPayload(key, String.valueOf(value), Payload.ValueType.STRING); + } + + /** + * Sets payload for this drag source to use with acceptance criterion. The + * payload is transferred as data type in the data transfer object in the + * following format: {@code "v-item:integer:key:value"}. The given value is + * compared to the criterion value when the drag source is dragged on top of + * a drop target that has the suitable criterion. + * <p> + * Note that setting payload in Internet Explorer 11 is not possible due to + * the browser's limitations. + * + * @param key + * key of the payload to be transferred + * @param value + * value of the payload to be transferred + * @see DropTargetExtension#setDropCriterion(String, ComparisonOperator, + * int) + */ + public void setPayload(String key, int value) { + setPayload(key, String.valueOf(value), Payload.ValueType.INTEGER); + } + + /** + * Sets payload for this drag source to use with acceptance criterion. The + * payload is transferred as data type in the data transfer object in the + * following format: {@code "v-item:double:key:value"}. The given value is + * compared to the criterion value when the drag source is dragged on top of + * a drop target that has the suitable criterion. + * <p> + * Note that setting payload in Internet Explorer 11 is not possible due to + * the browser's limitations. + * + * @param key + * key of the payload to be transferred + * @param value + * value of the payload to be transferred + * @see DropTargetExtension#setDropCriterion(String, ComparisonOperator, + * double) + */ + public void setPayload(String key, double value) { + setPayload(key, String.valueOf(value), Payload.ValueType.DOUBLE); + } + + private void setPayload(String key, String value, + Payload.ValueType valueType) { + getState().payload.put(key, new Payload(key, value, valueType)); + } + + /** * Set server side drag data. This data is available in the drop event and * can be used to transfer data between drag source and drop target if they * are in the same UI. @@ -322,7 +391,7 @@ public class DragSourceExtension<T extends AbstractComponent> * dragstart event happens on the client side. * * @param listener - * Listener to handle dragstart event. + * Listener to handle dragstart event. * @return Handle to be used to remove this listener. */ public Registration addDragStartListener(DragStartListener<T> listener) { @@ -337,7 +406,7 @@ public class DragSourceExtension<T extends AbstractComponent> * event happens on the client side. * * @param listener - * Listener to handle dragend event. + * Listener to handle dragend event. * @return Handle to be used to remove this listener. */ public Registration addDragEndListener(DragEndListener<T> listener) { @@ -349,7 +418,7 @@ public class DragSourceExtension<T extends AbstractComponent> * Set a custom drag image for the current drag source. * * @param imageResource - * Resource of the image to be displayed as drag image. + * Resource of the image to be displayed as drag image. */ public void setDragImage(Resource imageResource) { setResource(DragSourceState.RESOURCE_DRAG_IMAGE, imageResource); diff --git a/server/src/main/java/com/vaadin/ui/dnd/DropTargetExtension.java b/server/src/main/java/com/vaadin/ui/dnd/DropTargetExtension.java index 1f5c675b21..4cff2545e8 100644 --- a/server/src/main/java/com/vaadin/ui/dnd/DropTargetExtension.java +++ b/server/src/main/java/com/vaadin/ui/dnd/DropTargetExtension.java @@ -15,6 +15,7 @@ */ package com.vaadin.ui.dnd; +import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -23,9 +24,11 @@ import java.util.Objects; import com.vaadin.server.AbstractExtension; import com.vaadin.shared.MouseEventDetails; import com.vaadin.shared.Registration; +import com.vaadin.shared.ui.dnd.criteria.ComparisonOperator; import com.vaadin.shared.ui.dnd.DropEffect; import com.vaadin.shared.ui.dnd.DropTargetRpc; import com.vaadin.shared.ui.dnd.DropTargetState; +import com.vaadin.shared.ui.dnd.criteria.Criterion; import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.dnd.event.DropEvent; import com.vaadin.ui.dnd.event.DropListener; @@ -146,9 +149,13 @@ public class DropTargetExtension<T extends AbstractComponent> /** * Sets a criteria script in JavaScript to allow drop on this drop target. * The script is executed when something is dragged on top of the target, - * and the drop is not allowed in case the script returns {@code false}. If - * no script is set, then the drop is always accepted, if the set - * {@link #setDropEffect(DropEffect) dropEffect} matches the drag source. + * and the drop is not allowed in case the script returns {@code false}. + * <p> + * Drop will be allowed if it passes both this criteria script and the + * criteria set via any of {@code setDropCriterion()} or {@code + * setDropCriteria()} methods. If no criteria is set, then the drop is + * always accepted, if the set {@link #setDropEffect(DropEffect) dropEffect} + * matches the drag source. * <p> * <b>IMPORTANT:</b> Construct the criteria script carefully and do not * include untrusted sources such as user input. Always keep in mind that @@ -157,22 +164,23 @@ public class DropTargetExtension<T extends AbstractComponent> * Example: * * <pre> - * target.setDropCriteria( - * // If dragged source contains a URL, allow it to be dropped - * "if (event.dataTransfer.types.includes('text/uri-list')) {" - * + " return true;" + "}" + + * target.setDropCriterion( + * // If dragged source contains a URL, allow it to be dropped + * "if (event.dataTransfer.types.includes('text/uri-list')) {" + + * " return true;" + + * "}" + * - * // Otherwise cancel the event" - * "return false;"); + * // Otherwise cancel the event + * "return false;"); * </pre> * * @param criteriaScript * JavaScript to be executed when drop event happens or * {@code null} to clear. */ - public void setDropCriteria(String criteriaScript) { - if (!Objects.equals(getState(false).dropCriteria, criteriaScript)) { - getState().dropCriteria = criteriaScript; + public void setDropCriteriaScript(String criteriaScript) { + if (!Objects.equals(getState(false).criteriaScript, criteriaScript)) { + getState().criteriaScript = criteriaScript; } } @@ -182,10 +190,120 @@ public class DropTargetExtension<T extends AbstractComponent> * allowed. * * @return JavaScript that executes when drop event happens. - * @see #setDropCriteria(String) + * @see #setDropCriteriaScript(String) + */ + public String getDropCriteriaScript() { + return getState(false).criteriaScript; + } + + /** + * Set a drop criterion to allow drop on this drop target. When data is + * dragged on top of the drop target, the given value is compared to the + * drag source's payload with the same key. The drag passes this criterion + * if the value of the payload and the value given here are equal. + * <p> + * Note that calling this method will overwrite the previously set criteria. + * To set multiple criteria, call the {@link #setDropCriteria(Criterion.Match, + * Criterion...)} method. + * <p> + * To handle more complex criteria, define a custom script with {@link + * #setDropCriteriaScript(String)}. Drop will be allowed if both this + * criterion and the criteria script are passed. + * + * @param key + * key of the payload to be compared + * @param value + * value to be compared to the payload's value + * @see DragSourceExtension#setPayload(String, String) + */ + public void setDropCriterion(String key, String value) { + setDropCriteria(Criterion.Match.ANY, new Criterion(key, value)); + } + + /** + * Set a drop criterion to allow drop on this drop target. When data is + * dragged on top of the drop target, the given value is compared to the + * drag source's payload with the same key. The drag passes this criterion + * if the value of the payload compared to the given value using the given + * operator holds. + * <p> + * Note that calling this method will overwrite the previously set criteria. + * To set multiple criteria, call the {@link #setDropCriteria(Criterion.Match, + * Criterion...)} method. + * <p> + * To handle more complex criteria, define a custom script with {@link + * #setDropCriteriaScript(String)}. Drop will be allowed if both this + * criterion and the criteria script are passed. + * + * @param key + * key of the payload to be compared + * @param operator + * comparison operator to be used + * @param value + * value to be compared to the payload's value + * @see DragSourceExtension#setPayload(String, int) + */ + public void setDropCriterion(String key, ComparisonOperator operator, + int value) { + setDropCriteria(Criterion.Match.ANY, + new Criterion(key, operator, value)); + } + + /** + * Set a drop criterion to allow drop on this drop target. When data is + * dragged on top of the drop target, the given value is compared to the + * drag source's payload with the same key. The drag passes this criterion + * if the value of the payload compared to the given value using the given + * operator holds. + * <p> + * Note that calling this method will overwrite the previously set criteria. + * To set multiple criteria, call the {@link #setDropCriteria(Criterion.Match, + * Criterion...)} method. + * <p> + * To handle more complex criteria, define a custom script with {@link + * #setDropCriteriaScript(String)}. Drop will be allowed if both this + * criterion and the criteria script are passed. + * + * @param key + * key of the payload to be compared + * @param operator + * comparison operator to be used + * @param value + * value to be compared to the payload's value + * @see DragSourceExtension#setPayload(String, double) + */ + public void setDropCriterion(String key, ComparisonOperator operator, + double value) { + setDropCriteria(Criterion.Match.ANY, + new Criterion(key, operator, value)); + } + + /** + * Sets multiple drop criteria to allow drop on this drop target. When data + * is dragged on top of the drop target, the value of the given criteria is + * compared to the drag source's payload with the same key. + * <p> + * The drag passes these criteria if, depending on {@code match}, any or all + * of the criteria matches the payload, that is the value of the payload + * compared to the value of the criterion using the criterion's operator + * holds. + * <p> + * Note that calling this method will overwrite the previously set + * criteria. + * <p> + * To handle more complex criteria, define a custom script with {@link + * #setDropCriteriaScript(String)}. Drop will be allowed if both this + * criterion and the criteria script are passed. + * + * @param match + * defines whether any or all of the given criteria should match to + * allow drop on this drop target + * @param criteria + * criteria to be compared to the payload */ - public String getDropCriteria() { - return getState(false).dropCriteria; + public void setDropCriteria(Criterion.Match match, Criterion... criteria) { + getState().criteriaMatch = match; + getState().criteria = Arrays.asList(criteria); } /** diff --git a/server/src/main/java/com/vaadin/ui/dnd/event/DragEndEvent.java b/server/src/main/java/com/vaadin/ui/dnd/event/DragEndEvent.java index de0ba64a5e..df71ed0a08 100644 --- a/server/src/main/java/com/vaadin/ui/dnd/event/DragEndEvent.java +++ b/server/src/main/java/com/vaadin/ui/dnd/event/DragEndEvent.java @@ -64,7 +64,7 @@ public class DragEndEvent<T extends AbstractComponent> extends Component.Event { * dragend event. * @see DragSourceExtension#setEffectAllowed(EffectAllowed) * @see DropTargetExtension#setDropEffect(DropEffect) - * @see DropTargetExtension#setDropCriteria(String) + * @see DropTargetExtension#setDropCriteriaScript(String) */ public DropEffect getDropEffect() { return dropEffect; |