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_member231229
Participant
I saw many beautiful blogs around this topic, some among the others are:

Anyway, my goal is to put all together and have a Custom Tile type that is also able to show a Microchart (like the ones on SAP Smart Business). Moreover, it should also be connected to an oData service to give some "life" to the tile itself.

In this example we will create a Tile dedicated to Managers: it will have an embedded ComparisonMicroChart that shows the average of Employees Overtimes over the last 3 months.

So let's start!

1. Create the Tile


Technically speaking, as stated in the standard help guide here, a Custom Tile can be set up by creating an SAPUI5 View, register it as a CSR CHIP on the server and add it to the Tile Catalog configuration.

What it's not really stated is that if you need a Dynamic Tile (or even a Static one, but with navigation capabilities) this is not completely straightforward.
In order to have it "live", many rules have to be followed as the new Tile must be developed in such a way to be compatible with all the frameworks that are around the Launchpad itself, like Configuration, Navigation, Semantic Objects assignments, and so on.

Luckily, almost the entire job has been already done by our folks at SAP, so we can start from a working template rather than from scratch.

1.1 Enter sap-ui-debug


Open up /UI2/FLPD_CUST and attach the parameter sap-ui-debug=true to the URL, in order to have something like this:

http://:/sap/bc/ui5_ui5/sap/arsrvc_upb_admn/main.html?scope=CUST&sap-client=100&sap-language=IT&;sap-ui-debug=true

Load it and...be patient, libraries in debug mode take a while to get processed.

