Different visual component for reading and editing

Hi

We have an embedded entity PaymentTermRule that aggregates infos on payment terms : delay in days, end of month or quarter, which day of month, from invoice or command.

We would like to present it as a one-liner text field like this : “payment 30 days from invoice, end of month”, and when user wants to edit it, we want to replace the text field with 4 visual components to be edited separately.

What is the best way to do that with CUBA ?

NB : we do not want to create a screen for 4 fields.

Mike

Hi Mike,

How do you see the user will switch to editing? Clicking a button near the text?

Ideally when user clicks on the field/label or when tabulation reaches it, but if this is not possible a button will do the job.

A straightforward solution would be a frame dynamically showing and hiding components. What do you think?

Interesting, I guess you will define the frame as a custom component in the field group. Would you care to share a code sample for the frame ?

In fact that could help us solve another problem that we have currently only a partial solution for.

Here it is: GitHub - cuba-labs/frame-in-fieldgroup

There is AddressFrame that receives a datasource and shows/hides viewing and editing controls:

public class AddressFrame extends AbstractFrame {

    @WindowParam
    private Datasource<Address> datasource;

    @Inject
    private TextField cityField;
    @Inject
    private HBoxLayout fieldsBox;
    @Inject
    private Label label;
    @Inject
    private HBoxLayout labelBox;
    @Inject
    private TextField line1Field;
    @Inject
    private TextField line2Field;
    @Inject
    private TextField zipField;

    @Override
    public void init(Map<String, Object> params) {
        Address address = datasource.getItem();
        label.setValue(address.getLine1() + " " + address.getLine2() + " " + address.getCity() + " " + address.getZip());

        line1Field.setDatasource(datasource, "line1");
        line2Field.setDatasource(datasource, "line2");
        cityField.setDatasource(datasource, "city");
        zipField.setDatasource(datasource, "zip");
    }

    public void onEditBtnClick() {
        labelBox.setVisible(false);
        fieldsBox.setVisible(true);
    }
}

And PersonEdit which opens the frame programmatically passing the datasource, and inserts it into a fieldgroup as a custom field:

public class PersonEdit extends AbstractEditor<Person> {

    @Inject
    private FieldGroup fieldGroup;

    @Inject
    private ComponentsFactory componentsFactory;

    @Inject
    private Datasource<Address> addressDs;

    @Override
    protected void postInit() {
        VBoxLayout placeholder = componentsFactory.createComponent(VBoxLayout.class);
        openFrame(placeholder, "address-frame", ParamsMap.of("datasource", addressDs));
        fieldGroup.getField("address").setComponent(placeholder);
    }
}

Hope it helps.

Thanks Konstantin. This solution will have us create a frame for each case, but that’s a start.