vaadinvaadin-flowvaadin21

GridRowDragger in Vaadin 21 missing?


I'd like to use this "Drag and Drop Reorder of Rows in Grid"-code in Vaadin 21: https://demo.vaadin.com/sampler/#ui/drag-drop/grid-reorder-rows-html5

Unfortunately I don't find the com.vaadin.ui.components.grid.GridRowDragger<T> class in Vaadin 21.

Is there any replacement / substitution?


Solution

  • An approach is to use a class that has its own order number. When dropping an item, find the new neighbour items, update order number at all items and re-set them as items in the grid.

    This is working for me with a few hundreds of items in a grid:

        grid.setSelectionMode(SelectionMode.SINGLE);
        grid.setRowsDraggable(true);
        grid.setDropMode(GridDropMode.BETWEEN);
        grid.addDragStartListener(new ComponentEventListener<GridDragStartEvent<MyItem>>() {
            @Override
            public void onComponentEvent(GridDragStartEvent<MyItem> event) {
                draggedItems = event.getDraggedItems();
            }
        });
        grid.addDragEndListener(new ComponentEventListener<GridDragEndEvent<MyItem>>() {
            @Override
            public void onComponentEvent(GridDragEndEvent<MyItem> event) {
                draggedItems = null;
            }
        });
        grid.addDropListener(new ComponentEventListener<GridDropEvent<MyItem>>() {
            @Override
            public void onComponentEvent(GridDropEvent<MyItem> event) {
                if (draggedItems != null) {
                    Optional<MyItem> dropTargetItemOptional = event.getDropTargetItem();
                    if (dropTargetItemOptional.isPresent()) {
                        // Find drop target item
                        MyItem dropTargetItem = dropTargetItemOptional.get();
                        int dropTargetIndex = getIndexOf(dropTargetItem);
    
                        // Increase order number at all following items
                        int dropTargetOrder = dropTargetItem.getOrderNumber();
                        int offset = draggedItems.size() + 1;
                        boolean droppedAboveTargetItem = event.getDropLocation() == GridDropLocation.ABOVE;
                        int numberOfItems = myItems.size();
                        for (int i = dropTargetIndex + (droppedAboveTargetItem ? 0 : 1); i < numberOfItems; i++) {
                            myItems.get(i)
                                    .setOrderNumber(dropTargetOrder + i - dropTargetIndex + offset);
                        }
    
                        // Update order number at dragged items
                        int i = 1;
                        for (MyItem item : draggedItems) {
                            item.setOrderNumber(dropTargetOrder + i);
                            i++;
                        }
                        // Sort (and re-number) all items
                        sortByOrder(myItems);
                        grid.setItems(myItems);
                    }
                }
                draggedItems = null;
            }
        });