Skip to content

Action behavior

Actions are public methods on your ViewModel that are exposed to the browser as interactive triggers.

Where an action appears, how it behaves before execution, and what it returns are all controlled declaratively.


Where actions appear: @Button vs @Toolbar vs @ListToolbarButton

Section titled “Where actions appear: @Button vs @Toolbar vs @ListToolbarButton”

@Button places the action as a button in the form footer area.

@Button
public Message save() {
productRepository.save(id, name, status);
return new Message("Product saved");
}

Use @Button for the primary actions of a form page (save, submit, check, etc.).


@Toolbar places the action in the toolbar — more prominent than @Button, typically at the top of the screen.

@Toolbar
@Action(validationRequired = true)
public URI publish() {
String newId = productRepository.publish(name, status);
return URI.create("/products/" + newId);
}

In a listing, a @Toolbar method receives the currently selected rows and, optionally, the HttpRequest:

@Toolbar
public Message archiveSelected(List<Product> selectedRows) {
selectedRows.forEach(p -> productRepository.archive(p.id()));
return new Message("Archived " + selectedRows.size() + " products");
}

@ListToolbarButton adds a button to the listing toolbar that operates on the selected rows.

@ListToolbarButton
public Message markAvailable(List<Product> selection) {
selection.forEach(p -> productRepository.setStatus(p.id(), Status.Available));
return Message.builder()
.text("Marked " + selection.size() + " products as available")
.build();
}

Use confirmationRequired = false to skip the default confirmation dialog:

@ListToolbarButton(confirmationRequired = false)
public Message refresh(List<Product> selection) {
return new Message("Refreshed " + selection.size() + " items");
}

@Action configures how an action behaves before and during execution.

@Button
@Action(validationRequired = true)
public URI create() {
String id = productRepository.create(name, status);
return URI.create("/products/" + id);
}

When validationRequired = true, Mateu validates all form fields before calling the method. If validation fails, the method is not called and errors are shown next to the affected fields.

@ListToolbarButton(confirmationRequired = true)
public Message deleteSelected(List<Product> selection) {
selection.forEach(p -> productRepository.delete(p.id()));
return new Message("Deleted " + selection.size() + " products");
}

A confirmation dialog is shown before the method runs. The user must confirm to proceed.


Actions can declare HttpRequest as a parameter to access headers, authentication tokens, or any other request metadata.

@Toolbar
public Message auditAccess(HttpRequest httpRequest) {
String auth = httpRequest.getHeaderValue("Authorization");
String token = auth.split(" ")[1];
auditService.log(id, token);
return new Message("Access logged");
}

Mateu injects HttpRequest automatically when it appears as a method parameter. No wiring is needed.


Actions in a listing can be attached to individual rows using ColumnAction and ColumnActionGroup.

Define the action in the row model:

record Product(
String id,
String name,
Status status,
ColumnActionGroup action
) {
Product {
action = new ColumnActionGroup(new ColumnAction[]{
new ColumnAction("markAvailable", "Mark available"),
new ColumnAction("markOutOfStock", "Mark out of stock")
});
}
}

Handle each action in the orchestrator with a method whose name matches the actionId:

@UI("/products")
public class Products extends AutoCrudOrchestrator<Product> {
void markAvailable(Product row) {
productRepository.setStatus(row.id(), Status.Available);
}
void markOutOfStock(Product row) {
productRepository.setStatus(row.id(), Status.OutOfStock);
}
}

The return value controls what happens in the browser. See UI effects for the full reference.

Return typeEffect
MessageShow a toast notification
State(this)Refresh the form
URINavigate to a URL
UICommand.navigateTo(...)Programmatic navigation
Another ViewModelRender that page
List<?>Multiple effects
void / nullNothing

AnnotationWhere it appearsReceives
@ButtonForm footer
@Toolbar (on form)Form toolbar
@Toolbar (on listing)Listing toolbarselected rows, HttpRequest
@ListToolbarButtonListing toolbarselected rows
ColumnActionPer-row in listingthe row