Understanding sap.ui.table.Table in 10 minutes
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
- A sample JSON model where we are use it our sample code;
- Some code snippet on how to instantiate a table
- Creating columns and binding of rows
- Getting context of selected row(s),
- 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
Add a section " Selection None Mode and Select by control in row"
Hi,
Can i add a icon like " > " to the row selector button.
Fantastic! An additional section showing a comboBox renderer would be extremely useful as well.
Hi Dennis,
Fantastic Article but I have a query, in the function of selection of row in table: oTable.getModel()....
Iam getting the error ; getModel() is undefined - oTable.getModel(...) is undefined.
Can you please advice?
Hi Rahul
We are unable to figure out the error that you have unless you share your code. I suggest that you create a new discussion and provide more information.
Thanks
-D
Hi Dennis,
Thanks for your reply. I was trying to consume data from odata service into table. I modified your code a bit by passing the model id after which it started working correctly. I modified the code to :
oTable.getModel("EmployeeSet").getProperty(path);
Thanks for your reply 🙂
Hi Rahul
Again, We are unable to figure out the error that you have unless you share your code. I suggest that you create a new discussion and provide more information.
Hi guys,
i am facing below issue can any one help me
selectionMode: sap.ui.table.SelectionMode.Single,
Uncaught TypeError: Cannot read property 'Single' of undefined
Best Regards
Shiva
Hi Shiva
In the example
http://jsbin.com/toqof/1/edit?html,js,output
Look for data-sap-ui-libs='sap.ui.commons,sap.ui.table'
I think you missed it
Thanks
-D
Hi Dennis,
Is there a way to add to a sap.ui.table a custom menu to hide/show [e.g with a popup/checkbox] any of the displayed column in the table ?
Or, does exist a sap.ui.* component to achieve this ?
Regards,
Claudia
HI Claudia
Please take a look at this JsDoc Report - SAP UI development Toolkit for HTML5 - API Reference - sap.ui.table.TablePersoController
look at openDialog function.
Thanks
-D
Hi Dennis,
Thanks for your reply.
I took a look at openDialog function into the documentation you linked
but it seems that function requires sap.m library to work.
Unfortunally in the project I am working on, I am allowed to use sap.ui library only and sap.m is not compatible within the rest of the project [...]
Do you know if using the component smart table is a good alternative way to have the panel I need for the data table ?
Regards,
Claudia
Hi Claudia
I am not certain that smart table can help. You can create a dialog with a list of columns to show/hide easily.
-D
Hi Dennis,
I have a small concern with check box in ui.table. I have a table with around 4000+ records.
And on the selection of check box of each row I'm performing some action. The concern is, if i scroll down to next 10 records, the selected check boxes of previous page are still selected, which is now showing corresponding to new records. I have bound them to a model. It works fine if I refresh the table again.
I want to know is there a way to have fresh new check box for next records also.
Any help would be appreciated.
Thanks,
Ashwin
Hi Ashwin
the checkbox has to bind to a attribute in the model like this
JS Bin - Collaborative JavaScript Debugging
Thanks
-d
Thanks, awesome. I am waiting for new sections.
Hi,
Can i add a icon like " > " to the row selector button.
To All,
Unless you are asking for clarification/correction of some part of the Document, please create a new Discussion marked as a Question. The Comments section of a Blog (or Document) is not the right vehicle for asking questions as the results are not easily searchable. Once your issue is solved, a Discussion with the solution (and marked with Correct Answer) makes the results visible to others experiencing a similar problem. If a blog or document is related, put in a link. Read the Getting Started documents (link at the top right) including the Rules of Engagement.
NOTE: Getting the link is easy enough for both the author and Blog. Simply MouseOver the item, Right Click, and select Copy Shortcut. Paste it into your Discussion. You can also click on the url after pasting. Click on the A to expand the options and select T (on the right) to Auto-Title the url.
Thanks, Mike (Moderator)
SAP Technology RIG
Hi,
I am facing an issue while counting the number of rows in tree table because it also giving me the category row count too.I have tried this code snippet:
tableView.getBinding("rows").getLength() which is giving me the total count along with categories row.and also I want it do this though binding.I want to know is there a way to get row count in tree table without categories.
Thanks in advance.
Hi All,
Can we add two controls in the same column like checkbox and button in the same column using sap.ui.table.Table ?