Search code examples
sapui5

Manipulating icons in the table row based on condition


I have the sap.ui.table.Table in XML view as below:

<Table id="testtable" xmlns="sap.ui.table"
  rows="{/testdata}"
  alternateRowColors="true">
  <columns>
    <Column hAlign="Center" label="Col1">
      <template>
        <m:Text text="{dataX}" wrapping="false" />
      </template>
    </Column>
    <Column hAlign="Center" label="Col2">
      <template>
        <m:Text text="{dataY}" wrapping="false" />
      </template>
    </Column>
    <Column label="Col3">
      <template>
        <m:HBox>
          <core:Icon src="sap-icon://show" color="#007bff" />
          <core:Icon src="sap-icon://edit" color="#007bff" />
          <core:Icon src="sap-icon://print" color="#007bff" />
        </m:HBox>
      </template>
    </Column>
  </columns>
</Table>

sample fig: (rough)

Here what I am trying to achieve is for different rows I want to change the properties of Icons as:

manipulated table

To achieve this, I did something as:

Code below is what I tried for manipulating (not to get exactly as in image)

var noOfrows = data.length; // data is here table rows data 
var tabItems = this.byId("testtable").getRows();
if (noOfrows != 1) {
  for (var i = 0; i < noOfrows - 1; i++) {
    var cells = tabItems[i].getCells();
    cells[2].mAggregations.items[0].setColor("#000000");
    cells[2].mAggregations.items[1].setColor("#c2baba");
    cells[2].mAggregations.items[2].setColor("#000000");
  }
} else {
  var cells = tabItems[0].getCells();
  cells[2].mAggregations.items[0].setColor("#007bff");
  cells[2].mAggregations.items[1].setColor("#007bff");
  cells[2].mAggregations.items[2].setColor("#007bff");
}

This does the thing but I have read this to be very bad. I have no idea how I could do this in a proper way.

I am trying to accomplish this by keeping table, columns in XML view (if this is possible) as above instead of adding dynamically from controller.

The sample of data looks as:

var testdata = [{test: "A", data:'eg1'},
                {test: "B", data:'eg2'},
                {test: "C", data:'eg3'}]

Solution

  • Here is a worked example - it will move you towards where you need to go (as I would not put the formatting function in the controller but in a separate js file). Can do that later if you need me to.

    Set you Icons colours to depend on the variable 'test' you allude to in your comment by calling the setIconColour function that returns a valid Icon colour.

    <core:Icon src="sap-icon://show" color="{path: 'test', formatter: '.setIconColour'}" />
    

    Set a value for test in your data:

    {"testdata": [
        { "dataX": 1, "dataY": "testdata", "test": 0},
        { "dataX": 2, "dataY": "testdata", "test": 2},
        { "dataX": 3, "dataY": "testdata", "test": 3},
        { "dataX": 4, "dataY": "testdata", "test": 1}
    ]}
    

    Use the value of test to set the icon colour in a function (below is an example):

    setIconColour: function (value) {
      if (value === 0) {
        return "Default";
      } else if (value === 1) {
        return "#007bff";
      } else if (value === 2) {
        return "Positive";
      } else if (value === 3) {
        return "Negative";
      } 
    }
    

    The icon colour will now be a function of the value of the variable 'test'.

    enter image description here

    Addition - code snippet included (THIS IS NOT HOW YOU BUILD A SAPUI5 APP - this is to illustrate this with a WORKING example from which to learn or with which you can play)

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>example conditional formatter</title>
            <script
            	src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
                id="sap-ui-bootstrap"
                data-sap-ui-theme="sap_belize_plus"
                data-sap-ui-libs="sap.m"
                data-sap-ui-bindingSyntax="complex"
                data-sap-ui-compatVersion="edge"
                data-sap-ui-preload="async"></script>
                <!-- use "sync" or change the code below if you have issues -->
    
            <!-- XMLView -->
            <script id="myXmlView" type="ui5/xmlview">
                <mvc:View
                    controllerName="MyController"
                    xmlns:m="sap.m"
                    xmlns="sap.ui"
                    xmlns:core="sap.ui.core"
                    xmlns:mvc="sap.ui.core.mvc">
                  <Table id="testtable" xmlns="sap.ui.table"
                    rows="{/testdata}"
                    alternateRowColors="true">
                    <columns>
                      <Column hAlign="Center" label="Col1">
                        <template>
                          <m:Text text="{dataX}" wrapping="false" />
                        </template>
                      </Column>
                      <Column hAlign="Center" label="Col2">
                        <template>
                          <m:Text text="{dataY}" wrapping="false" />
                        </template>
                      </Column>
                      <Column label="Col3">
                        <template>
                          <m:HBox>
                            <core:Icon src="sap-icon://show" color="{path: 'test', formatter: '.setIconColour'}" />
                            <core:Icon src="sap-icon://edit" color="{path: 'test', formatter: '.setIconColour'}" />
                            <core:Icon src="sap-icon://print" color="{path: 'test', formatter: '.setIconColour'}" />
                          </m:HBox>
                        </template>
                      </Column>
                    </columns>
                  </Table>
                </mvc:View>
            </script>
    
            <script>
                sap.ui.getCore().attachInit(function () {
                    "use strict";
    
                    //### Controller ###
                    sap.ui.define([
                        "sap/ui/core/mvc/Controller",
                        "sap/ui/model/json/JSONModel"
                    ], function (Controller, JSONModel, XMLModel) {
                        "use strict";
    
                        return Controller.extend("MyController", {
                            onInit : function () {
    
                                var that = this;
                                let model = new JSONModel(this.getData());
                                this.getView().setModel(model);
                             },
                           setIconColour: function (value) {
                                if (value === 0) {
                                  return "Default";
                                } else if (value === 1) {
                                  return "#007bff";
                                } else if (value === 2) {
                                  return "Positive";
                                } else if (value === 3) {
                                  return "Negative";
                                } 
                              },
    
                           getData: function(){
                              return {"testdata": [
                                { "dataX": 1, "dataY": "testdata", "test": 0},
                                { "dataX": 2, "dataY": "testdata", "test": 2},
                                { "dataX": 3, "dataY": "testdata", "test": 3},
                                { "dataX": 4, "dataY": "testdata", "test": 1}
                                ]};
                              }
                    })
                    });
                    
    
                    //### THE APP: place the XMLView somewhere into DOM ###
                    sap.ui.xmlview({
                        viewContent : jQuery("#myXmlView").html()
                    }).placeAt("content");
    
                });
            </script>
    
        </head>
    
        <body class="sapUiBody">
            <div id="content"></div>
        </body>
    </html>