sap.m.Table – Conditional Cell Coloring based on value
Hello All,
Introduction:
The blog Coloring Table Cells Conditionally in SAP UI5 clearly explains you how to color the cells of a table(sap.ui.table.Table) precisely and with neat explanation. But in case of sap.m.Table, it can’t be followed because:
1. sap.ui.table.Table uses bindRows method to bind the table rows.
2. And hence the blog uses getRows method to add style classes conditionally.
For Example : oTable.getRows()[i].$().removeClass(“yellow”);
3. sap.m.Table doesn’t use bindRows method to bind the rows. It is based on “items”.
Step by Step Process:
Create a SAP UI5 project with sap.m library and with an initial view.
index.html looks like below:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>
<script src="resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.m"
data-sap-ui-theme="sap_bluecrystal">
</script>
<!-- only load the mobile lib "sap.m" and the "sap_bluecrystal" theme -->
<script>
sap.ui.localResources("zmtablecolor");
var app = new sap.m.App({initialPage:"idinitialview1"});
var page = sap.ui.view({id:"idinitialview1", viewName:"zmtablecolor.initialview", type:sap.ui.core.mvc.ViewType.JS});
app.addPage(page);
app.placeAt("content");
</script>
</head>
<body class="sapUiBody" role="application">
<div id="content"></div>
</body>
</html>
view looks like below:
*Add oController.createPage() inside the sap.m.Page function; because that will create and return the table *
sap.ui.jsview("zmtablecolor.initialview", {
/** Specifies the Controller belonging to this View.
* In the case that it is not implemented, or that "null" is returned, this View does not have a Controller.
* @memberOf zmtablecolor.initialview
*/
getControllerName : function() {
return "zmtablecolor.initialview";
},
/** Is initially called once after the Controller has been instantiated. It is the place where the UI is constructed.
* Since the Controller is given to this method, its event handlers can be attached right away.
* @memberOf zmtablecolor.initialview
*/
createContent : function(oController) {
return new sap.m.Page({
title: "M Table Colouring",
content: [
oController.createPage()
]
});
}
});
Content Creation:
create a method “createPage” in the controller as shown below:
createPage: function() {
jsonData = [];
jsonData.push({
"Invoice" : "INV1",
"Amount" : 123
});
jsonData.push({
"Invoice" : "INV2",
"Amount" : 84
});
jsonData.push({
"Invoice" : "INV3",
"Amount" : 283
});
var oInvoicesTable = new sap.m.Table("idInvoicesTable", {
//width: tabWidth,
fixedLayout: false,
width : '30%',
growing : true,
inset : true,
headerText : "My Invoice Details",
growingScrollToLoad : true,
columns: [
new sap.m.Column({
//width: "40%",
header: new sap.m.Text({
text: "Invoice"
})
}),
new sap.m.Column({
//width: "30%",
header: new sap.m.Text({
text: "Amount"
})
}),
],
items : {
path: '/modelData',
template: new sap.m.ColumnListItem({
selected: false,
//type: "Active",
cells: [
new sap.m.Text("idColInvoice", {
text: "{Invoice}"
}),
new sap.m.Text("idColAmount", {
text: "{Amount}"
}),
]
})
}}).addStyleClass('sapUiSizeCompact');
var oInvoicesMdl = new sap.ui.model.json.JSONModel();
oInvoicesMdl.setData({modelData : jsonData});
oInvoicesTable.setModel(oInvoicesMdl);
return oInvoicesTable;
}
Now save and run the application; It will show you output as below:
———————————————————————————————————————————————————————————————————
Now, let us see how to color the cell based on below condition:
If amount is less than 100, make it RED.
If amount is greater than or equal to 100 and less than 200, make it YELLOW.
If amount is greater than or equal to 200, make it GREEN.
CSS Styling:
- 1. create a CSS file under webcontent->css folder and name it as style.css(as you wish).
- 2. Paste the below content inside it. This is responsible for coloring the cell.
.green {
background-color: #66FF33;
}
.red {
background-color: #FF3300;
}
.yellow {
background-color: #FFFF66;
}
3. Insert below tag in index.html file.
<link rel="stylesheet" href="css/style.css">
Conditional Formatting:
4. Inside the onAfterRendering function of the controller, we need to write logic to color the cells based on values. It should look like below:
onAfterRendering: function() {
var tabData = sap.ui.getCore().byId("idInvoicesTable").getModel().getData().modelData;
var tabDataLength = tabData.length;
var colId = "";
var colValue = "";
for(var i =0; i<tabDataLength; i++){
colId = "idColAmount-__clone" + i;
colValue = sap.ui.getCore().byId(colId).getText();
colValue = parseInt(colValue);
if(colValue < 100){
sap.ui.getCore().byId(colId).addStyleClass("red");
sap.ui.getCore().byId(colId).removeStyleClass("green");
sap.ui.getCore().byId(colId).removeStyleClass("yellow");
}else if(colValue >= 100 && colValue < 200){
sap.ui.getCore().byId(colId).addStyleClass("yellow");
sap.ui.getCore().byId(colId).removeStyleClass("red");
sap.ui.getCore().byId(colId).removeStyleClass("green");
}else if(colValue >= 200){
sap.ui.getCore().byId(colId).addStyleClass("green");
sap.ui.getCore().byId(colId).removeStyleClass("yellow");
sap.ui.getCore().byId(colId).removeStyleClass("red");
}
}
That’s it. We are done. Now, the output looks like:
———————————————————————————————————————————————————————————————————
Explanation of the above logic:
By this time, you would have understood how it has been achieved. Nevertheless, I will explain the logic – which we have applied in the onAfterRendering function of the controller.
a. Make sure ID has been assigned to the corresponding cell of the table as shown below. Then only the ID is static and known to us definitely.
you can refer method “createPage” given above.
new sap.m.Text("idColAmount", {
text: "{Amount}"
}),
b. So once the table is rendered,
the Amount cell of first row is “idColAmount-__clone0“
the Amount cell of first row is “idColAmount-__clone1” and so on.
So we need to iterate the values based on the data bound to the table.
c. get the data bound to the table.
var tabData = sap.ui.getCore().byId("idInvoicesTable").getModel().getData().modelData;
var tabDataLength = tabData.length;
d. Inside the loop, we need to check the condition. We need to fix the ID based on the index and Make sure that the text is converted into integer using function parseInt() for proper check.
colId = "idColAmount-__clone" + i;
colValue = sap.ui.getCore().byId(colId).getText();
colValue = parseInt(colValue);
e. Now use addStyleClass method to assign a class and remove other classes using removeStyleClass function, to make sure only once class is assigned at a time.
if(colValue < 100){
sap.ui.getCore().byId(colId).addStyleClass("red");
sap.ui.getCore().byId(colId).removeStyleClass("green");
sap.ui.getCore().byId(colId).removeStyleClass("yellow");
}
Thank you. Appreciate your comments.
Seyed Ismail.
Hi Seyed,
First of all, appreciate your efforts on writing your first blog on SCN. 🙂
Coming onto your blog, I would say that the code can be made look more better if you apply the styles based on your model, rather than doing it based on ID (where it is colId = "idColAmount-__clone").
Here is an example from Dennis Seah , which is more cleaner and smoother: JS Bin - Collaborative JavaScript Debugging
Best Regards,
Sai Vellanki.
Hi Sai,
Thank you for appreciating and giving me information on how to color rows based on values.
Seyed Ismail.
why just dont add a delegate instead of make controller code messy
onAfterRendering: function () {
var intStatus = parseInt(this.getBindingContext().getObject().Status);
if ( intStatus !== NaN )
{
if(intStatus == 35 || intStatus == 30 || intStatus == 150)
{
this.$().css("color", "grey");
}
else if( intStatus <= 15)
{
this.$().css("color", "red");
}
else if( intStatus > 15 && intStatus < 90)
{
this.$().css("color", "orange");
}
else if( intStatus > 90)
{
this.$().css("color", "green");
}
}
}
}, false, StatusColumnText, true);
why the hard way? The feature is available out of the box with the Table. Say a control like ObjectNumber that has the state property shall emphasize based on the state values and it can be used within a table item. Check out the below explored example on the same.
https://sapui5.netweaver.ondemand.com/explored.html#/sample/sap.m.sample.Table/preview
Hi Sakthivel,
Thank you for your information. Really useful. But It is just about ObjectNumber and formatting the ObjectNumber cell based on state("Success", "Warning" ...).
But this blog is about adding CSS classes to a cell of any type. CSS can do many things and not just setting the state(color) of the cells.
Thank you,
Seyed Ismail.
Hi Syed,
This article is very helpful but it is not working with XML views.
It returns error.
Could you update it for xml views.
Thank you.
Amir