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
Section titled “@Button”@Button places the action as a button in the form footer area.
@Buttonpublic 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
Section titled “@Toolbar”@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:
@Toolbarpublic Message archiveSelected(List<Product> selectedRows) { selectedRows.forEach(p -> productRepository.archive(p.id())); return new Message("Archived " + selectedRows.size() + " products");}@ListToolbarButton
Section titled “@ListToolbarButton”@ListToolbarButton adds a button to the listing toolbar that operates on the selected rows.
@ListToolbarButtonpublic 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");}Controlling behavior: @Action
Section titled “Controlling behavior: @Action”@Action configures how an action behaves before and during execution.
Require validation
Section titled “Require validation”@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.
Require confirmation
Section titled “Require confirmation”@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.
Accessing the HTTP request
Section titled “Accessing the HTTP request”Actions can declare HttpRequest as a parameter to access headers, authentication tokens, or any other request metadata.
@Toolbarpublic 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.
Row-level actions (ColumnAction)
Section titled “Row-level actions (ColumnAction)”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); }
}What actions can return
Section titled “What actions can return”The return value controls what happens in the browser. See UI effects for the full reference.
| Return type | Effect |
|---|---|
Message | Show a toast notification |
State(this) | Refresh the form |
URI | Navigate to a URL |
UICommand.navigateTo(...) | Programmatic navigation |
| Another ViewModel | Render that page |
List<?> | Multiple effects |
void / null | Nothing |
Summary
Section titled “Summary”| Annotation | Where it appears | Receives |
|---|---|---|
@Button | Form footer | — |
@Toolbar (on form) | Form toolbar | — |
@Toolbar (on listing) | Listing toolbar | selected rows, HttpRequest |
@ListToolbarButton | Listing toolbar | selected rows |
ColumnAction | Per-row in listing | the row |