<table>
<tr>
<th>name</th>
<th>quantity</th>
<th>dateFrom</th>
<th>dateTo</th>
</tr>
<!-- Print entries with from/to dates -->
<#list records?filter(x -> x.custcol_from_date?has_content && x.custcol_to_date?has_content)?sort_by("custcol_to_date")?sort_by("custcol_from_date") as record>
<tr>
<td>${record.name}</td>
<td>${record.quantity}</td>
<td>${record.custcol_from_date}</td>
<td>${record.custcol_to_date}</td>
</tr>
</#list>
<!-- Print entries without from/to date at the end of table -->
<#list records?filter(x -> !x.custcol_from_date?has_content || !x.custcol_to_date?has_content) as record>
<tr>
<td>${record.name}</td>
<td>${record.quantity}</td>
<td>${record.custcol_from_date}</td>
<td>${record.custcol_to_date}</td>
</tr>
</#list>
</table>
Working of the freemarker code:
### Explanation of the Logic and Filter Functionality
The given code is designed to generate an HTML table from a list of records, using FreeMarker Template Language (FTL). The logic filters and sorts the records based on the presence and values of `custcol_from_date` and `custcol_to_date` fields. Let's break down the code step-by-step:
#### HTML Table Structure
```html
<table>
<tr>
<th>name</th>
<th>quantity</th>
<th>dateFrom</th>
<th>dateTo</th>
</tr>
</table>
```
This sets up an HTML table with four columns: `name`, `quantity`, `dateFrom`, and `dateTo`.
#### Printing Entries with Both `from` and `to` Dates
```html
<#list records?filter(x -> x.custcol_from_date?has_content && x.custcol_to_date?has_content)?sort_by("custcol_to_date")?sort_by("custcol_from_date") as record>
<tr>
<td>${record.name}</td>
<td>${record.quantity}</td>
<td>${record.custcol_from_date}</td>
<td>${record.custcol_to_date}</td>
</tr>
</#list>
```
1. **Filter**: `records?filter(x -> x.custcol_from_date?has_content && x.custcol_to_date?has_content)`
- This filters the `records` list to include only those records where both `custcol_from_date` and `custcol_to_date` have content (i.e., are not null or empty).
2. **Sort**: `?sort_by("custcol_to_date")?sort_by("custcol_from_date")`
- The filtered list is sorted first by `custcol_from_date` and then by `custcol_to_date`. The sorting is done twice because FreeMarker's `sort_by` does a stable sort, meaning the first sort order is preserved while applying the second.
3. **List Iteration**: `as record`
- Iterates over the sorted and filtered list, outputting each record as a row in the table.
#### Printing Entries Without `from` or `to` Dates
```html
<#list records?filter(x -> !x.custcol_from_date?has_content || !x.custcol_to_date?has_content) as record>
<tr>
<td>${record.name}</td>
<td>${record.quantity}</td>
<td>${record.custcol_from_date}</td>
<td>${record.custcol_to_date}</td>
</tr>
</#list>
```
1. **Filter**: `records?filter(x -> !x.custcol_from_date?has_content || !x.custcol_to_date?has_content)`
- This filters the `records` list to include only those records where either `custcol_from_date` or `custcol_to_date` (or both) do not have content.
2. **List Iteration**: `as record`
- Iterates over this filtered list, outputting each record as a row in the table.
### Summary
- The first block of code filters records that have both `custcol_from_date` and `custcol_to_date` filled, sorts them by these dates, and displays them in the table.
- The second block of code filters records that are missing either `custcol_from_date` or `custcol_to_date`, and displays them at the end of the table without sorting.
- The use of `?filter` and `?sort_by` functions helps manage the display order and grouping of records based on the specified criteria.