Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grid elements created with LitRenderer or ComponentRenderer cannot be used to drag and drop #6306

Closed
borjab opened this issue May 20, 2024 · 4 comments

Comments

@borjab
Copy link

borjab commented May 20, 2024

Description

When I drag from components created as ValueProvider I can drag and drop normally. However, any element created using either LitRenderer or ComponentRenderer do not work.

Debugging, I see that there is no DragStartListener event triggered.

Expected outcome

I would expect the object to be draggable. That is, every time that I start to drag an image there should be a call to this lambda:
grid.addDragStartListener { e -> draggedItem = e.draggedItems[0] }

Minimal reproducible example

We have a live example in the Vaadin grid documentation when the img cannot be used to drag and drop.

package com.vaadin.demo.component.grid;

import com.vaadin.demo.domain.DataService;
import com.vaadin.demo.domain.Person;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.dataview.GridListDataView;
import com.vaadin.flow.component.grid.dnd.GridDropLocation;
import com.vaadin.flow.component.grid.dnd.GridDropMode;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.data.renderer.LitRenderer;
import com.vaadin.flow.data.renderer.Renderer;
import com.vaadin.flow.router.Route;

import java.util.ArrayList;
import java.util.List;

@Route("grid-row-reordering")
public class GridRowReordering extends Div {

    private Person draggedItem;

    public GridRowReordering() {
        Grid<Person> grid = setupGrid();
        List<Person> people = new ArrayList<>(DataService.getPeople());
        GridListDataView<Person> dataView = grid.setItems(people);
        grid.setDropMode(GridDropMode.BETWEEN);
        grid.setRowsDraggable(true);

        grid.addDragStartListener(
                e -> draggedItem = e.getDraggedItems().get(0));

        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);
        add(grid);
    }

    private static Grid<Person> setupGrid() {
        Grid<Person> grid = new Grid<>(Person.class, false);
        
        // This column won't work
        grid.addColumn(createAvatarRenderer()).setHeader("Image");
                
        // This column will work
        grid.addColumn(Person::getFirstName).setHeader("First name");
        return grid;
    }

    private static Renderer<Person> createAvatarRenderer() {
        return LitRenderer.<Person> of(
                "<vaadin-avatar img=\"${item.pictureUrl}\" name=\"${item.fullName}\" alt=\"User avatar\"></vaadin-avatar>")
                .withProperty("pictureUrl", Person::getPictureUrl);
    }
}



Steps to reproduce

Use one example like the live one with documentation. Try to drag & drop using the image. It won't work. Now use the name. It will work as expected

Environment

Vaadin version(s): 24.3.12
OS: Linux (dockerized)

Browsers

Chrome

@tomivirkki
Copy link
Member

tomivirkki commented May 21, 2024

Hi @borjab
The issue seems to be not about the renderers specifically but about using an avatar inside the grid rows. When you start dragging by it, you're actually dragging the avatar's image element, and not the grid row. This should be fixed in grid (or avatar), but as a workaround you can try the following CSS:

vaadin-grid vaadin-avatar {
  pointer-events: none
}

@borjab
Copy link
Author

borjab commented May 21, 2024

Hi @tomivirkki

The workaround works as charm. Not only for images but also for other components like Urls using the Anchor element.

Thank you very much for the help.

P.S: I assume from you comment that I should leave the bug open

@tomivirkki
Copy link
Member

I'm glad it worked. Let's leave this issue open so we can properly fix the bug in the components. It should be possible to render avatars etc in the grid cells without having to use workarounds.

@tomivirkki
Copy link
Member

Closed by vaadin/web-components#7431 and vaadin/docs#3444

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants