@CollectionLayout

Layout hints for collections.

API

CollectionLayout.java
@interface CollectionLayout {
  String cssClass() default "";     (1)
  String defaultView() default "";     (2)
  String describedAs() default "";     (3)
  Where hidden() default Where.NOT_SPECIFIED;     (4)
  String named() default "";     (5)
  int paged() default -1;     (6)
  String sequence() default "";     (7)
  @SuppressWarnings("rawtypes")
Class<? extends Comparator> sortedBy() default Comparator.class;     (8)
  Class<? extends TableDecorator> tableDecorator() default TableDecorator.Default.class;     (9)
}
1 cssClass

Indicates the css class that a collection should have, to allow more targeted styling in application.css .

2 defaultView

Indicates which view is used by default to render the collection.

3 describedAs

Description of this collection, eg to be rendered in a tooltip.

4 hidden

Indicates where in the UI the collection should not not be visible.

5 named

Name of this collection (overriding the name derived from its name in code).

6 paged

The page size for instances of this class when rendered within a table.

7 sequence

The order of this member relative to other members in the same (layout) group, given in Dewey-decimal notation.

8 sortedBy

Indicates that the elements in a ( java.util.SortedSet ) collection should be sorted according to a different order than the natural sort order, as defined by the specified java.util.Comparator .

9 tableDecorator

Whether a parented collection when represented in a table form should additionally be "decorated" with client-side (javascript) enhancements, for example to enable paging and filtering.

Members

cssClass

Indicates the css class that a collection should have, to allow more targeted styling in application.css .

defaultView

Indicates which view is used by default to render the collection.

This is a simple string; every available implementation is required to use a different string.

The default is "table". Extensions provide also: "excel" (download as Excel spreadsheet), "calendar" and "map".

describedAs

Description of this collection, eg to be rendered in a tooltip.

hidden

Indicates where in the UI the collection should not not be visible.

Only Where#NOWHERE NOWHERE or Where#EVERYWHERE EVERYWHERE / Where#ANYWHERE ANYWHERE apply for collections.

named

Name of this collection (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).

sequence

The order of this member relative to other members in the same (layout) group, given in Dewey-decimal notation.

It specifically governs the slot-in order for the layout group that collects all unreferenced Collections , unless overwritten via application scoped config option that enforced alphabetical order:_causeway.applib.annotation.collectionLayout.sequencePolicyIfUnreferenced_

An alternative is to use the Xxx.layout.xml file, where Xxx is the domain object name.

sortedBy

Indicates that the elements in a ( java.util.SortedSet ) collection should be sorted according to a different order than the natural sort order, as defined by the specified java.util.Comparator .

Whenever there is a collection of type java.util.SortedSet , the domain entity referenced is expected to implement Comparable , ie to have a natural ordering. In effect tis means that all domain entities should provide a natural ordering.

However, in some circumstances the ordering of collection may be different to the entity’s natural ordering. For example, the entity may represent an interval of time sorted by its startDate ascending, but the collection may wish to sort by startDate .

The purpose of this annotation is to provide a java.util.Comparator such that the collection may be sorted in an order more suitable to the context.

tableDecorator

Whether a parented collection when represented in a table form should additionally be "decorated" with client-side (javascript) enhancements, for example to enable paging and filtering.

Examples

For example:

public class ToDoItem {
    @CollectionLayout(
        cssClass="x-key",
        named="Todo items that are <i>dependencies</i> of this item.",
        namedEscaped=false,
        describedAs="Other todo items that must be completed before this one",
        labelPosition=LabelPosition.LEFT,
        render=EAGERLY)
    public SortedSet<ToDoItem> getDependencies() { /* ... */ }
    ...
}

As an alternative to using the @CollectionLayout annotation, a file-based layout can be used (and is generally to be preferred since it is more flexible/powerful).

The annotation is one of a handful (others including @Collection, @Property and @PropertyLayout) that can also be applied to the field, rather than the getter method. This is specifically so that boilerplate-busting tools such as Project Lombok can be used.

Usage Notes

As alternative to using the annotation, the dynamic file-based layout can generally be used instead.

Default view

The `defaultView() element is used to select which of views should be used by default for a given collection. Without any hint the collection is shown collapsed (to save real estate and reduce load time).

For example:

import lombok.Getter;
import lombok.Setter;


public class BusRoute {

    @CollectionLayout( defaultView="table" )    (1)
    @Getter @Setter
    private SortedSet<BusStop> stops = ...

}
1 renders the collection as a table view.

The Web UI (Wicket viewer) allows additional views to be configured to render collections of objects, eg Tabular Download ("excel") and Fullcalendar ("fullcalendar") extensions. This attribute can be used to select any of these alternative views instead.

Paging

The paged() element specifies the number of rows to display in a (parented) collection.

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:

import lombok.Getter;
import lombok.Setter;

public class Order {

    @CollectionLayout(paged=15)
    @Getter @Setter
    private SortedSet<OrderLine> details = ...
}

It is also possible to specify a global default for the page size of parented collections, using the causeway.applib.annotation.collection-layout.paged configuration property.

Descriptions

The describedAs() element is used to provide a short description of the collection to the user. In the Web UI (Wicket viewer) it is displayed as a 'tool tip'.

For example:

import lombok.Getter;
import lombok.Setter;

public class ToDoItem {

    @CollectionLayout(
        describedAs = "Todo items to be completed before this one"
    )
    @Getter @Setter
    private SortedSet<ToDoItem> dependencies = ...

}

Client-side Sorting

The sortedBy() element specifies that the collection be ordered using the specified comparator, rather than the natural ordering of the entity (as would usually be the case).

For example:

import lombok.Getter;
import lombok.Setter;

public class ToDoItem implements Comparable<ToDoItem> {         (1)

    public static class DescriptionComparator                   (2)
                            implements Comparator<ToDoItem> {
        @Override
        public int compare(ToDoItem o1, ToDoItem o2) {
            return Comparator.comparing(ToDoItem::getDescription)
                             .compare(o1, o2);
        }
    }

    @CollectionLayout(sortedBy=DependenciesComparator.class)    (3)
    @Getter @Setter
    private SortedSet<ToDoItem> dependencies = ...

}
1 the class has a natural ordering (implementation not shown)
2 declaration of an alternative comparator class, using the object’s description property
3 ordering of the collection defined as being by this comparator

When the dependencies collection is rendered, the elements are sorted by the description property first.

CSS Styling

The cssClass() element can be used to render additional CSS classes in the HTML (a wrapping <div>) that represents the collection. Application-specific CSS can then be used to target and adjust the UI representation of that particular element.

For example:

import lombok.Getter;
import lombok.Setter;

public class ToDoItem {

    @CollectionLayout(
        cssClass="x-important"
    )
    @Getter @Setter
    private SortedSet<ToDoItem> dependencies = ...;

}

Names

The named() element explicitly specifies the collection’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.

The name is HTML escaped.

For example:

import lombok.Getter;
import lombok.Setter;

public class ToDoItem {
    @CollectionLayout(
        named="Dependencies of this item",
        namedEscaped=false
    )
    @Getter @Setter
    private SortedSet<ToDoItem> dependencies = ...

}

Alternatives

The framework also provides a separate, powerful mechanism for internationalization.

Hiding collections

The hidden() element indicates where (in the UI) the collection should be hidden from the user.

The acceptable values are:

  • Where.EVERYWHERE or Where.ANYWHERE

    The collection should be hidden everywhere.

  • Where.ANYWHERE

    Synonym for everywhere.

  • Where.OBJECT_FORMS

    The collection should be hidden when displayed within an object form.

  • Where.NOWHERE

    The collection should not be hidden.

The other values of the Where enum have no meaning for a collection.

For example:

import lombok.Getter;
import lombok.Setter;

public class ToDoItem {

    @CollectionLayout(
        hidden=Where.EVERYWHERE
    )
    @Getter @Setter
    private SortedSet<ToDoItem> dependencies = ...
}

Alternatives

It is also possible to use @Collection#hidden to hide a collection at the domain layer.