Skip to Content

sap.ui table change color of specific rows

Consider a table with 50 records. visibleRowCount is set to 15, so when table is loaded with data there are only 15 records displayed. I need to change color of some specific rows based on values (lets say when a cell has value "Total"). Assume, "Total" appears in rows 2,4 8. I can change the color of these rows. getRows() works well before I start scrolling a table down,The problem is that getRows() method returns only # of visible rows in the table. Therefore, when I scroll table down the rows 2, 4 ,8 are colored permanently. In this case the logic that it should depend on value "Total" doesn't work. Is thre any chance I can fix this issue? Thanks!

Add comment
10|10000 characters needed characters exceeded

  • Follow
  • Get RSS Feed

14 Answers

  • Nov 15, 2018 at 09:55 PM

    In the past I have taken advantage of aggregation binding factory functions - https://sapui5.hana.ondemand.com/#/topic/335848ac1174435c901baaa55f6d7819

    What I was doing was more involved with dynamic controls so it may not be the best solution for this.

    View:

    <table:Table rows="{/Rows}" visibleRowCount="10">
       <table:columns>
          <table:Column>
             <table:template>
                <HBox alignItems="Center"
                     displayInline="true"
                     items="{
                        path: 'value/0',
                        templateShareable:true,
                        factory: '.resultColumnFactory'
                }">
                </HBox>
             </table:template>
          </table:Column>
       </table:columns>
    </table:Table>

    Controller:

    resultColumnFactory: function (sId,oContext) {
    
    var color = "";
    var path = oContext.getPath().split("/");
    var Row = this.getView().getModel().getProperty("/" + path[1] + "/" + path[2]);
                var oText = new Text(sId, { text: Row.value });
    
                if(Row.value == "Good"){
                    color = "green";
                }
    
                oText.addEventDelegate({
                    "onAfterRendering": function () {
                        this.$()
                            .closest( "tr" )
                            .css( "background-color", color );
                    }
                }, oText);
    
                return oText;
      }
    Add comment
    10|10000 characters needed characters exceeded

  • Nov 15, 2018 at 02:14 AM
    Add comment
    10|10000 characters needed characters exceeded

  • Nov 15, 2018 at 04:39 AM

    Hi Sergey Koch,

    SAP.UI.TABLE only changes the data in the visible rows when you scroll unlike the SAP.M table which create new ui elements for new rows.

    As the rows never change in SAP.UI table, you can use onAfterRendering event of the table and remove the style class and add the style class again(as per your logic). Now in this event, if you check the getRows(), you will find the latest rows.

    Ideally speaking you can bind the style class to a formatter and change it based on the row data, but when i tried last time binding didnt work for the class property(style) for the controls.. I am not sure if it works in current releases, but you can check that as well.

    BR,

    Mahesh

    Add comment
    10|10000 characters needed characters exceeded

    • Thank you Mahesh! I don't know why, but onAfterRendering methos has never been invoked. I tried attach it to the table and override it: oTable.onAfterRendering = function(){ .....code....}

      Or

      oTable.addEventDelegate({ "onAfterRendering": function () {....code......} }, this);

      In both cases, the code flow never went inside these functions when I was scrolling my table up and down.

      Thanks!

  • Nov 19, 2018 at 01:04 AM
    Assume, we get oData = [{}, {},   ,{}] with data. 
    First, add a new property to each of the object in array, lets say: set color: "blue" for desired row cells, and "red" for everything else.
    Second, set this data to our model: oModel.setData(oData);
    Third, attach model to the table: this.getView().byId("table1").setModel(oModel);
    In XML view we define our table as following (it is sap.ui.table with desired properties):
    <Table id="table1"
    	rows="{/}"
    	title="Products"
    	selectionMode="MultiToggle"
    	fixedColumnCount="2"
    	visibleRowCount="15">
    <columns>
    	<Column width="6em">
    	<m:Label text="Column 1" />
    	<template>
    	   <m:Text text="{column1}" wrapping="false">
    	   <m:customData>
                  <core:CustomData key="mydata" value="{color}" writeToDom="true"></core:CustomData>
               </m:customData>
    	   </m:Text>
    	</template>
    	</Column>
            
    
    //continue in similar way 
           <Column>....................</Column>
    </columns>
    </Table>
    
    
    In CSS file add the following:
    
    span[data-mydata="blue"] {
    background-color:#f9f9c2 !important;
    }
    
    
    In this case, key is "mydata", value is the value of each cell ( value="{color}"). If value is blue then we aply the color to this cell. 
    Add comment
    10|10000 characters needed characters exceeded

    • Hi Sergey,

      Try in the following way,

      <Tableid="table1"rows="{/}"title="Products"
      	selectionMode="MultiToggle"
      	fixedColumnCount="2"
      	visibleRowCount="15">
      <columns>
      <m:customData><core:CustomData key="mydata" value="{color}" writeToDom="true"></core:CustomData></m:customData>
      <Columnwidth="6em"><m:Label text="Column 1" /><template><m:Texttext="{column1}" wrapping="false"></m:Text></template></Column>

      And update your CSS accordingly.

      Hope this will solve your issue...

  • Nov 19, 2018 at 01:07 AM

    This approach does not fulfill my requirements stated above, but at least does color cells. Unfortunately, I could not figure out how to color rows. Hopefully, it my help someone. Please if somebody knows the better way, let us know. Thanks!

    Add comment
    10|10000 characters needed characters exceeded

  • Nov 19, 2018 at 03:16 PM

    Hi Christian,

    Unfortunately, I couldn't make it work. My factory function gets invoked, but sId and oContext parameters are both undefined. Thus, I couldn't move any further with this. Thanks for your help!

    Add comment
    10|10000 characters needed characters exceeded

  • Nov 21, 2018 at 09:11 PM

    Arun Krishna It gives me "failed to load" error. I believe <customData> element should be within a specific control, in my case it was within <Text>. If I put it after <columns> instead, the error comes out. Thanks!

    Add comment
    10|10000 characters needed characters exceeded

  • Nov 21, 2018 at 09:13 PM

    christian libich I am on 1.44.11 version. Thanks!

    Add comment
    10|10000 characters needed characters exceeded

  • Jan 09 at 01:52 PM

    Hi Sergey.

    Do you find any solutions for getRows()? only return visible rows, i need all the rows ... for update the cell color, i have an input text in the cell don't find any solution!

    Thanks

    Add comment
    10|10000 characters needed characters exceeded

    • In short, no. But I found another acceptable solution - changing cell color. Overall, it is not solid throughout the whole row, but it highlights cells within the row which was enough for me.

      In controller,

      1. I used json model. For each object in the JSON array, I added another property (say "color").

      2. For desired objects (in my case with totals and subtotals) I set color to whatever ("yes")

      3. For undesired objects - set color to different value.

      In the view,

      for each column, I added CustomData control that binds "color" property of JSON objects (from above)

      <Column width="6em" 
              sortProperty="myColumn" 
              filterProperty="myColumn">
      	<m:Label text="My Column" design="Bold"/>
      	<template>
      	<m:Text text="{myColumn}" wrapping="false">
      		<m:customData>
                     <core:CustomData key="mydata" value="{color}" writeToDom="true"></core:CustomData>
                      </m:customData>
      	</m:Text>
      	</template>
      </Column>

      In css file, it checks key-value pairs from CustomData control. Key is "mydata". Value is whatever value the property "color" contains.

      If color is set to "yes" means we want to highlight that cell --> it applies the styling, otherwise it ignores.

      span[data-mydata="yes"] { background-color:#f9f9c2 !important; font-weight: bold; }

      I know there should be a better solution, but hope it helps too! Thanks

  • Jan 09 at 05:01 PM

    Hi Sergey, thanks so much.

    I'm new in sapui5... i don't understand well ... the color is asign automatically when you change the value to "yes"?

    The problem in your post " Therefore, when I scroll table down the rows 2, 4 ,8 are colored permanently. " is solved ??

    Regards,

    Add comment
    10|10000 characters needed characters exceeded

    • Initially, I was trying to find a way to use JS capabilities of the Table control inside my controller to add style class. In this case, it allowed managing only visible rows (unfortunately).

      By using customData control in XML view, I could avoid this "visible rows" issue.

      Consider an example,

      we have JSON model containing an array of JSON objects (basically, our data): [{column1: "value1", column2: "value2"}, {...}, {...}]

      I know that an object that has "Subtotal" as a value should be highlighted (all cells in that row should be highlighted): [{coumn1: "Subtotal", column2: "1234"}, {column1: "some data", column2: "345"}, {...},...]. Here I have Subtotal in row 1 (first object in the array). While I am looping through and looking for desired objects, I add another property to each of them: myJSONdata.color = "yes" /"no"

      At the end, I have modified JSON data: [{column1: "Subtotal", column2: "1234", color: "yes"}, {column1: "some data", column2: "345", color: "no"},...{...}]

      Thats all we need as a preparation.

      Next, customData in our view does its job. It checks {color} of each cell and css file applies styling based on key-value pairs returned from customData control.

      So, color is being assigned by css file where you add this: span[data-mydata="yes"] { background-color:#f9f9c2 !important; font-weight: bold; }

      Original issue has not been solved. I used an alternative approach to make it work.