Description
This macro is used to browse a sequence of Hash objects which has previously been ordered by applying one or more ordering processes. Ordering is a process involving transforming a sequence of objects into a sequence of object groups. A group is a virtual group of objects: the ordering process does not change the structure of the sequence or the value of the objects making up the sequence; only the order of the objects is changed. A value can be associated with each group (deduced from the values of the objects in it), which can be used as a label when displaying the sequence in the result document.
Each group can contain one or more objects from the initial sequence but two separate groups cannot contain the same object. After ordering, all the objects belong to one group.
Ordering can be carried out:
- by creating sorted groups,
- by creating named groups defined by the user (the order of groups is not defined by a sort but by the user).
Ordering is based on a key (an object attribute name common to all the Hash objects in the sequence) and applies to this attribute's values. Several different ordering processes can be executed on the same sequence (on several different attributes). In this case, each ordering is applied in the order defined by the user and applied to the result sequence of the preceding ordering.
The macro call syntax is as follows:
<@hardisAdv.groupList seqToOrder orderingCriteria; aHashObjInSeq> ... ${ aHashObjInSeq.fooAttribute } ... </@hardisAdv.groupList>
With:
- seqToOrder: sequence of Hash objects to order and browse,
- orderingCriteria: Sequence object defining the orderings to apply to the seqToOrder sequence,
- aHashObjInSeq: loop variable whose name is defined by the user and which is updated by the groupList macro at each result sequence element read iteration. The value of this variable is the read Hash object,
- nested content (? ${ aHashObjInSeq.fooAttribute } ?). Once the sequence is ordered, it is browsed from the first to the last element. During browsing, the value of the read element is stored in the aHashObjInSeq loop variable and the nested content of the macro (the text between the macro start and end tag) is executed. During this execution, which group the read element belongs to can be known. The nested content is therefore executed as many times as there are elements in the ordered sequence. The macro will not produce any result in the output document if the sequence is empty.
↑ Top of page
Each ordering process is based on the comparison of values: groupList supports Boolean, Number, String, Date, Time and Date-time comparisons.
Ordering key
The key corresponds to a Hash object attribute name belonging to the sequence. A first-level or Nth-level object attribute can be addressed (like the FreeMarker built-in ?sort_by function):
Level |
Sequence |
First-level keys: "price" / "id" |
[ { "id": 123, "price": 12}, { "id": 4, "price": 5.5}] |
Second-level keys: "stock.current" / "stock.command" |
[ { "id": 123, "price": 12, "stock" : {"current": 10, "command": 5}}, |
A key must represent an attribute with a supported type. An Nth-level key is defined using "dot" notation and represents the access path to the attribute from the first level. Each intermediate level refers to an attribute which must be Hash type.
↑ Top of page
Sorted groups
The sorted group creation process is based on:
- The key type. Two cases need to be differentiated:
- a String/Number-type key or
- a Boolean/Date/Time/Date-time-type key.
- The sorting order. There are several possible sorting orders:
- ascending order,
- descending order,
- original order (order is not changed).
- A dependency criterion. This criterion must be verified for each group element.
String/Number-type key
The group creation process is as follows:
- Sequence sorting according to key and sorting order,
- Sequence browsing to assign to each element a group with the required dependency criterion "All elements have the same value". A group value is the value of the element(s) it contains.
For example
Sorted group |
Key: "age", order: "d" |
||||||||||
Sequence |
[{"age":19}, {"age":20}, {"age":17}, {"age":18}, {"age":17}, {"age":20}, {"age":16}, {"age":20}] |
||||||||||
Ordered sequence |
|
Boolean/Date/Time/Date-time-type key
The group creation process is as follows:
- Sequence browsing to assign to each element a group with a dependency criterion chosen by the user. The group value depends on the criterion.
- Group sorting according to the value of each group and the sorting order. The new group order defines the result sequence.
The criterion type depends on the key type. Each criterion is described in the following table:
Criterion | Group description |
Group value |
|
Date type | |||
day |
All the dates define the same day (i.e. have the same value) |
Date of the day |
|
week |
All the dates belong to the same week |
Date of the first day of the week |
|
twoWeeks |
All the dates belong to a two-consecutive-week period |
Date of the first day of the first week of the period |
|
fortnight |
All the dates belong to the same fortnight (from 1 to 15 of each month) |
Date of the first day of the fortnight |
|
month |
All the dates belong to the same month |
Date of the first day of the month |
|
quarter |
All the dates belong to the same quarter |
Date of the first day of the first month of the quarter |
|
semester |
All the dates belong to the same semester |
Date of the first day of the first month of the semester |
|
year |
All the dates belong to the same year |
Date of the first day of the first month of the year |
|
Date-time type |
|||
All the criteria of the Date type plus: |
|||
second |
All the date-times belong to the same second |
Date-time of the second |
|
minute |
All the date-times belong to the same minute |
Date-time of the minute |
|
hour |
All the date-times belong to the same hour |
Date-time of the hour |
|
amPm |
All the date-times belong to the same AM or PM period |
Date-time of the first second of the period |
|
Time type |
|||
second |
All the times belong to the same second |
Time of second |
|
minute |
All the times belong to the same minute |
Time of minute |
|
hour |
All the times belong to the same hour |
Time of hour |
|
amPm |
All the times belong to the same AM or PM period |
Time of the first hour of the period |
|
Boolean type |
|||
everyChange |
Groups together Booleans with the same value ("true" or "false") |
First group value |
|
toChangeInYes |
Groups together Booleans belonging to the same sub-sequence (consecutive Boolean values in the sequence passed as a parameter) so that the last Boolean of the sub-sequence is "false" and the next Boolean has the "true" value. The sub-sequence must be minimal (it must not contain a "false" "true" sequence). If the conditions are not fulfilled, create a group with the remaining values. |
First group value |
|
toChangeInNo |
Groups together Booleans belonging to the same sub-sequence (consecutive Boolean values in the sequence passed as a parameter) so that the last Boolean of the sub-sequence is "true" and the next Boolean has the "false" value. The sub-sequence must be minimal (it must not contain a "true" "false" sequence). If the conditions are not fulfilled, create a group with the remaining values. |
First group value |
|
everyYes |
Groups together Booleans belonging to the same sub-sequence (consecutive Boolean values in the sequence passed as a parameter) so that the last Boolean of the sub-sequence is "true". The sub-sequence must be minimal (it cannot contain more than one "true"). If the conditions are not fulfilled, create a group with the remaining values. |
First group value |
|
everyNo |
Groups together Booleans belonging to the same sub-sequence (consecutive Boolean values in the sequence passed as a parameter) so that the last Boolean of the sub-sequence is "false" and the next Boolean has the "true" value. The sub-sequence must be minimal (it cannot contain more than one "false"). If the conditions are not fulfilled, create a group with the remaining values. |
First group value |
|
toTheNextYes |
Groups together Booleans belonging to the same sub-sequence (consecutive Boolean values in the sequence passed as a parameter) so that the first Boolean of the sub-sequence has the "true" value. The sub-sequence must be minimal (it cannot contain more than one "true". In addition, it may contain no "true" if the sequence starts with "false" for example). If the conditions are not fulfilled, create a group with the remaining values. |
First group value |
|
toTheNextNo |
Groups together Booleans belonging to the same sub-sequence (consecutive Boolean values in the sequence passed as a parameter) so that the first Boolean of the sub-sequence has the "false" value. The sub-sequence must be minimal (it cannot contain more than one "false"). In addition, it may contain no "false" if the sequence starts with "true" for example). If the conditions are not fulfilled, create a group with the remaining values. |
First group value |
↑ Top of page
Named group
A named group is used to group together values according to one or more dependency criteria (multicriteria). Unlike a typed group:
- The named group can be used for all simple types of the key (Boolean/Date/Time/Date-time/Number/String).
- The named group has a unique name defined by the user.
- The named group has an associated value which is a label defined by the user (alphanumeric string): this text may act as a "title" when displaying the ordered sequence.
- The named group has an order which is defined by the user: the ordering of a sequence by named groups generally involves the creation of several groups, and the user is responsible for the order of these groups (no group "sort" like with typed groups).
- According to the type of criteria defined by the user, an element may belong to no named group. In this case, the user can choose to:
- not process it: this element will not be present in the ordered sequence and will not be processed when browsing this sequence in the groupList macro (so not displayed),
- place it in a special named group, called "other". This group is always the last of the named groups. The element will be processed like the other elements when browsing this sequence in the groupList macro,
- place it in a new group which will contain only this element. The new group is inserted at the end of the list of named groups. The element will be processed like the other elements when browsing this sequence in the groupList macro.
↑ Top of page
The named groups are created by browsing the sequence (use of the natural browsing order). During browsing, each element is tested to find out which named group it belongs to: the first named group (in the list of named groups) with a valid grouping criterion is chosen if it exists. Otherwise the element is processed as specified by the user (see above).
Dependency criterion
This depends on the key type. Several criteria may be associated to define a named group. In this case, for an element to belong to a named group, the criterion just has to be verified. Depending on the criterion type, the user must supply one or more literal values of the same type as the key to complete the criterion description. Each criterion is described in the following table:
Criterion |
Description |
Values to supply |
|
String type | |||
|
isAnyValue |
Criterion verified whatever the alphanumeric value |
None |
|
isEqualTo |
Criterion verified if the alphanumeric value is equal to the eqValue value |
eqValue (alphanumeric value) |
|
isNotEqualTo |
Criterion verified if the alphanumeric value is different from eqValue |
eqValue (alphanumeric value) |
|
isAmong |
Criterion verified if the alphanumeric value is in the seqValues sequence |
seqValues (alphanumeric value sequence) |
|
isNotAmong |
Criterion verified if the alphanumeric value is not in the seqValues sequence |
seqValues (alphanumeric value sequence) |
|
isLessTo |
Criterion verified if the alphanumeric value is strictly lower than lessValue |
lessValue (alphanumeric value) |
|
isLessOrEqualTo |
Criterion verified if the alphanumeric value is lower than or equal to lessValue |
lessValue (alphanumeric value) |
|
isGreaterTo |
Criterion verified if the alphanumeric value is strictly higher than greaterValue |
greaterValue (alphanumeric value) |
|
isGreaterOrEqualTo |
Criterion verified if the alphanumeric value is higher than or equal to greaterValue |
greaterValue (alphanumeric value) |
|
isBetween |
Criterion verified if the alphanumeric value is between minValue and maxValue |
minValue and maxValue (alphanumeric values) |
|
isNotBetween |
Criterion verified if the alphanumeric value is not between minValue and maxValue |
minValue and maxValue (alphanumeric values) |
|
startWith |
Criterion verified if the alphanumeric value starts with one of the values in the seqValues sequence |
seqValues (alphanumeric value sequence) |
|
doNotStartWith |
Criterion verified if the alphanumeric value does not start with one of the values in the seqValues sequence |
seqValues (alphanumeric value sequence) |
|
isLike |
Criterion verified if the alphanumeric value satisfies at least one of the "regular expressions" in the seqValues sequence |
seqValues (alphanumeric value sequence). In the alphanumeric string representing a "regular expression", |
|
isNotLike |
Criterion verified if the alphanumeric value does not satisfy any of the "regular expressions" in the seqValues sequence |
seqValues (alphanumeric value sequence). In the alphanumeric string representing a "regular expression", |
Number/Date/Time/Date-time type | |||
|
isAnyValue |
Criterion verified whatever the value |
None |
|
isEqualTo |
Criterion verified if the value is equal to the eqValue value |
eqValue (a value) |
|
isNotEqualTo |
Criterion verified if the value is different from eqValue |
eqValue (a value) |
|
isAmong |
Criterion verified if the value is in the seqValues sequence |
seqValues (value sequence) |
|
isNotAmong |
Criterion verified if the value is not in the seqValues sequence |
seqValues (value sequence) |
|
isLessTo |
Criterion verified if the value is strictly lower than lessValue |
lessValue (a value) |
|
isLessOrEqualTo |
Criterion verified if the value is lower than or equal to lessValue |
lessValue (a value) |
|
isGreaterTo |
Criterion verified if the value is strictly higher than greaterValue |
greaterValue (a value) |
|
isGreaterOrEqualTo |
Criterion verified if the value is higher than or equal to greaterValue |
greaterValue (a value) |
|
isBetween |
Criterion verified if the value is between minValue and maxValue |
minValue and maxValue (two values) |
|
isNotBetween |
Criterion verified if the value is not between minValue and maxValue |
minValue and maxValue (two values) |
Boolean type | |||
|
isAnyValue |
Criterion verified whatever the "true"/"false" value |
None |
|
isTrue |
Criterion verified if the value is "true" |
None |
|
isFalse |
Criterion verified if the value is "false" |
None |
↑ Top of page
Ordering information
In the groupList macro, the information on the ordering process(es) to apply is carried by the orderingCriteria parameter. It must be Hash or Hash Sequence type. Each Hash object describes an ordering process. It must have the following attributes:
- name: group name (alphanumeric string). It must be unique and is used to reference a group in the groupHeader and groupFooter macros. This attribute is mandatory,
- colName: name of the key in "dot" notation (alphanumeric string). This attribute is mandatory,
- order: sorting order (alphanumeric string). The possible values are:
- "a": ascending order,
- "d": descending order,
- "o": original order (order is not changed).
- "s": specified order.
Values "a", "d" and "s" define "sorted groups"-type ordering. The last value defines "named groups"-type ordering. This attribute is optional: its default value is "a".
- groupCriteria: (alphanumeric string) defines the dependency criterion for "sorted groups"-type ordering when the colName type is Boolean/Date/Time/Date-time. Also used as a criterion when ordering is "named groups" type and the named group "other" has the "ownGroups" grouping property. This attribute is optional: its default value is "week" when the colName type is Date/Date-time; "second" when the colName type is Time and "everyChange" when the colName type is Boolean.
- namedGroups: named group or named group sequence (Hash or Hash Sequence). This attribute is only taken into account if the "order" attribute is "s". Each named group is a Hash object with the following attributes:
- name (alphanumeric string): named group name. It must be unique and is used to reference a group named in the groupHeader and groupFooter macros. This attribute is optional.
- label: named group title (alphanumeric string). It can be displayed in the groupHeader and groupFooter macros. This attribute is optional.
- criteria: criterion/criteria for belonging to the named group (Hash or Hash Sequence). This attribute is mandatory (a named group must have at least one dependency criterion). Each criterion is a Hash object with the following attributes:
- name: criterion name (alphanumeric string). This attribute is mandatory.
- values: values associated with the criterion to calculate its validity (colName type or ColName-type sequence). This attribute is optional.
- otherGroup: definition of the properties of the group called "other" (Hash). This attribute is mandatory if "order" is "s". This named group is a Hash object with the following attributes:
- grouping: grouping type (alphanumeric string). This attribute is mandatory. The possible values are:
- "ignore": the elements of this group are not processed by the macro,
- "oneGroup": the elements are part of the same "other" group,
- "ownGroups": each element belongs to a sorted group (original order and default dependency criterion according to the colName type).
- label: "other" group title (alphanumeric string). It can be displayed in the groupHeader and groupFooter macros. This attribute is optional.
- grouping: grouping type (alphanumeric string). This attribute is mandatory. The possible values are:
<#macro groupList dataList sortingGroup>
Empty directive: No
Parameters
Hash sequence |
seqData |
Hash object sequence to order |
Mandatory |
Hash/Hash sequence |
orderingCriteria |
Hash object or Hash object sequence defining the ordering processes to apply to seqData. The user can define a single ordering process (Hash object) for several (Hash object sequence) |
Mandatory |
For example
<#assign myData = [{"name": "Franck", "age": 19 }, {"name": "Alice", "age": 22 }, {"name": "Paul", "age": 15 } ] /> <#assign orderingCriteria = [{"name": "ascending_order_by_age", "colName": "age"}, {"name": "descending_order_by_name", "colName": "name", "order": "d"} ] /> <@hardisAdv.groupList myData orderingCriteria ; aPerson> Hello ${aPerson.name}! You have ${aPerson.age} years old. </@hardisAdv.groupList>