Tree/TreeTable
Tree and TreeTable
The Tree
and TreeTable
ViewTemplates allow the visualization of hierarchical data structures. Both ViewTemplates serve similar purposes but differ in layout and interaction. This chapter explains their functionality, configuration, and implementation.
Tree
The Tree
ViewTemplate displays datasets grouped in a hierarchical structure with fixed fields at designated positions.
Functional Overview
- Grouping: Controlled via
defaultGroupFields
- Leaf Entries: Configurable title (
titleField
), description (descriptionField
), and icon (iconField
) - Action Buttons: Up to three
ActionGroup
buttons can be added viafavoriteActionGroup1–3
- Children Count: Optional display via
showChildrenCount
- Client Filtering: Grouping can be changed by users using the "Filter" dialog
Appearance in the Client
An example instance of the Tree ViewTemplate is "Tree"
, assigned to 360DegreeFilter_view
.
It is used in the MainView
of contexts such as "Company"
under:
Contact Management > Company > [Select Company] > 360 Degree
Group nodes are displayed by context name, and their entries include icons, titles, and dates.
Configuration Example
Property | Value |
---|---|
defaultGroupFields | CONTEXT_NAME |
iconField | ICON |
titleField | TITLE |
descriptionField | DATE |
favoriteActionGroup2 | newModule |
showChildrenCount | true |
TreeTable
The TreeTable
ViewTemplate displays datasets in a table with grouping functionality. Rows represent datasets, columns represent EntityFields.
TreeTable is typically used in Filter Views, in order to enable grouping.
Functional Overview
- Columns: Configured via the
columns
property - Grouping: Defined using
defaultGroupFields
- Drag & Drop: Supported if
enableDragAndDrop
is set totrue
(which, in turn, is only possible, if propertyparentField
is set).
If using drag-and-drop, LexoRank is recommended for ordering. See chapter LexoRank.
Appearance in the Client
An example is "ActivitiesTreeTable"
from ActivityFilter_view
.
It can be accessed via:
Contact Management > Activity > Select "Treetable" via the ViewSelectionButton in the upper right corner. Then, configure a grouping in the filter component, e.g., for the EntityField "Category".
It displays several columns including date, image, responsible person, subject, and description.
Configuration Example
Property | Value |
---|---|
columns | entryDateDateFormat , #IMAGE , RESPONSIBLE , SUBJECT , INFO |
Tree and TreeTable: Advanced Configuration
Both ViewTemplates rely on similar principles and differ only in field layout. The TreeTable
adds tabular display support.
They typically use a JDitoRecordContainer
. If the data is prestructured, a DatabaseRecordContainer
can be used.
Tree Properties
Figure: Property configuration for Tree
Property | Description |
---|---|
entityField | Usually #ENTITY if multiple EntityFields are used |
linkedColumns | Defines fields used to link to the MainView |
parentField | Stores the UID of the parent node; defines the tree structure |
informationField | Displays additional information at the top of the node |
nodeExpandedField | Boolean field to control initial open/closed state of nodes |
titleField | Title of the node (commonly the name) |
descriptionField | Second row of info (e.g., date, status) |
iconField | Icon or initials shown on the left. Accepts #IMAGE , #ICON , predefined icon names, or Base64 |
defaultGroupFields | Grouping fields used by default |
fixedFilterFields | Restricts filter options to a defined set of fields |
expandRootItems | If true , expands all root nodes by default |
If used without paging, enabling expandRootItems
will load all items at once — may degrade performance.
TreeTable Properties
Figure: Property configuration for TreeTable
Property | Description |
---|---|
entityField | Usually #ENTITY |
columns | Defines the columns to be shown per entry |
linkedColumns | Enables record navigation to MainView |
parentField | Stores parent UID; defines the tree hierarchy |
informationField | Optional top-line information |
defaultGroupFields | See Tree |
fixedFilterFields | See Tree |
expandRootItems | See Tree |
TreeTable builds on Tree’s functionality. Read Tree configuration first.
Tree Building Logic
Tree/TreeTable requires correct ordering of nodes:
Parent entries must be added before their children. This rule also applies when using a DatabaseRecordContainer
.
Strategies
-
Layer-by-layer
Add data sequentially per hierarchy level. Ideal for known levels like:- Level 1: Organisation
- Level 2: Persons with function
- Level 3: Activities linked to persons
-
Recursive
For unknown or variable depths. Start from root nodes, then recurse to fetch children until no further descendants exist.
Example: Tree of Organisations and Persons
This example builds a Tree showing organisations and their associated persons.
Setup
- Entity:
OrgTree_entity
- Fields:
UID
,PARENT
,TITLE
- Context:
OrgTree
- View:
OrgTree_view
with Tree ViewTemplate
Configure ViewTemplate:
Property | Value |
---|---|
entityField | #ENTITY |
parentField | PARENT |
titleField | TITLE |
Register Context in menu:
application > ____SYSTEM_APPLICATION_NEON
JDitoRecordContainer contentProcess
import { result } from "@aditosoftware/jdito-types";
import { newSelect } from "SqlBuilder_lib";
// Fetch person data
var personData = newSelect("CONTACTID, FIRSTNAME, LASTNAME, ORGANISATION_ID")
.from("PERSON")
.join("CONTACT", "PERSONID = PERSON_ID")
.where("ORGANISATION_ID is not null")
.and("PERSON_ID is not null")
.table();
// Fetch organisation data
var orgData = newSelect("CONTACTID, ORGANISATIONID, NAME")
.from("ORGANISATION")
.join("CONTACT", "ORGANISATIONID = ORGANISATION_ID")
.where("ORGANISATION_ID is not null")
.and("PERSON_ID is null")
.table();
// Normalize parent-child references
for (let i = 0; i < orgData.length; i++) {
for (let j = 0; j < personData.length; j++) {
if (personData[j][3] === orgData[i][1]) {
personData[j][3] = orgData[i][0]; // Replace ORG ID with CONTACT ID
}
}
}
// Build result array
var res = [];
// Add organisations first
for (let i = 0; i < orgData.length; i++) {
res.push([orgData[i][0], null, orgData[i][2]]);
}
// Add persons under org nodes
for (let i = 0; i < personData.length; i++) {
res.push([
personData[i][0],
personData[i][3],
personData[i][1] + " " + personData[i][2]
]);
}
// Return result
result.object(res);
Final Steps
- Configure
recordFieldMappings
in the RecordContainer:UID.value
PARENT.value
TITLE.value
- Deploy changes and test in the ADITO web client.