Fragments with actions in Jmix 2.3.0-RC1

I’ve been testing fragments in Jmix 2.3.0-RC1 (with 2.3.NIGHTLY1357-241 plugin). I’m having difficulty with actions. In my fragment descriptor, I’ve created an action that is used by several buttons:

<fragment xmlns="http://jmix.io/schema/flowui/fragment">
    <content>
        <vbox id="root">
            <hbox>
                <button id="fragBtn1" action="fragmentAction" text="fragment button 1"/>
                <button id="fragBtn2" action="fragmentAction" text="fragment button 2"/>
                <button id="fragBtn3" action="fragmentAction" text="fragment button 3"/>
            </hbox>
        </vbox>
    </content>
    <actions>
        <action id="fragmentAction"/>
    </actions>
</fragment>

In my controller, I’ve coded an event handler and need to determine the id of the button that has been clicked:

@Subscribe("fragmentAction")
protected void onFragmentAction(final ActionPerformedEvent event) {
    if (event.getComponent().getId().isPresent()) {
        String btnId = event.getComponent().getId().get();
        notifications.show("fragment button pressed: ".concat(btnId));
    } else {
        notifications.show("fragment button was pressed but no id available");
    }
}

Although the handler detects the button click, I’m unable to retrieve the id of the button. This does work properly from a regular view. It also worked with fragments in Jmix 1.x. Using the debugger, I can determine the button that was clicked but not via a public method.

I’ve attached a sample project that shows the behavior of both a list view and a fragment. Is there any chance this could be fixed for the official 2.3.0 release, or am I simply doing something wrong in attempting to retrieve the id of the button?

Thanks!
FragmentAction.zip (109.6 KB)

Hi!

The components located inside the fragment don’t have actual IDs.
This limitation is due to the fact that the fragment can be integrated into any views. These views may have components with IDs that overlap with the components IDs in the fragment.

To solve this problem, a hidden ID feature was implemented.
You can read about this in the brief fragment documentation: Fragments (#841) by glebfox · Pull Request #3336 · jmix-framework/jmix · GitHub

Specifics of defining a layout in XML

To avoid id duplicates in components tree when several fragments of the same type is used simultaneously or fragment inner components have the same id as other components in the components tree, the value of id attribute of each component defined in fragment descriptor (so called fragment id or Shadow XML id) is stored in the component Attributes field instead of setting it as actual id using Component. setId(String).

To work with ID you must use the following API:

  • FragmentUtils.getComponentId(Component) - to get component ID
  • fragmentInstance.findInnerComponent(String) / fragmentInstance.getInnerComponent() - to find/get the inner component with given fragment ID

These methods search among components added via an XML-descriptor only

Best regards,
Dmtriy

Thank you! That is precisely the information I needed.

For anyone following this, FragmentUtils.getComponentId(event.getComponent()) provides the Optional<String> I needed in my code. Although it’s not mentioned in the Jmix documentation yet, FragmentUtils is well documented in the 2.3 API.