Docs

Documentation versions (currently viewingVaadin 24)

Grid

Grid supports drag-and-drop actions. This feature might be used, for example, to reorder rows and to drag rows between grids.

Drop Mode

The drop mode of a grid determines where a drop can happen. Vaadin offers four different drop modes, which are described in the table here:

Drop Mode Description

On Grid

Drops can occur on the grid as a whole, not on top of rows or between individual rows. Use this mode when the order isn’t important.

Between

Drops can happen between rows. Use this mode when the order is important.

On Top

Drops can take place on top of rows. This is useful when creating relationships between items or moving an item into another item, such as placing a file inside a folder.

On Top or Between

Drops can occur on top of rows or between them.

Row Reordering

You can drag rows to reorder them. This can be a useful and impressive feature for users. Try dragging with your mouse one of the rows of data in the example here to another place in the list.

Open in a
new tab
Grid<Person> grid = setupGrid();

// Modifying the data view requires a mutable collection
List<Person> people = new ArrayList<>(DataService.getPeople());
GridListDataView<Person> dataView = grid.setItems(people);

grid.setRowsDraggable(true);

grid.addDragStartListener(e -> {
    draggedItem = e.getDraggedItems().get(0);
    grid.setDropMode(GridDropMode.BETWEEN);
});

grid.addDropListener(e -> {
    Person targetPerson = e.getDropTargetItem().orElse(null);
    GridDropLocation dropLocation = e.getDropLocation();

    boolean personWasDroppedOntoItself = draggedItem
            .equals(targetPerson);

    if (targetPerson == null || personWasDroppedOntoItself)
        return;

    dataView.removeItem(draggedItem);

    if (dropLocation == GridDropLocation.BELOW) {
        dataView.addItemAfter(draggedItem, targetPerson);
    } else {
        dataView.addItemBefore(draggedItem, targetPerson);
    }
});

grid.addDragEndListener(e -> {
    draggedItem = null;
    grid.setDropMode(null);
});

Drag Rows between Grids

Rows can be dragged from one grid to another. You might use this feature to move, copy or link items from different datasets.

In the example here, there are two grids of data. Maybe they represent people to speak at two different presentations at the same conference. One grid lists the first panel of speakers and the other the second panel. Try dragging people from one to the other, as if you were reassigning them to speak at a different panel.

Open in a
new tab
Grid<Person> grid1 = setupGrid();
Grid<Person> grid2 = setupGrid();

GridListDataView<Person> dataView1 = grid1.setItems(people1);
GridListDataView<Person> dataView2 = grid2.setItems(people2);

grid1.setRowsDraggable(true);
grid1.addDragStartListener(e -> {
    draggedItem = e.getDraggedItems().get(0);
    grid1.setDropMode(GridDropMode.ON_GRID);
    grid2.setDropMode(GridDropMode.ON_GRID);
});
grid1.addDropListener(e -> {
    dataView2.removeItem(draggedItem);
    dataView1.addItem(draggedItem);
});
grid1.addDragEndListener(e -> {
    draggedItem = null;
    grid1.setDropMode(null);
    grid2.setDropMode(null);
});

grid2.setRowsDraggable(true);
grid2.addDragStartListener(e -> {
    draggedItem = e.getDraggedItems().get(0);
    grid1.setDropMode(GridDropMode.ON_GRID);
    grid2.setDropMode(GridDropMode.ON_GRID);
});
grid2.addDropListener(e -> {
    dataView1.removeItem(draggedItem);
    dataView2.addItem(draggedItem);
});
grid2.addDragEndListener(e -> {
    draggedItem = null;
    grid1.setDropMode(null);
    grid2.setDropMode(null);
});

Drag & Drop Filters

Drag-and-drop filters determine which rows are draggable and which rows are valid drop targets. These filters function on a per-row basis.

Open in a
new tab
TreeGrid<Person> treeGrid = setupTreeGrid();

TreeData<Person> treeData = new TreeData<>();
treeData.addItems(managers, this::getStaff);
TreeDataProvider<Person> treeDataProvider = new TreeDataProvider<>(
        treeData);
treeGrid.setDataProvider(treeDataProvider);
treeGrid.setRowsDraggable(true);
treeGrid.setDropMode(GridDropMode.ON_TOP);

// Only allow dragging staff
treeGrid.setDragFilter(person -> !person.isManager());
// Only allow dropping on managers
treeGrid.setDropFilter(person -> person.isManager());

treeGrid.addDragStartListener(e -> {
    draggedItem = e.getDraggedItems().get(0);
});

treeGrid.addDropListener(e -> {
    Person newManager = e.getDropTargetItem().orElse(null);
    boolean isSameManager = newManager != null
            && newManager.getId().equals(draggedItem.getManagerId());

    if (newManager == null || isSameManager)
        return;

    draggedItem.setManagerId(newManager.getId());
    treeData.setParent(draggedItem, newManager);

    treeDataProvider.refreshAll();
});

treeGrid.addDragEndListener(e -> {
    draggedItem = null;
});