As soon as you have access to your launchpad, open Chrome Developer tools and navigate to "Network" tab (if you don't see anything, you might need to reload the page).
Enter "Dynamic" in the filter field and check the loaded files:



We need the contents of DynamicTile-dbg.controller.js but we can skip DynamicTile-dbg.view.js as we will create our own UI later on.
At this point you shall also download the contents of applauncher_dynamic.chip.xml.

Now, leaving Developer Tools open, go back to the Launchpad Customization page and click on any of the Dynamic Tiles to get to its configuration page.
Then, go back to the Network tab in the Developer Tools and this time search for "Configuration":



We need the contents of both Configuration.view.xml and Configuration-dbg.controller.js.

Pay attention to the url of these files: they must belong to the sap/ushell/components/tiles/applauncherdynamic repository.

With these sources, we are now ready to create our tile.

1.2 Create the Project


For the purpose of this tutorial, I created a simple project using Eclipse - the reason why I did not use the SapWebIDE is because I do not have a correctly set environment for the deployment from the Cloud (I am lazy and the Eclipse Team Provider is faster than a manual Download/Upload 🙂 ).

The structure of the project is straightforward:



Configuration.controller.js and Configuration.view.xml are copies of the original sources download in the previous chapter, slightly changed only to rewrite original component namespaces.

KpiTile.controller.js is a changed copy of the original DynamicTile.controller.js source.

KpiTile.view.xml is the new Tile layout file.

kpilauncher_dynamic.chip.xml is a changed copy of the original applauncher_dynamic.chip.xml source.

1.2.1 View Layout


Open up KpiTile.view.xml and create your own tile. You can use any tile type (StandardTile, CustomTile, GenericTile), but remember that the only supported frame type is OneByOne - I wasn't able to have it working using the TwoByOne frame, but maybe someone else will be 🙂

Also, GenericTile is the one that works best with contents like Microcharts.

Here is my example:
<?xml version="1.0" encoding="UTF-8"?>
<core:View
xmlns="sap.suite.ui.commons"
xmlns:ui="sap.suite.ui.microchart"
xmlns:core="sap.ui.core"
controllerName="customtilechips.KpiTile">

<GenericTile
id="kpiTile"
press="onPress"
header="{/config/display_title_text}"
subheader="{/config/display_subtitle_text}"
frameType="OneByOne">
<tileContent>
<TileContent footer="{/config/display_info_text}">
<content>
<ui:ComparisonMicroChart scale="M">
<ui:data>
<ui:ComparisonMicroChartData title="{/data/emp/month1}" value="{/data/emp/value1}" color="{/data/emp/color1}" />
<ui:ComparisonMicroChartData title="{/data/emp/month2}" value="{/data/emp/value2}" color="{/data/emp/color2}" />
<ui:ComparisonMicroChartData title="{/data/emp/month3}" value="{/data/emp/value3}" color="{/data/emp/color3}" />
</ui:data>
</ui:ComparisonMicroChart>
</content>
</TileContent>
</tileContent>
</GenericTile>

</core:View>

 

Let's have a look at the bindings.
The Tile shall display a static title and a static subtitle customized in the configuration properties of the Tile itself.
On the other hand, the embedded Microchart shall display live data, coming from an oData service.

The "config" property of the configuration model of every Dynamic Tile has these properties:

  • display_title_text

  • display_subtitle_text

  • display_icon_url

  • display_info_text

  • display_number_unit


The "data" property of the configuration model has the dynamic properties incoming from any configured oData service Url that can drive data on a DynamicTile:

  • icon

  • info

  • infoState

  • number

  • numberDigits

  • numberFactor

  • numberState

  • numberUnit

  • stateArrow

  • subtitle

  • targetParams

  • title


In addition to these properties, remember that the oData service can return as many properties as you want, so - with a little trick - the Tile will not be limited to display only these.

Moreover, do not change the "onPress" event handler registered to the Tile press event: this is already managed in the original Controller file and it works fine.
If you want to have your Tile doing something else rather than navigate you to some content, than change the event handler and implement your specific behavior in the Controller object.

1.2.2 Changing the Controller


Now open the KpiTile.controller.js file as we need to do some changes to the code copied from the standard.

Important: the standard code declares the sap.ushell.components.tiles.applauncherdynamic.DynamicTile.controller. Remember to change this in the controller declaration and all other references! The namespace and repository structure must be consistent!
Update:
After checking in different systems, I noticed that in some cases the code within the controller requires the load of a library named sap.ushell.components.tiles.utilsRT, whereas on others only the sap.ushell.components.tiles.utils library is loaded.
I didn't investigate (maybe some Mentor has an answer here), but in the system where this project has been deployed the utilsRT library is not existing so I went through the controller code and changed all the references to utilsRT simply renaming them to utils (and therefore pointing all the references to sap.ushell.components.tiles.utils) - a "Find and Replace" in Eclipse or WebIDE is enough.

Scroll down the code util you reach the successHandleFn function: this is the Success callback for each oData call that the Tile makes to the registered Service Url and here we will do a quick enhancement to take into account additional incoming data.
        successHandleFn: function (oResult) {
var oConfig = this.getView().getModel().getProperty("/config");
this.oDataRequest = undefined;
var oData = oResult,
oDataToDisplay;
if (typeof oResult === "object") {
var uriParamInlinecount = jQuery.sap.getUriParameters(oConfig.service_url).get("$inlinecount");
if (uriParamInlinecount && uriParamInlinecount === "allpages") {
oData = {number: oResult.__count};
} else {
oData = this.extractData(oData);
}
} else if (typeof oResult === "string") {
oData = {number: oResult};
}
oDataToDisplay = sap.ushell.components.tiles.utils.getDataToDisplay(oConfig, oData);
// Begin Change --------------------------->
// Use "emp" property to store original data
var aKeys =
[
// Additional data for our KPI Tile //
"month1", "month2", "month3", "value1", "value2",
"value3", "color1", "color2", "color3"
// End additional data //
];
var sName;
// Prepare emp object:
oResult.results = {};
for ( var i = 0; i < aKeys.length; i++){
sName = aKeys[i];
oResult.results[sName] = oResult[sName];
}
// Store the additional results back to emp
oDataToDisplay.emp = oResult.results;
// End Change <---------------------------

// set data to display
this.getView().getModel().setProperty("/data", oDataToDisplay);

// rewrite target URL
this.getView().getModel().setProperty("/nav/navigation_target_url",
sap.ushell.components.tiles.utils.addParamsToUrl(
this.navigationTargetUrl,
oDataToDisplay
));
},

The core of the change is in the middle, right after the "Begin Change" mark: the oData linked to our tile returns a set of additional properties used to load the Microchart.

We store these properties in an array named aKeys and for each one of them, we loop the oData structure oResult moving any additional property to its result property. As a last step, we fill the emp property of oDataToDisplay: the emp property is the one binded into the View object.

In this example, additional properties are statically defined in the code: with some more advanced JavaScript, everything can be completely transformed to dynamic.

1.2.3 Change the CHIP definition file


The standard documentation for custom Tiles creation refers to the term CSR CHIP, which stands for Client-Side Rendered CHIP.

Basically, a CHIP within the system is described by a metadata XML file which contains some very important properties: these properties are interpreted at runtime by the Launchpad engine to understand if a registered CHIP can be used as a Tile or not.

At this page is explained the schema of an XML CHIP definition file.

For our example, the change is pretty straightforward and everything it's done by simply changing the path to our SAPUI5 view in the <sapui5> node of the original applauncher_dynamic.chip.xml file.

So make a copy of it and change it as follows:
<?xml version="1.0" encoding="UTF-8"?>
<chip xmlns="http://schemas.sap.com/sapui2/services/Chip/1">
<implementation>
<sapui5>
<viewName>customtilechips.KpiTile.view.xml</viewName>
</sapui5>
</implementation>
<appearance>
<title>Dynamic Applauncher with Microchart</title>
<description>Dynamic KPI Applauncher Chip</description>
</appearance>
<contracts>
<consume id="configuration">
<parameters>
<parameter name="tileConfiguration"></parameter>
</parameters>
</consume>
<consume id="preview" />
<consume id="writeConfiguration" />
<consume id="configurationUi" />
<consume id="search" />
<consume id="refresh" />
<consume id="visible" />
<consume id="bag" />
<consume id="url" />
<consume id="actions" />
<consume id="types">
<parameters>
<parameter name="supportedTypes">tile</parameter>
</parameters>
</consume>
</contracts>
</chip>

You can also change the title and description of the Tile (it will be shown in the "Add new tile" screen of the Launchpad configuration) and customize the supportedTypes property.
In my case, I only need a Tile so I've limited the property value to "tile". Another suitable value is "link", which must then be supported at runtime by additional coding (see the original DynamicTile-dbg.controller.js file for reference).

As previously said, the most important property here is the <viewName> under <sapui5>.
Remember that this property must contain the full name of the view - including the namespace - relatively to CHIP definition XML file.

So if your XML file is under:

https://:/sap/bc/ui5_ui5/sap/Y_FLP_KPITILE1/kpidynamic_launcher.chip.xml

Than the view name is relative to this file, so:

customtilechips.KpiTile.view.xml

2. Deploy the tile


Let's do a quick review of what we have done so far.

  1. Download necessary template files directly from your system

    1. DynamicTile-dbg.controller.js

    2. Configuration-dbg.controller.js

    3. Configuration.view.xml

    4. applauncher_dynamic.chip.xml



  2. Create a new SAPUI5 project and import the downloaded sources

  3. Cleanup the sources (change namespaces, file names, controller names, and so on)

  4. Create a new XML view containing the UI for the custom tile you want to create (in this example, KpiTile)

  5. Change the Tile controller object in order to process additional oData properties

  6. Check and change the CHIP definition file


Done? Good, so let's deploy the project to the ABAP SAPUI5 Repository.

After the deployment, you should see a newly created BSP Application with a structure that mirrors your project:


2.1 Register the CHIP


This is by far the most simple step but at the same time the most important one.

Without registering the CHIP, the Tile will never be visible in the Catalog so it will not be possible to use it in any Launchpad.

Open transaction /UI2/CHIP and create a new Chip definition.
Name it as you want, I named it exactly as the BSP Page for clarity:



Use the absolute - without hostname - path to your chip definition file as the URL.
While saving, the system validates all the entries so you'll be sure that the file can actually be found.

Save this newly created CHIP and go to SE80.

Search for WebDynpro Application CUSTOMIZE_COMPONENT, then execute it.
At this point, we need to enhance the /UI2/CHIP_CATALOG_CONFIG component by adding our CHIP definition to the component configuration /UI2/FLPD_CATALOG.

This configuration is taken into account by the Launchpad application configuration component: Tiles defined as CHIPS in this configuration are instantiated and can then be used in Launchpads.

In the browser window, set parameters as follows then hit "Continue in Change Mode". If the configuration ID is not existing, go on and create it.



In the next window, we are going to add our CHIP as a configurable tile in Launchpads.

From the Configuration Context table on the left, open node "parameterMultiVal", select its line and click "New -> values" from the Toolbar.

On the right, in the input field, write:

X-SAP-UI2-CHIP: <your_chip_name>

Where the chip name is the same used in transaction /UI2/CHIP



Save and close the browser.

2.2 Try to load it


Now that our Tile is deployed and registered as CHIP, let's try to add it to one of our Launchpads.

First of all, I noticed (as explained in this blog) that cleaning up the ICM cache helps in this cases, so if you have proper authorization open SMICM transaction and head to "Go-To -> HTTP Plug-In -> Server Cache -> Invalidate locally" (or globally, depending on your installation).

Open transaction /UI2/FLPD_CUST and select one existing catalog. You might need to clean the browser cache, so it loads fresh files from the server.

As soon as it loaded, hit the "+" sign on the page to add a new Tile and - if everything worked as expected - you shall be able to see your shiny new Custom Tile:



Select the tile and you shall be presented with the Configuration page, in which you can set base parameters (remember the ones stored under the /config/ path of the Tile model).

At the moment, even if we add the tile as it is, nothing is shown on our Microchart because we miss a proper oData service.
Remember that in our case, the service must return a specific set of properties:

  • month1

  • value1

  • color1

  • month2

  • value2

  • color2

  • month3

  • color3

  • value3


Keeping this is mind, go on and create a very simple oData service that returns a value for each one of these properties.

Go to SEGW transaction on your Gateway system, create a new service with at least one EntityType and EntitySet. The EntityType must expose properties necessary to be consumed by the Tile (refer to paragraph 1.2.1) plus our custom properties.

With the oData service URL ready, configure it in the Tile options and go back to the catalog.



At this point, your Launchpad Customization page should show you something similar to this:


3 Use the Tile


Using a Username linked to the catalog you have changed, log on to the Fiori Launchpad or execute transaction /UI2/FLP.

If you don't see the new Tile, it could be because it is not added to the personalized catalog yet: click on the Pencil icon on the lower right of the screen and you'll be presented with the customization page.
From here, look for the custom tile and add it by clicking the "+" sign.

Our custom tile should now be there, ready to receive the first update from the underlying oData service you created.

Here's the expected result:



If you have defined a Semantic Object navigation, you should also be able to click on the Tile and get navigated to the application you have configured.

4 Closure


Following this rather simplicistic approach (in which - to be honest - the most of the work has been already done by SAP guys creating the DynamicTile definitions) a complete new set of custom tiles can be created on the OnPremise Launchpad as well.

Charts, Images, almost any control that can fit the "content" aggregation of the GenericTile component can be used - just pay attention on how you want to feed it and change the Tile controller accordingly to your needs.

I hope that this can bring some help to anyone that needs to deal to a similar situation, and also that new ideas can be presented to the community.
A really good trick would be to have a the option to select the kind of Microchart on the Tile, and have it completely dynamic and configurable.

If you need a copy of the original coding, drop me a comment and I will place it on a GitHub repository for reference.

Update: here is the repository URL on GitHub

Enjoy your new Tile and all the best!
Roberto.
40 Comments