Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
former_member182862
Active Contributor

Introduction

sap.ui.table.Table is commonly used in OpenUI5 desktop application. Many questions (related to this control) that are posted in this group, it is evident that documentation for this control is lacking and we (developers) have to dive deep into debugging its source code to figure things out. It is fortunate that Javascript source code is always available; modern browsers provide debugging capability and personally, I am fortunate to have the opportunity to work with someone in SAPUI5 team while using this control. Hence it is an opportunity for me to contribute back to the community on what I have learned about this control.

I am assuming that reader of this document has some basic understanding of OpenUI5. The person understands what is OpenUI5 control, model and model binding. Please ask questions if you have any and I (the community experts) will try answer them. I am hoping that I can keep this as a live document where I can constantly receive feedback and update it.

In this document, we show

  1. A sample JSON model where we are use it our sample code;
  2. Some code snippet on how to instantiate a table
  3. Creating columns and binding of rows
  4. Getting context of selected row(s),
  5. Two ways binding of model and control

Sample JSON Model

  var naughtyList = [
    {lastName: "Dente", name: "Al", stillNaughty: true},
    {lastName: "Friese", name: "Andy", stillNaughty: true},
    {lastName: "Mann", name: "Anita", stillNaughty: false}
  ];

  var oModel = new sap.ui.model.json.JSONModel();
  oModel.setData(naughtyList);

Instantiate a table

It can be as simple as

var oTable = new sap.ui.table.Table();

where we inherit all the default properties from the control. Please refer to the official doc for reference.

There are a few properties that I hope to explain a little more.

SelectionMode (API)

Example

var oTable = new sap.ui.table.Table({
    selectionMode : sap.ui.table.SelectionMode.Single
});

Here you can control the selection mode such as None (disable selection), Single (maximum one row can be selected at any time) and Multi (one or more rows can be selected) . Default is Multi

SelectionBehavior (API)

Example

var oTable = new sap.ui.table.Table({
    selectionBehavior: sap.ui.table.SelectionBehavior.Row
});

Here you can control how the row can be selected such as RowOnly (mouse click on the row only), Row (mouse click on the row and row selector) and RowSelector (mouse click on the row selector only). Default is RowSelector.

Create columns and bind rows

Here is an example of how you can do these.

  // instantiate the table
  var oTable = new sap.ui.table.Table({
    selectionMode : sap.ui.table.SelectionMode.Single,
    selectionBehavior: sap.ui.table.SelectionBehavior.Row
  });

  // define the Table columns and the binding values
  oTable.addColumn(new sap.ui.table.Column({
    label: new sap.ui.commons.Label({text: "Last Name"}),
    template: new sap.ui.commons.TextView({text:"{lastName}"})
  }));

  oTable.addColumn(new sap.ui.table.Column({
    label: new sap.ui.commons.Label({text: "First Name"}),
    template: new sap.ui.commons.TextField({value: "{name}"})
  }));

  oTable.addColumn(new sap.ui.table.Column({
    label: new sap.ui.commons.Label({text: "Still Naughty"}),
    template: new sap.ui.commons.CheckBox({checked: '{stillNaughty}'})
  })); 

  oTable.setModel(oModel);
  oTable.bindRows("/");
  oTable.placeAt("content");

Observe that we do bindRows("/"), this is because we have the JSON model containing an array.

oModel.setData(naughtyList);

But if your model is created in this manner,

oModel.setData({'mydata' : naughtyList});

Then you need to do bindRows('/mydata');

And if your data is modified to

  var naughtyList = [
    {lastName: "Dente", name: "Al", stillNaughty: 'true'},
    {lastName: "Friese", name: "Andy", stillNaughty: 'true'},
    {lastName: "Mann", name: "Anita", stillNaughty: 'false'}
  ];

where stillNaugthy is a string and not a boolean. We can adapt to this with this change in the column definition

  oTable.addColumn(new sap.ui.table.Column({
    label: new sap.ui.commons.Label({text: "Still Naughty"}),
    template: new sap.ui.commons.CheckBox({
      checked: {
        path: 'stillNaughty',
        formatter: function(v) {
          return (v === 'true')
        }
      }
    })
  }));

