Working example of action button

Hi, I have a standard, working, entity browser screen, generated by the platform.

Now, I need to add a button on the browser screen, that performs an action (instantiate a class and call some methods in it) based on the values of the selected row. I searched the documentation and the live examples, it is clear how to define buttons and actions, but I was not able to understand how to wire it in the existing screen definition and how to have access to the table with the displayed rows.

Any hint or pointer? A simple, but complete working example, including not only the button and action definitions but also the other affected elements, would be very useful.

Many thanks

Table with action and button:

...
<groupTable id="newEntitiesTable"
                    width="100%"
                    dataContainer="newEntitiesDc">
            <actions>
                <action id="myAction"/>
            </actions>
            <columns>
                <column id="name"/>
            </columns>
            <simplePagination/>
            <buttonsPanel id="buttonsPanel"
                          alwaysVisible="true">
                <button id="myButton" action="newEntitiesTable.myAction"/>
            </buttonsPanel>
        </groupTable>
...

Process this action in the screen controller and work with the selected table element:

...
    @Autowired
    private GroupTable<NewEntity> newEntitiesTable;

    @Subscribe("newEntitiesTable.myAction")
    public void onNewEntitiesTableMyAction(Action.ActionPerformedEvent event) {
        if (!newEntitiesTable.getSelected().isEmpty() && !newEntitiesTable.isMultiSelect()) {
            NewEntity selectedEntity = newEntitiesTable.getSingleSelected();
            //Process the selected table element
            ....
        }
    }
...
1 Like

Hi,
I would recommend to go through published tutorials on the YouTube:
https://www.youtube.com/c/JmixFramework/videos
“UI Development Basics” should make you familiar with how to build and modify screens beyond standard templates.

Many thanks, Andrey, for the support. I implemented it with few little variations, and is working as desired. I attach my code to help others.

My requirement was to have a button, on the browser listing my table entries, in order to perform an action on the selected row; the action was to run a job.

In the XML file of the screen (jobs-manager-browse.xml):

<layout expand="jobsManagersTable" spacing="true">
    <filter id="filter"
            dataLoader="jobsManagersDl">
        <properties include=".*"/>
    </filter>
    <groupTable id="jobsManagersTable"
                width="100%"
                dataContainer="jobsManagersDc">
        <actions>
            <action id="create" type="create"/>
            <action id="edit" type="edit"/>
            <action id="remove" type="remove"/>
            <action id="runjob" type="runJobAction"/>

I added the new action (runjob) in the actions element.

Then, in order to make the action visible, I added a button in the buttons panel of the list:

        <buttonsPanel id="buttonsPanel"
                      alwaysVisible="true">
            <button id="createBtn" action="jobsManagersTable.create"/>
            <button id="editBtn" action="jobsManagersTable.edit"/>
            <button id="removeBtn" action="jobsManagersTable.remove"/>
            <button id="runBtn" action="jobsManagersTable.runjob" />
        </buttonsPanel>

The button has id runBtn and references the action using the action attributes, that points to the action id.

Now, how can I link this layout specification with the code?

I have implemented a Class for the action, with this declaration:

@ActionType("runJobAction")
public class JobRunAction extends ItemTrackingAction {
....

The trick is the @ActionType annotation: the label specified is linked by the type attribute of the action element in the screen definition.
The extended class - ItemTrackingAction - performs all the interaction linked to the selection on a list: the resulting button is thus disabled if no row was selected by the user, and became enabled when the user selects a row.

Within the method actionPerform, you have access to the currently selected row:

Object selected = getTarget().getSingleSelected();

it is also possible to cast the Object selected to the class representing the Entity listed in the table:

JobsManager jmsel = (JobsManager)selected;

in this way you can execute any method in the entity class performing the required business logic (in my case, the entity class was JobsManager).

1 Like