Button in a FieldGroup?

I have an Entity A that has an attribute/field that is itself a pretty complex entity (B).

For the field I want to display text that says the name of the field and then a button that says something like “Click here to examine B” and it will pop up B’s edit page.

How can I do this with a custom field in a FieldGroup? The issue is that if I do it with a label and a button outside the field group, it doesn’t line up well.

I should have mentioned there’s a one-to-one relationship between A and B. If A gets deleted, B should get deleted as well. If B gets deleted, A should not get deleted.

Anyway, PickerField would be the right field except since there’s only one, there’s no lookup/picking to be done.

Also, if B doesn’t already exist, how can I get the lookup action to create it?

Hi,

First of all, if you need only one action in PickerField, just tune actions set. Let say we have Client entity with a reference field - manager, that is assigned automatically while creating a record of Client:


public class ClientEdit extends AbstractEditor<Client> {
    @Named("fieldGroup.manager")
    private PickerField managerField;
    @Inject
    private UserSessionSource userSessionSource;

    @Override
    public void init(Map<String, Object> params) {
        super.init(params);

        managerField.removeAllActions();
        managerField.addOpenAction();
    }

    @Override
    protected void initNewItem(Client item) {
        super.initNewItem(item);
        item.setManager(userSessionSource.getUserSession().getUser());
    }
}

Here we inject instance of PickerField from a field group and on init stage we change actions set, just add OpenAction.

If this approach does not suit your needs you can always create a composite custom field. We set name of a method that will generate custom field to generator attribute of a field:


<fieldGroup id="fieldGroup"
            datasource="clientDs">
    <column width="250px">
        <field id="title"/>
        <field id="manager" generator="createLabelButtonField"/>
    </column>
</fieldGroup>

We will create custom component in that method inside of controller:


public class ClientEdit extends AbstractEditor<Client> {
    @Inject
    private UserSessionSource userSessionSource;
    @Inject
    private ComponentsFactory componentsFactory;

    @Override
    protected void initNewItem(Client item) {
        super.initNewItem(item);
        item.setManager(userSessionSource.getUserSession().getUser());
    }

    public Component createLabelButtonField(Datasource<Client> datasource, String fieldId) {
        // Inject and use componentsFactory if you need to create components programmatically
        HBoxLayout layout = componentsFactory.createComponent(HBoxLayout.class);
        layout.setWidthFull();

        Label label = componentsFactory.createComponent(Label.class);
        label.setAlignment(Alignment.MIDDLE_LEFT);
        layout.add(label);
        layout.expand(label);

        Button openBtn = componentsFactory.createComponent(Button.class);
        openBtn.setAction(new AbstractAction("Open") {
            @Override
            public void actionPerform(Component component) {
                showNotification("Your logic here!");
            }
        });
        layout.add(openBtn);

        // When item is set we update label
        datasource.addItemChangeListener(e -> {
            if (e.getItem() != null)
                label.setValue(e.getItem().getManager());
        });
        return layout;
    }
}