It seems that everybody understand hierarchies but it is sometimes difficult to handle them, be it
- Defining them,
- Building them or
- Rearranging them,
- Not to speak about the whole stuff in the UI.
This document want to shed some light on these tasks. 😀
Let’s first spent some words on “What is a Hierarchy”
Hierarchy as a Tree in Graph Theory
We will focus here on those special hierarchies in which the vertices have one or zero parents and one or many children which in turn are called Tree.
Second no cycles are permitted. Therefore following the Parent relationship we will reach some vertex without a parent which we will call Root. If we follow the Children relationship to the vertices without children these are the Leaves.
All vertices which can be reached starting from the Root vertex via the Children relationship are belonging to the same Tree (= Hierarchy).
Defining a Tree Hierarchy in BODL
Of course the vertexes are the nodes and the relationships are the associations. 😀
As the Children association has the multiplicity “to-many” we cannot use the normal Alternative Key based associations as these have the multiplicity “to-one”. Instead we had to use the addition “valuation”. As result we can only target nodes from the own Business Object.
There are two different ways to implement such a Tree Hierarchy:
- You can define the associations on the root node of the Business Object.
This means that the target is also the root node, but of another Business Object instance.
So the vertexes are different Business Object instances like the hierarchy defined by the Business Object InstallationPoint.
- You can define the associations on a sub-node of the Business Object.
Here the Business Object itself represents the hierarchy as a whole and all the sub-nodes define the hierarchy like in the Business Object ProductCategoryHierarchy.
For the sake of convenience we will work with the second approach here.
So here’s the BODL for the Tree hierarchy:
At the Root node of the Business Object we define some information about the root of Tree hierarchy like the association which can be used later as the entry point for traversing the hierarchy.
The node Vertex defines the hierarchy itself:
- The own identifier of the Vertex node.
Please note that we did not use this identifier as Alternative Key because in that case we cannot use this value in any other hierarchy. We would need to combine it with the identifier of the whole Tree hierarchy.
- The identifier of the own parent node.
This value will be empty for the Root vertex of the hierarchy
- The element HasKidsIndicator is needed later in the UI to determine if the expand / collapse icon shall be displayed for this entry.
- Of course the associations Parent and Children based on the relationship between the own parent identifier and the identifier of the target node realizes in the valuation clause.
Adding some ABSL Code to Ensure Consistency
We will add an AfterModify script to the Root node of the Business Object to ensure that the root vertex of the Tree hierarchy is existing
And we add also an AfterModify script to the Vertex node to ensure the correct setting of the own HasKidsIndicator which is needed after removing children and also of the parent indicator which in turn is needed after re-arranging of a sub part of the hierarchy.
Define the List as Hierarchy in the UI
First you define the list of the Vertex node instances via an AdvancedListPane, but you add the “HierarchicalExtension” to this list
Second you need to define the bindings for this special structure
This is the result if there are already some vertices maintained. You notice the triangles which tells you that this vertex has children and if the children are visible. Technically spoken: The vertex is collapsed or expanded.
The vertex has no children if there is only a square shown.
You should not show the technical fields like “HasKidsIndicator” or “ParentId”, because this information is already shown via the graphics.
It may be useful not only to expand or collapse the current vertex by clicking on the triangle but to show or hide the complete hierarchy. This can be achieved by some EventHandlers with List operations, for example “ExpandAll”.
Add a Vertex
Adding an vertex is best done via a modification structure in own pop-up and not inside the hierarchical list.
Please use a data operation before starting the modifications structure which sets the current node as the new parent.
Inside the modification structure let the user only chose the ID and the description of the new vertex
This will prevent such issues like more than one Root vertex.
Delete a Vertex
If you would simple delete the current row, then exact only this would happen. As consequence all children of the current row would lose their parent.
So you need to ensure that on the deletion of a vertex all children (and the children of the children and so on) are deleted too.
This can easily achieved with a small action:
So add the line
to your BO definition and add this ABSL coding:
Which will delete in a recursive call (depth-first approach) the children and finally the current vertex.
Reorganizing Hierarchical Structure
If you want to re-arrange the hierarchy some precautionary measures should be taken:
- Never allow a new parent for the Root vertex
- Ensure that no circles are created
- Verify if the new parent really exists.
Otherwise you would decouple the sub-hierarchy from the rest.
The best way to ensure the later topic is to allow the user to select the new parent from a dropdown listbox. Just define a second list in the data model VertexList which is also bound to the Vertex node
Create a “NewParentId” element which is typed as a Code and bind the code list to this new VertexList using the ID and the Name.
I’ve added an EventHandler to “OnValueChanged” which updates the ParentId of the current selected line and does a Refresh on the VertexHierarchy.
After entering the new parent ID the hierarchy refreshes itself and shows the vertex under the new parent.
Sadly, this worked for me only in HTML5.
Now you should be able to create and modify hierarchies.
That’s all, folks.