There are many things that you can do with formatter function. For instance if you want to display the first and last name together uppercase the last name. we can do this. (Example)

  oTable.addColumn(new sap.ui.table.Column({
    label: new sap.ui.commons.Label({text: "Name"}),
    template: new sap.ui.commons.TextView(
      {text:
       {
         parts : ['name', 'lastName'],
         formatter: function(n, l) {
           if (n && l) {
             return n + ', ' + l.toUpperCase();
           }
         }
       }
      }
    )
  }));

Getting context of selected row(s),

Here come the interesting part of this document because many questions are asked related to this topic.

Single Selection Mode

When a row is selected or deselected, a rowSelectionChange event is fired. And here is how we deal with it. And below this is main code.

  var oTable = new sap.ui.table.Table({
    selectionMode : sap.ui.table.SelectionMode.Single,
    rowSelectionChange: function(e) {
      var idx = e.getParameter('rowIndex');
      if (oTable.isIndexSelected(idx)) {
        var cxt = oTable.getContextByIndex(idx);
        var path = cxt.sPath;
        var obj = oTable.getModel().getProperty(path);
        console.log(obj);       
      }
    }
  });

Here (in the code), we can get the selected or deselected row; then we use the isIndexSelected function to check if it is selected or deselected. And by getting the context and path, we are able to get the binding object itself.

Please note that if row 1 is already selected and now user select row #2, this event will not fire for that deselection of row #1, an event will be fired for selection of row #2.

Multi Selection Mode

When one or more rows are selected or deselected, the same rowSelectionChange event will be fired. And here is how we deal with it. And below this is main code.

  var oTable = new sap.ui.table.Table({
    selectionMode : sap.ui.table.SelectionMode.Multi,
    rowSelectionChange: function(e) {
      var indices = e.getParameter('rowIndices');
      for (var i = 0; i < indices.length; i++) {
        var idx = indices[i];
        if (oTable.isIndexSelected(idx)) {
          var cxt = oTable.getContextByIndex(idx);
          var path = cxt.sPath;
          var obj = oTable.getModel().getProperty(path);
          console.log(obj);       
        }
      }
    }
  });

Here (in the code), we can get the selected or deselected rows; then we iterate through the array and use the isIndexSelected function to check if it is selected or deselected. And by getting the context and path, we are able to get the binding object itself. This piece of code is almost identical to the code snippet in the single selection mode except for getting an array of selected indices.

Selection None Mode and Select by control in row

You can also identify the row and context with button, checkbox, etc. in the row. Here is an example.

  oTable.addColumn(new sap.ui.table.Column({
    label: new sap.ui.commons.Label({text: "Still Naughty"}),
    template: new sap.ui.commons.CheckBox({
      checked: {
        path: 'stillNaughty',
        formatter: function(v) {
          return (v === 'true')
        }
      },
      change: function(e) {
        var path = e.getSource().getBindingContext().sPath;
        var obj = oTable.getModel().getProperty(path);
        alert(JSON.stringify(obj));
       
        var index = parseInt(path.substring(path.lastIndexOf('/')+1));
        alert(index);
      }
    })
  }));

Two ways binding of model and control

One of the beauty of OpenUI5 is the binding between model and control. In our example here (Check and uncheck the checkbox and then click on Show button to see that current data in the model), we are able to bind the checkbox value to the model effortlessly. You can also bind any controls such as textfield, radio button, etc in the table.

However if you use the formatter function to alter the value before displaying it then you need to update the model manually like this. And below this is main code.

  oTable.addColumn(new sap.ui.table.Column({
    label: new sap.ui.commons.Label({text: "Still Naughty"}),
    template: new sap.ui.commons.CheckBox({
      checked: {
        path: 'stillNaughty',
        formatter: function(v) {
          return (v === 'true')
        }
      },
      change: function(e) {
        var path = e.getSource().getBindingContext().sPath;
        var obj = oTable.getModel().getProperty(path);
        obj.stillNaughty = this.getChecked()
      }
    })
  }));

Closing

I hope that I have covered enough on the basic things on sap.ui.table.Table control. Please let me know if you have questions or comments; or let me know about things that I have missed out.

Thanks

-D

20 Comments