Search code examples
jsonodatasapui5

SAPUI5 TreeTable - flat OData


i have an issue or lack of idea how to build TreeTable from flat OData data. The data looks like this (columns):

  • Document Number,
  • Year,
  • Month,
  • Status,
  • several more columns

The hierarchy should like like this:

DOCUMENT
`- YEAR
    `- Month
        `- STATUS 1
            - data for status 1 #1
            - data for status 1 #2
        `- STATUS 2
            - data for status 2 #1
            - data for status 2 #2

ODATA returns: 
DOCUMENT | YEAR | MONTH | STATUS1 | Data for status 1 #1
DOCUMENT | YEAR | MONTH | STATUS1 | Data for status 1 #1
DOCUMENT | YEAR | MONTH | STATUS2 | Data for status 2 #1
DOCUMENT | YEAR | MONTH | STATUS2 | Data for status 2 #2

The question would be - is there any callback function/whatever i could use in order to reorganize the data for example by putting it in JSON format ? Or any other Idea ?

I have a CDS View and generated OData behind, so need to do this in UI5. Any help would be highly appreciated !

Cheers

Kubas


Solution

  • If as you said there should be an edit possibility for the table, you can use a stanard TreeTable OData binding, but the backend must provide you the hierarchical data (it will cost nothing to implement the editability due to standard two-way binding), in your case the OData structure will look like this:

    [
        {
            ID: "",
            NodeID: 1,
            type: "document",
            title: "",
            HierarchyLevel: 1,
            ParentNodeID: null
        },
        {
            ID: "",
            NodeID: 2,
            type: "year",
            title: "",
            HierarchyLevel: 2,
            ParentNodeID: 1
        },
        {
            ID: "",
            NodeID: 3,
            type: "month",
            title: "",
            HierarchyLevel: 3,
            ParentNodeID: 2
        },
        {
            ID: "",
            NodeID: 4,
            type: "status",
            title: "",
            HierarchyLevel: 4,
            ParentNodeID: 3
        },
        {
            ID: "",
            NodeID: 5,
            type: "data for status",
            data: {},
            title: "",
            HierarchyLevel: 5,
            ParentNodeID: 4
        }
    ]
    

    If there is no chance for the backend to provide such structure, you can parse your backend response and construct JSON model (the parsing will be just for a grouping reasons, you need to group your flat structure into the hierarchical considering the keys: document ids, years, months, statuses..).

    JSON data structure:

    [
        {
            DocumentId: "",
            items: [
                {
                    year: "",
                    items: [
                        {
                            month: "",
                            items: [
                                {
                                    status: ""
                                }
    
                            ]
                        }
                    ]
                }
            ]
        }
    ]
    

    But this JSON-approach makes harder to track the changes to be send to the backend side. So the task is to find the nodes that were changed by the user and here you can think about making the diff between original parsed data and the data in a state after the changes applied by the user. Or you can keep a kind of a map of the changes user made to the document id's and turn this data into the odata calls once user wants to submit the changes.

    UPD 1:

    Implementation of "lazy loading" for the tree structure that is defined by the flat one (via backend) will be problematic. Because to my understanding, the lazy loading for the tree will look like the following:

    initially UI loads all the items from the 1-st level. Then after clicking on the "expand" button of th 1st level, UI makes a call to fetch the 2nd level and so on.

    The lazy loading for the "flat" list works differently, while user scrolling the table down and reaches the very bottom side (based on the "threshold" property), table can request more data via new $skip & $top properties in OData call.

    So I'm afraid that it won't be possible to make the lazy loading without property tree structure from backend.

    Possible workaround might be providing a kind of a filter to reduce amount of items.

    As to your question about "where to put this parsing" - you need to perform the "read" request manually in the controller, then in "success" method call the parsing, then construct JSONModel based on parsed data and finally bind the table to this model.