EditAction

EditAction is a list action designed to edit entity instances. It opens the entity edit screen with the entity instance selected in the UI component. After the instance is saved to the database by the edit screen, the action updates it in the data container of the UI component.

The action is implemented by the io.jmix.ui.action.list.EditAction class and should be defined in XML using type="edit" action’s attribute. You can configure common action parameters using XML attributes of the action element. See Declarative Actions for details. Below we describe parameters specific to the EditAction class.

Properties

The following parameters can be set both in XML and in Java:

  • openMode - the editor screen opening mode as a value of the OpenMode enum: NEW_TAB, DIALOG, etc. By default, EditAction opens the editor in THIS_TAB mode.

  • screenId - string id of the editor screen to use. By default, EditAction uses either a screen, annotated with @PrimaryEditorScreen, or having identifier in the format of <entity_name>.edit, for example, demo_Customer.edit.

  • screenClass - Java class of the editor screen controller to use. It has a higher priority than screenId.

For example, if you want to open a specific editor screen as a dialog, you can configure the action in XML:

<action id="edit" type="edit">
    <properties>
        <property name="openMode" value="DIALOG"/>
        <property name="screenClass" value="ui.ex1.screen.entity.customer.CustomerEdit"/>
    </properties>
</action>

Alternatively, you can inject the action into the screen controller and configure it using setters:

@Named("customersGroupTable.edit")
private EditAction<Customer> editAction;

@Subscribe
public void onInit(InitEvent event) {
    editAction.setOpenMode(OpenMode.DIALOG);
    editAction.setScreenClass(CustomerEdit.class);
}

Handlers

Now let’s consider parameters that can be configured only in Java code. To generate correctly annotated method stubs for these parameters, use Studio.

screenOptionsSupplier

It is a handler that returns ScreenOptions object to be passed to the opened editor screen. For example:

@Install(to = "custTable.edit", subject = "screenOptionsSupplier")
private ScreenOptions custTableEditScreenOptionsSupplier() {
    return new MapScreenOptions(ParamsMap.of("someParameter", 10));
}

The returned ScreenOptions object will be available in InitEvent of the opened screen.

screenConfigurer

It is a handler that accepts the editor screen and can initialize it before opening. For example:

@Install(to = "custTable.edit", subject = "screenConfigurer")
private void custTableEditScreenConfigurer(Screen screen) {
    ((CustomerEdit) screen).setSomeParameter(10);
}

Note that screen configurer comes into play when the screen is already initialized but not yet shown, that is, after its InitEvent and AfterInitEvent and before BeforeShowEvent are sent.

transformation

It is a handler that is invoked after the entity is selected and validated in the editor screen. It accepts the selected entity. You can use this handler to transform the committed entity before setting it to the target data container. For example:

@Install(to = "custTable.edit", subject = "transformation")
private Customer custTableEditTransformation(Customer customer) {
    return reloadCustomer(customer);
}

afterCommitHandler

It is a handler that is invoked after the edited entity instance is committed in the editor screen. It accepts the updated entity. For example:

@Install(to = "custTable.edit", subject = "afterCommitHandler")
private void custTableEditAfterCommitHandler(Customer customer) {
    System.out.println("Updated " + customer);
}

afterCloseHandler

It is a handler that is invoked after the editor screen is closed. AfterCloseEvent is passed to the handler. For example:

@Install(to = "custTable.edit", subject = "afterCloseHandler")
private void custTableEditAfterCloseHandler(AfterCloseEvent afterCloseEvent) {
    if (afterCloseEvent.closedWith(StandardOutcome.COMMIT)) {
        System.out.println("Committed");
    }
}

Using ActionPerformedEvent

If you want to perform some checks or interact with the user before the action is executed, subscribe to the action’s ActionPerformedEvent and invoke the execute() method of the action when needed. The action will be invoked with all parameters that you defined for it. In the example below, we show a confirmation dialog before executing the action:

@Named("custTable.edit")
private EditAction<Customer> custTableEdit;

@Subscribe("custTable.edit")
public void onCustTableEdit(Action.ActionPerformedEvent event) {
    dialogs.createOptionDialog()
            .withCaption("Please confirm")
            .withMessage("Do you really want to edit the customer?")
            .withActions(
                    new DialogAction(DialogAction.Type.YES)
                            .withHandler(e -> custTableEdit.execute()), // execute action
                    new DialogAction(DialogAction.Type.NO)
            )
            .show();
}

You can also subscribe to ActionPerformedEvent, and instead of invoking the action’s execute() method, use ScreenBuilders API directly to open the edit screen. In this case, you are ignoring all specific action parameters and behavior and using only its common parameters like caption, icon, etc. For example:

@Autowired
private ScreenBuilders screenBuilders;

@Subscribe("customersTable.edit")
public void onCustomersTableEdit(Action.ActionPerformedEvent event) {
    screenBuilders.editor(customersTable)
            .withOpenMode(OpenMode.DIALOG)
            .withScreenClass(CustomerEdit.class)
            .withAfterCloseListener(afterScreenCloseEvent -> {
                if (afterScreenCloseEvent.closedWith(StandardOutcome.COMMIT)) {
                    Customer committedCustomer = (afterScreenCloseEvent.getScreen()).getEditedEntity();
                    System.out.println("Updated " + committedCustomer);
                }
            })
            .build()
            .show();
}