@DomainObjectLayout
Layout hints for domain objects.
API
@interface DomainObjectLayout {
BookmarkPolicy bookmarking() default BookmarkPolicy.NOT_SPECIFIED; (1)
String cssClass() default ""; (2)
String cssClassFa() default ""; (3)
CssClassFaPosition cssClassFaPosition() default CssClassFaPosition.LEFT; (4)
String describedAs() default ""; (5)
String named() default ""; (6)
int paged() default -1; (7)
Class<? extends TableDecorator> tableDecorator() default TableDecorator.Default.class; (8)
Class<? extends CssClassUiEvent<?>> cssClassUiEvent() default CssClassUiEvent.Default.class; (9)
Class<? extends IconUiEvent<?>> iconUiEvent() default IconUiEvent.Default.class; (10)
Class<? extends LayoutUiEvent<?>> layoutUiEvent() default LayoutUiEvent.Default.class; (11)
Class<? extends TitleUiEvent<?>> titleUiEvent() default TitleUiEvent.Default.class; (12)
}
1 | bookmarking
Whether (and how) this domain object can be bookmarked in the UI. |
2 | cssClass
Indicates the CSS class that a domain class (type) should have, to allow more targeted styling in |
3 | cssClassFa
TheFont AwesomeCSS class that is used as icon for the annotated domain object. |
4 | cssClassFaPosition
Indicates the position of theFont Awesomeicon. The icon could be rendered on the left or the right of the object’s title. |
5 | describedAs
Description of this class, eg to be rendered in a tooltip. |
6 | named
Name of this class (overriding the name derived from its name in code). |
7 | paged
The page size for instances of this class when rendered within a table. |
8 | tableDecorator
Whether a standalone collection, when represented in a table form, should additionally be "decorated" with client-side (javascript) enhancements, for example to enable paging and filtering. |
9 | cssClassUiEvent
Which subclass of CssClassUiEvent should be used to obtain a CSS class. |
10 | iconUiEvent
Which subclass of IconUiEvent should be used to obtain an icon. |
11 | layoutUiEvent
Which subclass of LayoutUiEvent should be used to obtain a layout. |
12 | titleUiEvent
Which subclass of TitleUiEvent should be used to obtain a title. |
Members
cssClass
Indicates the CSS class that a domain class (type) should have, to allow more targeted styling in application.css
.
cssClassFa
TheFont AwesomeCSS class that is used as icon for the annotated domain object.
Use the FontAwesomeLayers iconFaLayers() object support method for more advanced icons.
cssClassFaPosition
Indicates the position of theFont Awesomeicon. The icon could be rendered on the left or the right of the object’s title.
named
Name of this class (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
.
paged
The page size for instances of this class when rendered within a table.
If annotated on a collection, then the page size refers to parented collections (eg Order#lineItems
).
If annotated on a type, then the page size refers to standalone collections (eg as returned from a repository query).
tableDecorator
Whether a standalone collection, when represented in a table form, should additionally be "decorated" with client-side (javascript) enhancements, for example to enable paging and filtering.
cssClassUiEvent
Which subclass of CssClassUiEvent should be used to obtain a CSS class.
This subclass must provide a no-arg constructor; the fields are set reflectively.
iconUiEvent
Which subclass of IconUiEvent should be used to obtain an icon.
This subclass must provide a no-arg constructor; the fields are set reflectively.
layoutUiEvent
Which subclass of LayoutUiEvent should be used to obtain a layout.
This subclass must provide a no-arg constructor; the fields are set reflectively.
titleUiEvent
Which subclass of TitleUiEvent should be used to obtain a title.
This subclass must provide a no-arg constructor; the fields are set reflectively.
Examples
For example:
@DomainObjectLayout(
cssClass="x-key",
cssClassFa="fa-checklist",
describedAs="Capture a task that you need to do",
named="ToDo",
paged=30,
plural="ToDo List")
)
public class ToDoItem {
...
}
Note that there is (currently) no support for specifying UI hints for domain objects through the dynamic .layout.xml file (only for properties, collections and actions are supported). |
Usage Notes
Descriptions
The describedAs() element is used to provide a short description of the domain object to the user. In the Web UI (Wicket viewer) it is displayed as a 'tool tip'.
For example:
@DomainObjectLayout(
describedAs = "A customer who may have originally become"
+ " known to us via the marketing system or who may"
+ " have contacted us directly."
)
public class ProspectiveSale {
...
}
CSS Styling
The cssClass() element can be used to render additional CSS classes in the HTML (a wrapping <div>
) that represents the domain object.
Application-specific CSS can then be used to target and adjust the UI representation of that particular element.
For example:
@DomainObject
@DomainObjectLayout(
cssClass="x-core-entity"
)
public class ToDoItem { /* ... */ }
The similar @DomainObjectLayout#cssClassFa() element is also used as a hint to apply CSS, but in particular to allow Font Awesome icons to be rendered as the icon for classes. |
Font Awesome Icons
The cssClassFa() element is used to specify the name of a Font Awesome icon name, to be rendered as the domain object’s icon.
If necessary the icon specified can be overridden by a particular object instance using the iconName() method.
For example:
@DomainObjectLayout(
cssClassFa="fa-check-circle"
)
public class ToDoItem {
// ...
}
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.
The related cssClassFaPosition element is currently unused for domain objects; the icon is always rendered to the left.
The similar @DomainObjectLayout#cssClass() element is also used as a hint to apply CSS, but for wrapping the representation of an object or object member so that it can be styled in an application-specific way. |
Names
The named() element explicitly specifies the domain object’s name, overriding the name that would normally be inferred from the Java source code.
We recommend that you only use this element 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:
@DomainObjectLayout(
named="Customer"
)
public class CustomerImpl implements Customer{
// ...
}
Plural form
When Apache Causeway displays a standalone collection of several objects, it will label the collection using the plural form of the object type. By default the plural name will be derived from the end of the singular name, with support for some basic English language defaults (eg using "ies" for names ending with a "y").
For irregular plurals it’s possible to specify a plural form using the plural element.
For example:
@DomainObjectLayout(plural="Children")
public class Child {
// ...
}
i18n
The framework also provides a separate, powerful mechanism for internationalization.
Bookmarks
The bookmarking() element indicates that an entity is automatically bookmarked.
In the Web UI (Wicket viewer), a link to a bookmarked object is shown in the bookmarks panel, top right.
For example:
@DomainObject(bookmarking=BookmarkPolicy.AS_ROOT)
public class ToDoItem ... {
...
}
indicates that the ToDoItem
class is bookmarkable:
It is also possible to nest bookmarkable entities. For example:
For example, the Property
entity "[OXF] Oxford Super Mall" is a root bookmark, but the Unit
child entity "[OXF-001] Unit 1" only appears as a bookmark but only if its parent Property
has already been bookmarked.
This is accomplished with the following annotations:
@DomainObject(bookmarking=BookmarkPolicy.AS_ROOT)
public class Property {
// ...
}
and
@DomainObject(bookmarking=BookmarkPolicy.AS_CHILD)
public abstract class Unit {
// ...
}
The nesting can be done to any level.
Paging
The paged() element specifies the number of rows to display in a standalone collection, as returned from an action invocation.
The RestfulObjects viewer currently does not support paging. The Web UI (Wicket viewer) does support paging, but note that the paging is performed client-side rather than server-side. We therefore recommend that large collections should instead be modelled as actions (to allow filtering to be applied to limit the number of rows). |
For example:
@DomainObjectLayout(paged=15)
public class Order {
// ...
}
It is also possible to specify a global default for the page size of standalone collections, using the causeway.applib.annotation.domain-object-layout.paged configuration property.
UI Events
Whenever a domain object is to be rendered, the framework fires off a number of various events to allow subscribers to influence the visual appearance of that domain object:
-
a CSS class UI event
to obtain a CSS class to use in any wrapping
<div>
s and<span>
s that render the domain object. -
an icon UI event
to obtain an icon (name) for the object (if possible)
-
a layout UI event
to obtain an alternative layout name with which to render the domain object.
-
a title UI event
to obtain a title for the object
The framework has a built-in event class (for each UI hint) that is raised by default; for example a TitleUiEvent.Default
is raised to obtain a title for the object.
Subscribers subscribe through the EventBusService and can use obtain a reference to the domain object from the event.
From this they can, if they wish, specify the corresponding UI hint.
This basic model can be influenced in a couple of ways:
-
first, it is also possible to suppress any events from being emitted using a configuration property (a different config property exists each lifecycle hook).
-
second, an element on @DomainObjectLayout annotation (for each UI hook) allows a different subtype event types to be emitted instead
This allows subscribers to more targeted as to the events that they subscribe to.
The type of this event can be changed using various xxxUiEvent
elements of @DomainObjectLayout.
This allows subscribers to be more precise as to the domain objects that they will target.
The framework also provides convenience "Doop" and a "Noop" event classes, that provoke these behaviours:
-
if the appropriate DomainObject' element is set to the "Doop" subclass, then this will event will be fired
this is a convenient way of ensuring an event is fired even if the hook has been disabled globally, but without the hassle of defining a custom event type
-
if set to the "Noop" subclass, then an event will not be fired.
If the domain object implements the corresponding reserved method directly (for example title(), then that will take precedence.
The table below summarises all the UI event hooks:
UI hint |
Config property |
@DomainObjectLayout override |
Framework event types |
Reserved method |
CSS class |
|
|||
Icon Name |
|
|||
Layout |
|
|||
Title |
|
For example:
@DomainObjectLayout(
iconUiEvent=ToDoItemDto.CssClassUiEvent.class,
titleUiEvent=ToDoItemDto.TitleUiEvent.class
)
public class ToDoItemDto {
public static class CssClassUiEvent
extends org.apache.causeway.applib.events.ui.CssClassUiEvent<ToDoItemDto> { }
public static class TitleUiEvent
extends org.apache.causeway.applib.events.ui.TitleUiEvent<ToDoItemDto> { }
...
}
Subscribers
Subscribers can be either coarse-grained (if they subscribe to the top-level event type):
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
@Service
public class SomeSubscriber {
@EventListener(CssClassUiEvent.class)
public void on(CssClassUiEvent ev) {
if(ev.getSource() instanceof ToDoItemDto) {
...
}
}
}
or can be fine-grained (by subscribing to specific event subtypes):
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
@Service
public class SomeSubscriber {
@EventListener(ToDoItemDto.CssClassUiEvent.class)
public void on(ToDoItemDto.CssClassUiEvent ev) {
...
}
}
The subscriber should then use the appropriate method — CssClassUiEvent#setCssClass(…)
— to actually specify the CSS class to be used.