@ActionLayout
Layout hints for actions.
API
@interface ActionLayout {
String associateWith() default ""; (1)
String cssClass() default ""; (2)
String cssClassFa() default ""; (3)
CssClassFaPosition cssClassFaPosition() default CssClassFaPosition.LEFT; (4)
String describedAs() default ""; (5)
String fieldSetId() default "__infer"; (6)
String fieldSetName() default "__infer"; (7)
Where hidden() default Where.NOT_SPECIFIED; (8)
String named() default ""; (9)
Position position() default Position.NOT_SPECIFIED; (10)
PromptStyle promptStyle() default PromptStyle.AS_CONFIGURED; (11)
@Deprecated(forRemoval = false, since = "2.0.0-RC1")
Redirect redirectPolicy() default Redirect.AS_CONFIGURED; (12)
String sequence() default ""; (13)
}
1 | associateWith
Associates this action with a property or collection, specifying its id. |
||
2 | cssClass
Indicates the css class that an action should have. |
||
3 | cssClassFa
Indicates theFont AwesomeCSS class to decorate an action (button or menu item). |
||
4 | cssClassFaPosition
Indicates the position of theFont Awesomeicon. |
||
5 | describedAs
Description of this action, eg to be rendered in a tooltip. |
||
6 | fieldSetId
Specifies the id of associated FieldSet .To associate an Action with a Collection , use Action#choicesFrom() instead. |
||
7 | fieldSetName
Specifies the friendly-name of associated FieldSet or Collection .To associate an Action with a Collection , use Action#choicesFrom() instead. |
||
8 | hidden
Indicates where in the UI the action should not not be visible. |
||
9 | named
Name of this action (overriding the name derived from its name in code). |
||
10 | position
For actions that are associated with a property (using either Action#choicesFrom() or ActionLayout#fieldSetId() or ActionLayout#fieldSetName() , indicates the positioning of the action’s button relative to the property. |
||
11 | promptStyle
How the parameters for this action are prompted, either PromptStyle#DIALOG dialog or PromptStyle#INLINE inline . |
||
12 | redirectPolicy
If the action returns its target, then determines whether to update the page or instead to redirect (forcing a re-rendering of a new page). |
||
13 | sequence
The order of this member relative to other members in the same (layout) group, given in Dewey-decimal notation. |
Members
associateWith
Associates this action with a property or collection, specifying its id.
To specify the layout order use ActionLayout#sequence() .
For example @ActionLayout(associateWith="items") @ActionLayout(sequence="2.1")
Note that it is also possible to associate an action with a collection using Action#choicesFrom() (which has the additional semantic of the rows of the element being used as choices for that action’s collection parameter of the same type as the elements of the collection).
cssClass
Indicates the css class that an action should have.
For the Wicket viewer, this can be a bootstrap class such as btn-info
.
cssClassFaPosition
Indicates the position of theFont Awesomeicon.
The icon could be rendered on the left or the right of the action button
fieldSetId
Specifies the id of associated FieldSet .To associate an Action with a Collection , use Action#choicesFrom() instead.
For a more in depth description see the analogous PropertyLayout#fieldSetId() .
fieldSetName
Specifies the friendly-name of associated FieldSet or Collection .To associate an Action with a Collection , use Action#choicesFrom() instead.
For a more in depth description see the analogous PropertyLayout#fieldSetId() ;
named
Name of this action (overriding the name derived from its name in code).
A typical use case is if the desired name is a reserved Java keyword, such as default
or package
.
position
For actions that are associated with a property (using either Action#choicesFrom() or ActionLayout#fieldSetId() or ActionLayout#fieldSetName() , indicates the positioning of the action’s button relative to the property.
Ignored if the action has not been associated with a property.
promptStyle
How the parameters for this action are prompted, either PromptStyle#DIALOG dialog or PromptStyle#INLINE inline .
redirectPolicy
deprecated: currently NOT supported by the Wicket viewer, but could be re-implemented with a future release |
If the action returns its target, then determines whether to update the page or instead to redirect (forcing a re-rendering of a new page).
Not re-rendering can provide a smoother UI experience.
Examples
For example:
public class ToDoItems {
@Action(semantics=SemanticsOf.SAFE) (1)
@ActionLayout(
bookmarking=BookmarkPolicy.AS_ROOT,
cssClass="x-key",
cssClassFa="fa-checkbox",
describedAs="Mark the todo item as not complete after all",
hidden=Where.NOWHERE, (2)
sequence = "1"
)
public List<ToDoItem> notYetComplete() {
...
}
}
1 | required for bookmarkable actions |
2 | default value, so could be omitted |
As an alternative to using the |
Usage Notes
As alternative to using the annotation, the dynamic file-based layout can generally be used instead.
Prompt Style
The promptStyle() element is used to specify whether, when invoking an action associated with a domain object property, the parameters for the action are prompted either in modal dialog box, a (non-modal) sidebar dialog box, or is prompted using an inline panel (replacing the property on the page). For more on sidebar vs modal dialogs, see Wicket viewer features.
The prompt style is influenced by two configuration properties:
-
if the promptStyle() element is set to
DIALOG
, then a configuration property is used to determine whether to render using a modal dialog or a sidebar:-
causeway.viewer.wicket.dialog-mode if the action is for a domain object (entity or view model)
If the configuration property is not set, then sidebar is used.
-
causeway.viewer.wicket.dialog-mode-for-menu if the action is for a domain service
If the configuration property is not set, then modal is used.
-
-
if the attribute is not set at all, then thecauseway.viewer.wicket.prompt-style configuration property is used to specify the preferred prompt style.
If the configuration property is not set, then an inline prompt is used.
And, if this is set but is set to just
DIALOG
, then the causeway.viewer.wicket.dialog-mode configuration property determines which style.
For example:
import lombok.Getter;
import lombok.Setter;
public class Customer {
@Property(editing = Editing.DISABLED) (1)
@Getter @Setter
private String notes;
@Action(associateWith="notes") (2)
@ActionLayout(
promptStyle=PromptStyle.INLINE (3)
)
public Customer updateNotes(String notes) {
// ...
}
}
1 | property is not editable |
2 | instead, associate this action with the "notes" property |
3 | prompt for the action’s parameters using an inline panel. |
Exactly one action for a given property can be specified with INLINE_AS_IF_EDIT
.
Assuming that the corresponding property is not itself editable, this means that the property will be rendered as if it is editable, but the action’s prompt form will be rendered instead.
The net effect is that a property conceptually consisting of different parts (eg a name, an address or a date) can be updated using an action that lets each separate part be specified independently.
Positioning
The position() element pertains only to actions that have been associated with properties using @Action#associateWith(). For these actions, it specifies the positioning of the action’s button with respect to the field representing the object property.
The attribute can take one of four values: BELOW
, RIGHT
, PANEL
or PANEL_DROPDOWN
.
For example:
import lombok.Getter;
import lombok.Setter;
public class Customer {
@Property( editing=Editing.DISABLED )
@Getter @Setter
private BigDecimal cost;
@Property( editing=Editing.DISABLED )
@Getter @Setter
private String location;
@Action( associateWith="cost" ) (1)
@ActionLayout(
named="Update", (2)
position=Position.BELOW (3)
)
public Customer updateCost(BigDecimal cost ) {
// ...
}
@Action( associateWith="location" )
@ActionLayout(
named="Update",
position=Position.BELOW
)
public Customer updateLocation(String latitude, String longitude) {
// ...
}
}
1 | associate the "updateCost" action with the "cost" property |
2 | give the action an abbreviated name, because the fact that the "cost" property is to be updated is implied by its positioning |
3 | positioning of the action’s button |
The default is BELOW
.
If the action is positioned as RIGHT
, then the action’s button is rendered to the right of the property’s field, in a compact drop-down.
If the action is positioned as PANEL
, then the action’s button is rendered on the header of the panel that contains the property.
And finally, if the action is positioned as PANEL_DROPDOWN
, then the action’s button is again rendered on the panel header.
If there are multiple actions associated with a single property then the positioning can be mix’ed-and-match’ed as required.
If the PANEL
or PANEL_DROPDOWN
are used, then (as the screenshots above show) the actions from potentially multiple properties grouped by that panel will be shown together.
Descriptions
The describedAs() attribute is used to provide a short description of the action to the user. In the Web UI (Wicket viewer) it is displayed as a 'tool tip'.
For example:
public class Customer {
@ActionLayout(describedAs=
"Place a repeat order of the last (most recently placed) order")
public Order placeRepeatOrder(...) { /* ... */ }
}
CSS Styling
The cssClass() element can be used to render additional CSS classes in the HTML (a wrapping <div>
) that represents the action.
Application-specific CSS can then be used to target and adjust the UI representation of that particular element.
For example:
public class ToDoItem {
@ActionLayout(cssClass="x-key")
public ToDoItem postpone(LocalDate until) { /* ... */ }
...
}
The similar @ActionLayout#cssClassFa annotation attribute is also used as a hint to apply CSS, specifically to add Font Awesome icons on action menu items or buttons. |
Font Icons
The cssClassFa() element is used to specify the name of a Font Awesome icon name, to be rendered on the action’s representation as a button or menu item. The related cssClassFaPosition() element specifies the positioning of the icon, to the left or the right of the text.
These attributes can also be applied to domain objects to specify the object’s icon.
For example:
public class ToDoItem {
@ActionLayout(
cssClassFa="fa-step-backward"
)
public ToDoItem previous() {
// ...
}
@ActionLayout(
cssClassFa="fa-step-forward",
cssClassFaPosition=ActionLayout.CssClassFaPosition.RIGHT
)
public ToDoItem next() {
// ...
}
}
There can be multiple "fa-" classes, eg to mirror or rotate the icon.
There is no need to include the mandatory fa
"marker" CSS class; it will be automatically added to the list.
The fa-
prefix can also be omitted from the class names; it will be prepended to each if required.
Bookmarking
The bookmarking() element indicates if an action (with safe action semantics) is automatically bookmarked.
In the Web UI (Wicket viewer), a link to a bookmarked object is shown in the bookmarks panel.
The Web UI (Wicket viewer) supports |
For example:
public class ToDoItems {
@Action(semantics=SemanticsOf.SAFE)
@ActionLayout(
bookmarking=BookmarkPolicy.AS_ROOT,
sequence = "1")
public List<ToDoItem> notYetComplete() {
...
}
}
indicates that the notYetComplete()
action is bookmarkable.
The enum value |
Hiding actions
The hidden() attribute indicates where (in the UI) the action should be hidden from the user.
It is also possible to use @Action#hidden to hide an action at the domain layer. |
For example:
public class Customer {
@ActionLayout(hidden=Where.EVERYWHERE)
public void updateStatus() {
// ...
}
...
}
The acceptable values for the where
parameter are:
-
Where.EVERYWHERE
orWhere.ANYWHERE
The action should be hidden at all times.
-
Where.NOWHERE
The action should not be hidden.
The other values of the Where
enum have no meaning for a collection.
Names
The named() element explicitly specifies the action’s name, overriding the name that would normally be inferred from the Java source code.
Only use this attribute when the desired name cannot be used in Java source code. Examples of that include a name that would be a reserved Java keyword (eg "package"), or a name that has punctuation, eg apostrophes. |
For example:
public class Customer {
@ActionLayout(named="Get credit rating") (1)
public CreditRating obtainCreditRating() {
// ...
}
}
1 | "get" normally indicates a property rather than an action. |
Alternatives
The framework also provides a separate, powerful mechanism for internationalization.
Smoother UI
Often an action, when invoked, will return the target (in other words, will "return this"). The redirectPolicy() element is used to control how the object is re-rendered.
There are three options:
-
if set to
ONLY_IF_DIFFERS
, then the existing web page will not be re-rendered, rather it will be updated in-place (using Ajax).This makes for a smoother UI.
Any properties with @PropertyLayout#repainting set to
NO_REPAINT
are then not updated. -
if set to
EVEN_IF_SAME
, then a redirect occurs and a new web page is rendered. -
if set to
AS_CONFIGURED
, then the default behaviour is as specified by thecauseway.viewer.wicket.redirectEvenIfSameObject
configuration property).
One use case for choosing EVEN_IF_SAME
is if the action "returning this" is intended in some way to require that the object use a different layout, as per multiple layout support, as specified using the layout() method.
For example:
import lombok.Getter;
import lombok.Setter;
public class Customer {
@Getter @Setter
@PropertyLayout(hidden=ALWAYS)
private String layout;
public String layout() { (1)
return layout;
}
@ActionLayout(
redirect=EVEN_IF_SAME (2)
)
public Customer switchToEditMode() {
setLayout("edit");
return this;
}
}
1 | specifies the alternate layout to use, eg Customer-edit.layout.xml . |
2 | even though this action returns the same target object, still re-render the page. |
If switchToEditMode()
action is invoked, then the UI will attempt to render the customer using a Customer.layout.edit.xml
layout file (instead of the default Customer.layout.xml
).