How to build an expandable sap.m.Table in sapui5?

8k views Asked by At

I am searching for a kind of TreeTable that uses sap.m.Table as base. My first "hack" looks like this:

Experimental data model:

var oModel = new sap.ui.model.json.JSONModel({
    "Items" : [
               {"Name" : "A", "SubItems" : [
                                            {"Name" : "A.1" },
                                            {"Name" : "A.2" },
                                            {"Name" : "A.3" },
                                           ]
               },
               {"Name" : "B", "SubItems" : [
                                            {"Name" : "B.1" }
                                           ]
               },
               ]
});
this.getView().setModel(oModel, "expand");

Experimental Table implementation:

var oContent = new sap.m.Table({      
              items : {
                path : "expand>/Items",
                template : new sap.m.ColumnListItem({
                  customData : [ new sap.ui.core.CustomData({
                            key : "SubItems",
                            value : "SubItems",
                            customData : {
                              path : "expand>SubItems",
                              template : new sap.ui.core.CustomData({
                                key : this.createId("subItem"),
                                value : new sap.m.ColumnListItem({
                                  cells : [
                                           new sap.m.Text({
                                             text: "{expand>Name}",
                                           })
                                           ]
                                })
                              })
                            }
                          })                          
                        ],
                  type : sap.m.ListType.Active,
                  cells: [
                            new sap.m.Text({ text: "{expand>Name}" }),
                          ],
                  press : [function(oEvent) {
                    var oRow = oEvent.getSource();
                    var oTable = oRow.getParent();
                    var oItems = oTable.getItems();

                    var insertIndex = -1;
                    var oSubItemsData = undefined;

                    for (var i=0;i<oItems.length;i++) {
                      if (oItems[i]==oRow) {
                        oSubItemsData = oRow.getAggregation("customData").filter(function(oData) {return oData.getProperty("key") == "SubItems";});
                        insertIndex = i;
                      }
                    }

                    var oSubItems = oSubItemsData[0].getAggregation("customData").map(function(oData) {return oData.getValue();});
                    for (var j=0;j<oSubItems.length;j++) {
                      var mShownSubItems = oItems.filter(function(oShownItem) {
                        return oShownItem == oSubItems[j];
                      });
                      if (mShownSubItems.length>0) {
                        console.log("removing"+j);
                        oTable = oTable.removeItem(oSubItems[j]);
                      } else {
                        console.log("adding "+(insertIndex+j+1));
                        oTable = oTable.insertItem(oSubItems[j],insertIndex+j+1);
                      }                          
                    }                        
                  }, oController]
                })
              },
              columns : [ new sap.m.Column({}) ],
    });

I figured out different problems with this "hack". First of all the binding of the SubItems is not displayed, if I use hard coded text the text is shown. Second problem is, that I can only insert exactly one row.

How can this be solved?

2

There are 2 answers

1
qmacro On

You may be interested in the Table - Breadcrumb sample in Explored. It uses sap.m.Table as a base and can display a hierarchy of data, in a tree table kind of style.

0
Fenerski Dimitar On

I have bumped into the same issue and I've solved it by using a sap.m.Panel as a sap.m.CustomListItem aggregation of the sap.m.List. If you wish to expand it by clicking anywhere on the row (collapsed Panel) and not only on the Panel's expand Button, you could get the aggregation go trough a factory, which can do something like this

var oUIControl = this.byId("custItem").clone(sId);
        var oPanel = oUIControl.getContent()[0];
        oPanel.addEventDelegate({
            onclick: function (e) {
                try {
                    if (sap.ui.getCore().byId(e.target.id).getMetadata().getElementName() !== "sap.ui.core.Icon") {
                        oPanel.setExpanded(!oPanel.getExpanded());
                    }
                } catch (e) {
                    oPanel.setExpanded(!oPanel.getExpanded());
                }
            }
        });
        return oUIControl;

The check is needed because without it the click event is fired twice when clicking on the expand button itself. With it we trigger custom click event when the user clicks anywhere else on the panel row.