Skip to main content

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 via favoriteActionGroup1–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

PropertyValue
defaultGroupFieldsCONTEXT_NAME
iconFieldICON
titleFieldTITLE
descriptionFieldDATE
favoriteActionGroup2newModule
showChildrenCounttrue

TreeTable

The TreeTable ViewTemplate displays datasets in a table with grouping functionality. Rows represent datasets, columns represent EntityFields.

note

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 to true (which, in turn, is only possible, if property parentField is set).
note

If using drag-and-drop, LexoRank is recommended for ordering. See chapter LexoRank.

Appearance in the Client

An example is "ActivitiesTreeTable" from ActivityFilter_view.

TreeTable

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

PropertyValue
columnsentryDateDateFormat, #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

Tree Properties
Figure: Property configuration for Tree

PropertyDescription
entityFieldUsually #ENTITY if multiple EntityFields are used
linkedColumnsDefines fields used to link to the MainView
parentFieldStores the UID of the parent node; defines the tree structure
informationFieldDisplays additional information at the top of the node
nodeExpandedFieldBoolean field to control initial open/closed state of nodes
titleFieldTitle of the node (commonly the name)
descriptionFieldSecond row of info (e.g., date, status)
iconFieldIcon or initials shown on the left. Accepts #IMAGE, #ICON, predefined icon names, or Base64
defaultGroupFieldsGrouping fields used by default
fixedFilterFieldsRestricts filter options to a defined set of fields
expandRootItemsIf true, expands all root nodes by default
warning

If used without paging, enabling expandRootItems will load all items at once — may degrade performance.


TreeTable Properties

Tree Table Properties
Figure: Property configuration for TreeTable

PropertyDescription
entityFieldUsually #ENTITY
columnsDefines the columns to be shown per entry
linkedColumnsEnables record navigation to MainView
parentFieldStores parent UID; defines the tree hierarchy
informationFieldOptional top-line information
defaultGroupFieldsSee Tree
fixedFilterFieldsSee Tree
expandRootItemsSee Tree
tip

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

  1. 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
  2. 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:

PropertyValue
entityField#ENTITY
parentFieldPARENT
titleFieldTITLE

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.