Documentation

Documentation versions (currently viewingVaadin 23)

You are viewing documentation for Vaadin 23. View latest documentation

Creating a Drop Target

Make any component a drop target that the user can drop things on to.

With the DropTarget class, you can make any component a drop target that the user can drop things on to. When the drop occurs, you can get an event on the server side and get the data related to the drag operation when the drag originates from the same UI (browser window/tab). The DropTarget class is a configuration object for the drop target and contains static methods for configuring the given component as a drop target instance.

VerticalLayout first = new VerticalLayout();
VerticalLayout second = new VerticalLayout();

// Make the first layout an active drop target
DropTarget<VerticalLayout> dropTarget = DropTarget.create(first);

// Provide access to drop target API for second layout,
// without setting it as an active drop target.
DropTarget<VerticalLayout> dropTarget2 = DropTarget.configure(second);

// Change previously set settings
dropTarget2.setDropEffect(DropEffect.NONE);

The DropTarget configuration object doesn’t itself store any data, as it’s an API extension that only facilitates making any component a drop target. Creating a new DropTarget instance of a component doesn’t reset any previous configuration, but any changes override the previous configuration.

Similarly to the DragSource, the DropTarget is a "mix-in interface" that can be added to any custom component to expose the drop target API for it.

public class Column extends VerticalLayout implements DropTarget<VerticalLayout> {

    public Column() {
        // Allow drops by default
        setActive(true);
    }

    // All drop target methods have default implementations
}

Reacting to Drops

When the user performs a valid drop on the browser, the DropEvent is fired. You can listen to the event with a DropListener. If the drag originated from within the same Vaadin UI, you can retrieve the dragged component or the assigned business data from the DropEvent.

Div box = new Div();
box.setWidth("300px");
box.setHeight("300px");

DropTarget<Div> dropTarget = DropTarget.create(box);

dropTarget.addDropListener(event -> {
    // move the dragged component to inside the drop target component
    if (event.getDropEffect() == DropEffect.MOVE) {
        // the drag source is available only if the dragged component is from
        // the same UI as the drop target
        event.getDragSourceComponent().ifPresent(box::add);

        event.getDragData().ifPresent(data -> {
            // the server side drag data is available if it has been set and the
            // component was dragged from the same UI as the drop target
        });
    }
});

You can read more about setting the server-side drag data from the previous chapter, Drag Source. At the moment, there is no way to retrieve any client-side drag data from the drop event.

Controlling the Drop with Drop Effect

The DropEffect set for the drop target needs to match the effectAllowed set for the drag operation in order for the drop to succeed.

The drop effect is determined in priority order by:

  • the desired action dropEffect set by the drop target;

  • the effectAllowed set for the drag source;

  • the modifier keys the user presses and holds when dropping.

This means that not setting a drop effect for a drop target allows either the drag source or the user to determine the drop effect. The possible values for the drop effect are: COPY, MOVE, LINK and NONE. Setting the drop effect to NONE means that the drop can’t occur, and thus no DropEvent is fired.

Note
Drop effect on Edge and Safari
If the drop effect set for the drop target doesn’t match the effectAllowed of the drag source, it does not prevent drop on Edge and Safari. For FireFox and Chrome, the drop is prevented when the properties don’t match. Edge and Safari allow the drop but don’t prevent the drop on the DragEnd event.

Drop Target Styling

When there is a valid drag over the drop target, the drop target element receives the v-drag-over-target class name automatically while the dragged object stays over the drop target. The class name is removed when:

  • the drop occurs, or

  • the drop is canceled, or

  • the object is moved outside the drop target.

.v-drag-over-target.card {
    outline: 1px solid lightgreen;
}

Depending on the desired user experience, you might consider highlighting the possible drop targets for a started drag during the DragStart event. See an example of this in the DragSource documentation.

B1B0660B-88EE-401D-B94C-F03FE4A60D9A