How to implement a three dot menu in cuba platform?

402 Views Asked by At

How can I implement a vertical three dot menu in every table row, like here in this picture?

enter image description here

1

There are 1 best solutions below

0
glebfox On

CUBA.platform has no built-in component that provides context menu on button click, but it can be easily implemented using Vaadin ContextMenu class.

The main concept is as follows:

  1. unwrap Vaadin component:
CubaButton vButton = button.unwrap(CubaButton.class);
  1. create a context menu for this component and add menu items:
ContextMenu contextMenu = new ContextMenu(vButton, true);

contextMenu.addItem("Item", (MenuBar.Command) selectedItem -> {
   // handle menu item click
});
...
  1. show the context menu programmatically on button click:
vButton.setClickHandler(clickEvent ->
        contextMenu.open(clickEvent.getClientX(), clickEvent.getClientY()));

You can use this approach in the generated table column. Let's assume that we need a single-column table that displays all the data.

XML definition

<table id="usersTable"
       dataContainer="usersDc"
       columnHeaderVisible="false"
       stylename="no-stripes"
       width="250px"
       height="400px">
    <columns>
        <column id="column"/>
    </columns>
    <buttonsPanel>
        <button caption="Share" icon="USER_PLUS" stylename="borderless"/>
        <button caption="Preview" icon="EYE" stylename="borderless"/>
    </buttonsPanel>
</table>

Java Controller

@UiController("demo_Sandbox")
@UiDescriptor("sandbox.xml")
public class Sandbox extends Screen {

    @Inject
    private UiComponents uiComponents;
    @Inject
    private Notifications notifications;
    @Inject
    private MetadataTools metadataTools;

    @Install(to = "usersTable.column", subject = "columnGenerator")
    private Component usersTableColumnColumnGenerator(User user) {
        HBoxLayout rootLayout = uiComponents.create(HBoxLayout.class);
        rootLayout.setMargin(new MarginInfo(true, false, true, false));
        rootLayout.setSpacing(true);
        rootLayout.setWidthFull();

        VBoxLayout content = uiComponents.create(VBoxLayout.class);
        content.setSpacing(true);

        Label<String> login = uiComponents.create(Label.TYPE_STRING);
        login.setValue("Login: " + user.getLogin());

        Label<String> name = uiComponents.create(Label.TYPE_STRING);
        name.setValue("Name: " + user.getName());

        content.add(login, name);

        LinkButton contextMenu = uiComponents.create(LinkButton.class);
        contextMenu.setIconFromSet(CubaIcon.ELLIPSIS_V);
        contextMenu.setAlignment(Alignment.TOP_RIGHT);
        setupContextMenu(contextMenu, user);

        rootLayout.add(content, contextMenu);

        return rootLayout;
    }

    private void setupContextMenu(LinkButton button, User user) {
        CubaButton vButton = button.unwrap(CubaButton.class);

        ContextMenu contextMenu = new ContextMenu(vButton, true);
        addMenuItem(contextMenu, "Rename", user);
        addMenuItem(contextMenu, "Delete", user);
        addMenuItem(contextMenu, "Open", user);

        vButton.setClickHandler(clickEvent ->
                contextMenu.open(clickEvent.getClientX(), clickEvent.getClientY()));
    }

    private void addMenuItem(ContextMenu contextMenu, String caption, User user) {
        contextMenu.addItem(caption, (MenuBar.Command) selectedItem ->
                notifications.create()
                        .withCaption(caption + ": " + metadataTools.getInstanceName(user))
                        .show());
    }
}

The result

enter image description here