TagLookupAction

TagLookupAction is a lookup action designed to select entity instances from a lookup screen and set it to the tag picker.

The action is implemented by the io.jmix.ui.action.tagpicker.TagLookupAction class and should be defined in XML using type="tag_lookup" 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 TagLookupAction class.

Properties

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

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

  • screenId - string id of the lookup screen to use. By default, TagLookupAction uses either a screen, annotated with @PrimaryLookupScreen, or having identifier in the format of <entity_name>.browse, for example, demo_Customer.browse.

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

  • multiSelect - whether to enable multiselect in the lookup screen. The default value is true.

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

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

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

@Named("customerTagPicker.tagLookup")
private TagLookupAction<Customer> tagLookupAction;

@Subscribe
public void onInit(InitEvent event) {
    tagLookupAction.setOpenMode(OpenMode.DIALOG);
    tagLookupAction.setScreenClass(CustomerBrowse.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 the ScreenOptions object to be passed to the opened lookup screen. For example:

@Install(to = "customerTagPicker.tagLookup", subject = "screenOptionsSupplier")
private ScreenOptions customerTagPickerTagLookupScreenOptionsSupplier() {
    return new MapScreenOptions(ParamsMap.of("someParameter", 10));
}

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

screenConfigurer

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

@Install(to = "customerTagPicker.tagLookup", subject = "screenConfigurer")
private void customerTagPickerTagLookupScreenConfigurer(Screen screen) {
    ((CustomerBrowse) 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.

selectValidator

It is a handler that is invoked when the user clicks Select in the lookup screen. It accepts the object that contains the collection of selected entities. The first item of the collection is set to the field. You can use this handler to check if the selection matches some criteria. The handler must return true to proceed and close the lookup screen. For example:

@Install(to = "customerTagPicker.tagLookup", subject = "selectValidator")
private boolean customerTagPickerTagLookupSelectValidator(LookupScreen.ValidationContext<Customer> validationContext) {
    boolean valid = validationContext.getSelectedItems().size() == 1;
    if (!valid) {
        notifications.create().withCaption("Select a single customer").show();
    }
    return valid;
}

transformation

It is a handler that is invoked after entities are selected and validated in the lookup screen. It accepts the collection of selected entities. The first item of the collection is set to the field. You can use this handler to transform the selection before setting the entity to the field. For example:

@Install(to = "customerTagPicker.tagLookup", subject = "transformation")
private Collection<Customer> customerTagPickerTagLookupTransformation(Collection<Customer> collection) {
    return reloadCustomers(collection);
}

afterCloseHandler

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

@Install(to = "customerTagPicker.tagLookup", subject = "afterCloseHandler")
private void customerTagPickerTagLookupAfterCloseHandler(AfterCloseEvent afterCloseEvent) {
    if (afterCloseEvent.closedWith(StandardOutcome.SELECT)) {
        System.out.println("Selected");
    }
}

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:

@Subscribe("customerTagPicker.tagLookup")
public void onCustomerTagPickerTagLookup(Action.ActionPerformedEvent event) {
    dialogs.createOptionDialog()
            .withCaption("Please confirm")
            .withMessage("Do you really want to select a customer?")
            .withActions(
                    new DialogAction(DialogAction.Type.YES)
                            .withHandler(e -> tagLookupAction.execute()), (1)
                    new DialogAction(DialogAction.Type.NO)
            )
            .show();
}
1 Execute action

You can also subscribe to ActionPerformedEvent, and instead of invoking the action’s execute() method, use ScreenBuilders API directly to open the lookup 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;

@Autowired
private TagPicker<Customer> customerTagPicker;

@Subscribe("customerTagPicker.tag")
public void onCustomerTagPickerTag(Action.ActionPerformedEvent event) {
    screenBuilders.lookup(customerTagPicker)
            .withOpenMode(OpenMode.DIALOG)
            .withScreenClass(CustomerBrowse.class)
            .withSelectValidator(customerValidationContext -> {
                boolean valid = customerValidationContext.getSelectedItems().size() == 1;
                if (!valid) {
                    notifications.create().withCaption("Select a single customer").show();
                }
                return valid;

            })
            .build()
            .show();
}