Vaadin 23 TreeGrid drag and drop filter dependent on the dragged item

HI. I would liek the drop target filter to be dependent on the item that is being dragged. So in the example person-manager at https://vaadin.com/docs/v23/components/grid/#drag-and-drop the manager should not be able to be dragged into another manager, only be reordered. It seems that the behaviour of the drop filter has changed from V14 in that the drop filter is executed at creation time and not after the drag has started.
Any ideas on how toi do a dynamic filter so that the allowable drop targets depending on the type of dragged item?

You can call setDropFilter in the addDragStartListener

I tried that and it sents the filter correctly for the first type, but then when trying to drag a different type the filter does not work. So it looks like it can only be set once. I cant see a way to remove it either.

I’m pretty sure it works fine, at least the last time I tried it.

Let me try again and see if there is some other issue on the second drag…

To reset the dropFilter, just call setDropFilter(item -> true)

that’s the default drop filter

The problem appears to be that the addDragStartListener is called only on the first drag and then subsequent drag attempts it is not called at all.

Just double checked, it works fine for me with 24.0.5

    public static class Item {
        int i;
        public Item(int i) {
            this.i = i;
        }
    }

    public MainView() {
        setSizeFull();

        var items = new ArrayList<Item>();
        for (int i = 0; i < 100; i++) {
            items.add(new Item(i));
        }

        var grid = new Grid<Item>();
        grid.setSelectionMode(Grid.SelectionMode.NONE);
        grid.setDropMode(GridDropMode.ON_TOP);
        grid.setRowsDraggable(true);
        grid.setItems(items);
        grid.addComponentColumn(item -> new Label(String.valueOf(item.i)));
        grid.addDragStartListener(event -> {
            var item1 = event.getDraggedItems().stream().findFirst().orElse(null);
            grid.setDropFilter(item2 -> item1.i % 2 != item2.i % 2);
        });
        add(grid);
    }

if you grab an item with an even index, you can only drag to odd indexes and vice versa

you can add

        grid.setDropFilter(item -> false);
        grid.addDragEndListener(event -> grid.setDropFilter(item -> false));

to make sure the drop filter is reset

After some more testing/logging I was wrong and the addDragStartListener is being called on each drag attempt. It is the drop filter that is not being changed. In your test can you switch your logic around on a second call. Or call a different drop filter on each call.

In my end drag listener I set grid.setDropFilter(item → true); // reset the drop filter
and that also doesnt change anything.

I’m sorry but without more context I can’t help you further. As I demonstrated, it works fine the way I used it

There must be some side effects of your code

I’m not saying there isn’t a underlying vaadin issue, but I can’t reproduce it if it exists

Can you please try switch your logic around. So on each alternate call you can drag and drop on even/odd items. So on the first calkl you can drag even onto odd, and the second call you can only drag odd onto odd.

like this?

        grid.addDragStartListener(event -> {
            var item1 = event.getDraggedItems().stream().findFirst().orElse(null);
            grid.setDropFilter(item2 -> evenOntoOdd == (item1.i % 2 != item2.i % 2));
            evenOntoOdd = !evenOntoOdd;
        });
        grid.setDropFilter(item -> false);
        grid.addDragEndListener(event -> grid.setDropFilter(item -> false));

It works fine. Can you provide an example what you think should work but doesn’t?