Skip to Content
Technical Articles
Author's profile photo Lukas Riederle

Experience Management – Collect Feedback from within your SAP Fiori Launchpad with Qualtrics

Experience Management is a trending topic today. There is great potential and value in doing things right and replace guessing with knowing when it comes to human behavior within today’s Experience Economy. To be able to do that properly in a business context its crucial to combine the context – which is known already pretty often in the SAP Systems – with the experience information in the Experience Management Platform from Qualtrics. Having those two types of information combined you can get all necessary insights to improve and react properly on every touch point to drive your business even better.
In advance it is important to do that as seamless as possible for your Users. This is what we focus on this time.

With this blog post I want to give a hands-on introduction how easy it is to collect feedback within your SAP Fiori Launchpad for example from a SAP S/4HANA System.

Target Process Overview

After running through the steps of this tutorial you have a running exemplary integration of Qualtrics within your SAP Fiori Launchpad to Listen to feedback on apps and processes.

Source: Own Graphic

We can react to specific situations happening while using the apps and collect context during the listening process.

That could be:

  • Feedback Frequency
  • Target Groups
  • User Segmentation
  • App Context
  • and many more

Now we can build an integrated “Listen”, “Understand” and “Act” process for this touchpoint.

Source: Screenshots from SAP Fiori Launchpad Sandbox

Source%3A%20Screenshot%20from%20SAP%20Fiori%20Launchpad%20Sandbox

Source: Screenshot from SAP Fiori Launchpad Sandbox

The scenario just showcases an example on how to combine the SAP Fiori Launchpad and the Qualtrics XM Platform.

Have a look what you could get out of this:

This is only setting the foundation for applying all the powerful insight, analytics and follow-up functionalities which the platforms provide. If you want to learn more about it, feel free to reach out to us and have a first look here:

https://www.sap.com/products/experience-management-xm.html

https://www.qualtrics.com/

Preconditions

You should be aware of how to design an proper Experience Management Process and already have some experience with building SAP Fiori Apps as well as how to setup an feedback process in Qualtrics. Maybe you team up with a colleague to combine that?

Needed Accounts

Needed Knowledge

Qualtrics

If you have no experience with Qualtrics yet, you better start of with a beginners guide there.
What about my previous blog post?
https://blogs.sap.com/2020/03/07/experience-management-create-your-first-close-the-loop-integration-with-qualtrics-and-sap-s-4hana/ 

In addition to the basics I recommend learning something about the Website and App Feedback in the Qualtrics Basecamp:
https://basecamp.qualtrics.com/implementing-a-digital-feedback-program/384230

Further information is available here:
https://www.qualtrics.com/support/website-app-feedback/

SAP

For building the Integration into the Fiori Launchpad you should at least have some experience with building SAP Fiori Apps.

There are great Tutorials on https://developers.sap.com/ as well as courses on https://open.sap.com.

You can find more about the Fiori Launchpad here:

Or walkthrough this Blog Post:

Our target architecture

Source: Own Graphic

Setup your Qualtrics Website and App Feedback

Now we setup our Website and App Feedback Project in Qualtrics. For that we need an paid account with the functionality activated.

This project will be our central connection for all different types of feedback we want to collect from the SAP Fiori Launchpad.

Create the Website and App Feedback Project

  1. Login into your Qualtrics XM Platform Account and create a new “Website and App Feedback” project.

    Source: Screenshots from Qualtrics

  2. Give it a name:

    Source: Screenshots from Qualtrics

  3. Create an intercept and creative then publish and activate all.

Test the survey

Finally, click on “Publish” and you’re done!

You can find more details how to do so in the Qualtrics Basecamp:
https://basecamp.qualtrics.com/implementing-a-digital-feedback-program/384230

Build the Feedback Plugin

I will just mention the most important steps with the special needs for our case. A great generic tutorial with all the details can be found here:
https://blogs.sap.com/2019/03/19/fiori-for-s4hana-developing-a-custom-fiori-launchpad-plugin/

Now let’s get it done in three steps:

  1. Create the rare plugin
  2. Embed Qualtrics functionality
  3. Capture and transfer the context

Create the rare plugin (1/3)

Easiest way is to go through the WebIDE and create a SAP Fiori Launchpad Plugin from Templates.

  1. Choose SAP Fiori Launchpad Plugin. If it’s not showing up you have to activate the “SAP Fiori Launchpad Extensibility” Extension first.

    Source: Screenshots from SAP WebIDE

  2. Give it a name

    Source: Screenshots from SAP WebIDE

  3. Define an ID and Title, activate the button template.

    Source: Screenshots from SAP WebIDE

Embed Qualtrics functionality (2/3)

We need to embed the intercept code into the launchpad through our plugin

Add intercept JavaScript code

  1. add a new method to your Component.js
    embedWebsiteFeedbackStarter: function () {
    /* eslint-disable */
    //BEGIN QUALTRICS WEBSITE FEEDBACK SNIPPET
    
    [THE CODE HERE]
    
    //END WEBSITE FEEDBACK SNIPPET
    /* eslint-enable */
    }​

     

  2. copy the embed code from your Qualtrics App Feedback Code towards “THE CODE HERE” but only starting at “var g=function” end ending with “catch(i){}”

NOTE: You can make this more generic by substituting the ids in this code with variables.

Manage Intercept Logic

To have better control of the App Feedback we follow the following guidance: https://www.qualtrics.com/support/website-app-feedback/common-use-cases/single-page-application/

The API is documented here: https://s.qualtrics.com/WRAPI/SiteIntercept/JavaScript/classes/API.html

  1. Add new method:
    registerWebsiteFeedbackLoadedEvent: function () {
    	//Make sure to be notified once intercept API has been loaded
    	/* eslint-disable sap-forbidden-window-property*/
    	window.addEventListener(
    		"qsi_js_loaded",
    		function () {
    			if (QSI.API) {
    				this.hasInterceptLoaded = true;
    				QSI.API.load().then(QSI.API.run());
    			} else {
    				this.hasInterceptLoaded = false;
    			}
    		}.bind(this),
    		false
    	);
    	/* eslint-enable sap-forbidden-window-property*/
    },​

Initialize our new methods

Now we initialize our application by adding the following to the end of the existing “init” method:

  1. this.hasInterceptLoaded = false;
    this.registerWebsiteFeedbackLoadedEvent();
    this.embedWebsiteFeedbackStarter();

Try it out!

We have embedded and activated the app Feedback in our Fiori Launchpad!

By activating an Creative and Intercept without specific rules it will already show up in our launchpad.

Hint: You can enable the Qualtrics Debugger by executing the following code in the Web Browser Console:

QSI.API.unload();
QSI.isDebug = true;
QSI.API.load();
QSI.API.run(); 

Collect feedback through a custom feedback button

Lets first adopt the feedback button which has been created already but we did not yet use.

  1. Change the layout and position of the button and send an event to Qualtrics by changing the code in our “init” function like this
    init: function () {
    	var rendererPromise = this._getRenderer();
    	/**
    	 * Add item to the header
    	 */
    	rendererPromise.then(function (oRenderer) {
    		oRenderer.addHeaderEndItem({
    			id: "qualtrics-feedback-button",
    			icon: "sap-icon://feedback",
    			tooltip: "Give Feedback",
    			press: function () {
    				/* eslint-disable sap-no-global-define*/
    				// gets the window._qsie variable or sets it to an array 
    				window._qsie = window._qsie || []; 
    				// count how often the feedbackbutton has been pressed
    				window._qsie.push("feedbackrequest");	}
    				/* eslint-enable sap-no-global-define*/
    		}, true, false);
    	});
    	this.hasInterceptLoaded = false;
    	this.registerWebsiteFeedbackLoadedEvent();
    	this.embedWebsiteFeedbackStarter();
    },
    },​
  2. Now we can react to a click on this element id in our intercept in Qualtrics.
    1. Add an Creative like a “ResponsiveDialog” to our “Website and App Feedback Project”.
    2. Add a new “Intercept” reacting to it.
    3. Select “Options” -> “Advanced Options” for the “Action Set” and react to the click like this:

      Source: Screenshots from Qualtrics

  3. In addition we can react to the event “feedbackrequest” which is counting our clicks on the button.
  4. With this we can also simulate the click whenever needed like this:
    sap.ui.getCore().byId("qualtrics-feedback-button").getDomRef().click();​

Try it out!

As soon as you hit the button, the Responsive Dialog shows up.

Capture and transfer the context (3/3)

Now we want to collect user and application context and send it to Qualtrics.

That way

  • we can control better when to show an feedback request
  • understand feedback with context
  • and act properly on the feedback.

Collect SAP Fiori Launchpad Application context

As we need want to react to context of the user we will leverage the Unified Shell Services to collect the needed information. To make it accessible for Qualtrics we will store the information in a global variable.

Source: https://sapui5.hana.ondemand.com/sdk/#/api/sap.ushell.services

  1. Create a new method which collects the relevant context:
    getAppContextData: function () {
    	return new Promise(function (fnResolve, fnReject) {
    		var contextData = {};
    		
    		// Current Application
    		contextData.app = {};
    		var oCurrentApp = sap.ushell.Container.getService("AppLifeCycle").getCurrentApplication();
    		if(oCurrentApp){
    			if(oCurrentApp.homePage){
    				contextData.app.id = "HOME";
    			} 
    			contextData.app.type = oCurrentApp.applicationType;
    			
    			var oComponentInstance = oCurrentApp.componentInstance;
    			if(oComponentInstance){
    				// Only for UI5 APP
    				contextData.app.componentId = oComponentInstance.getId();
    				var appData = oComponentInstance.getManifestEntry("sap.app");
    				for (var attrname in appData) { contextData.app[attrname] = appData[attrname]; }
    			}
    		}
    		// User Information
    		contextData.user = {};
    		var userInfo = sap.ushell.Container.getService("UserInfo");
    		var userData = userInfo.getUser();
    		contextData.user.id = userData.getId();
    		contextData.user.email = userData.getEmail();
    
    		//resolve data
    		fnResolve(contextData);
    	});
    },
  2. Call this method before triggering the intercept and store the result into a global variable. Therefore replace the following method like this:
    registerWebsiteFeedbackLoadedEvent: function () {
    	//Make sure to be notified once intercept API has been loaded
    	/* eslint-disable sap-forbidden-window-property*/
    	/* eslint-disable no-undef*/
    	window.addEventListener(
    		"qsi_js_loaded",
    		function () {
    			if (QSI.API) {
    					this.getAppContextData().then(function (oContextData) {
    						// global variable accessable by qualtrics:
    						qualtricscontext = oContextData;
    						this.hasInterceptLoaded = true;
    						QSI.API.load().then(QSI.API.run());
    					}.bind(this));
    			} else {
    				this.hasInterceptLoaded = false;
    			}
    		}.bind(this),
    		false
    	);
    	/* eslint-enable sap-forbidden-window-property*/
    	/* eslint-enable no-undef*/
    },
  3. Enrich this method with whatever context you might find relevant and react to it through Qualtrics.

Reload Context and Rules on navigation changes

To trigger the logic of the Website and App Feedback properly we have to react to launchpad navigation and update the context accordingly.

  1. Create a new Event Handler method
    onAppLoaded: function (evt, oData) {
    	//Attach current context to global variable to be able to collect in Qualtrics Website Feedback as embeded data
    	this.getAppContextData().then(function (oContextData) {
    		/* eslint-disable sap-forbidden-window-property*/
    		/* eslint-disable no-undef*/
    		qualtricscontext = oContextData;
    		//Validate that intercept has loaded before accessing intercept API's
    		if (this.hasInterceptLoaded === true) {
    			// https://www.qualtrics.com/support/website-app-feedback/common-use-cases/single-page-application/
    			QSI.API.unload();
    			QSI.API.load().then(QSI.API.run());
    		}
    		/* eslint-enable sap-forbidden-window-property*/
    		/* eslint-enable no-undef*/
    	}.bind(this));
    },​
  2. Register the new Event Handler after the Qualtrics JavaScript has loaded. Therefore adopt our method like this:
    registerWebsiteFeedbackLoadedEvent: function () {
    	//Make sure to be notified once intercept API has been loaded
    	/* eslint-disable sap-forbidden-window-property*/
    	/* eslint-disable no-undef*/
    	window.addEventListener(
    		"qsi_js_loaded",
    		function () {
    			if (QSI.API) {
    					this.getAppContextData().then(function (oContextData) {
    						// global variable accessable by qualtrics:
    						qualtricscontext = oContextData;
    						this.hasInterceptLoaded = true;
    						// Listen to the "AppLoaded" Event
    						sap.ushell.Container.getService("AppLifeCycle").attachAppLoaded({},
    							this.onAppLoaded,
    							this
    						);
    						// If you need to react to navigation within an app add the listener to "hashchange" here.
    
    						// load and run the intercept
    						QSI.API.load().then(QSI.API.run());
    					}).bind(this);
    			} else {
    				this.hasInterceptLoaded = false;
    			}
    		}.bind(this),
    		false
    	);
    	/* eslint-enable sap-forbidden-window-property*/
    	/* eslint-enable no-undef*/
    },​
  3. (Optional) If you need to react also to navigations within a single app –  like from overview to detail screen.
    You have to  listen to the hash change in addition to the SAP Fiori Launchpad navigation.
    Therefore just add the following after attaching to the “onAppLoaded” event

    var oHashChanger = sap.ui.core.routing.HashChanger.getInstance();
    oHashChanger.attachEvent("hashChanged", function(oEvent) {
          this.onAppLoaded();
    }.bind(this));

Optional: Enable XM Directory Contact Frequency Rules

If you want to enable the plugin to allow the XM Directory to control frequency rules for users you have to map the user identifier here as well. It’s well documented at the Qualtrics Support Site: https://www.qualtrics.com/support/website-app-feedback/common-use-cases/xm-directory-contact-frequency-rules-for-digital-intercepts/

  1. Therefore we add the following code at the beginning of our method “registerWebsiteFeedbackLoadedEvent” which maps our User field to the “externalReference” Identifier of the XM Directory.
    /* eslint-disable sap-forbidden-window-property*/
    /* eslint-disable no-undef*/
    // Map User Context:
    if(typeof qualtricscontext === "undefined"){
    	qualtricscontext = {};
    	qualtricscontext.user = {};
    }
    if(typeof QSI === "undefined") {
    	QSI = {};
    	QSI.config = {
    		externalReference: qualtricscontext.user.id
    	};
    }

Deploy your extension

You can now deploy your extension to whatever Fiori Launchpad Environment you are running on. If you don’t know how, have a look at one of the referenced Blog Posts or SAP Help.

You made it!

Congratulations! You have embedded a nice feedback channel into your SAP world!

Now build a proper feedback process around:

  • Listen
  • Understand
  • Act

Let me know your experience and feedback around this!
What context was relevant? What did you learn from it?
How do your users react?

Did you know that there is a comparable feedback channel to our product development already available in S/4HANA Cloud?
https://help.sap.com/viewer/4fc8d03390c342da8a60f8ee387bca1a 

Last but not least:

This blog post is just out of my personal experience and learning of the topic. It does not represent any official statements for SAP’s product directions or functionalities.

About Me

I am working as Innovation Lead and Architect within a team in the Customer Advisory which is focused on driving customer innovations around XM (Experience Management) and Business Technology for Middle and Eastern Europe.

I am with SAP for more then 10 years in different customer facing roles and my motivation is to improve and innovate on business processes around all industries by applying technology in a way no one has done before.

Outlook

I will continue to add further Blog Posts whenever I see a need for it. What topic would you like to learn more about?

So stay tuned and follow me here to get notified: https://people.sap.com/lukas.riederle

Looking for a way how to collect feedback from other SAP Solutions?

Assigned Tags

      10 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Sean D'Silva
      Sean D'Silva

      Very nice article with good detailing, Lukas. Thanks!

      Author's profile photo Lukas Riederle
      Lukas Riederle
      Blog Post Author

      Updated the beginning of the blog post with a video showing how this could look like when implemented. Enjoy!

      Author's profile photo Ganesh Salunke
      Ganesh Salunke

      This is a very detailed and Insightful post, thanks Lukas!

      Is there a way we can store the qualtrics survey response id along with the custom fiori application key in the SAP backend ? This is to provide the ability for the user to look at the fiori application and see the specific response to the survey.

      Author's profile photo Lukas Riederle
      Lukas Riederle
      Blog Post Author

      Thanks Ganesh, great that you like it!

      Not sure whether I got exactly what you are trying to achieve.

      Generally the fiori application key captured together with the user feedback can be stored and used for analytics within Qualtrics.

      You could also use a Qualtrics Action to react to given feedback in any way including a call to a web service where you then could store the response id and parts of the feedback. More details how to call an SAP system like S/4HANA from Qualtrics can be found in my other blog post here: https://blogs.sap.com/2020/03/07/experience-management-create-your-first-close-the-loop-integration-with-qualtrics-and-sap-s-4hana/#

      Author's profile photo Silviu Vladut Tanasie
      Silviu Vladut Tanasie

      Hello,

      Thank you for your blog, but I have a problem, do you have this code on github or something?

      I have an error with _getRenderer :(, it tells me that is not a function.

       

      Thank you.

      Author's profile photo Lukas Riederle
      Lukas Riederle
      Blog Post Author

      Hi Silviu,

      no I don't have published it on public github.

      Could you maybe try to adopt the getRenderer Part as described here?

      Developing a Shell Plugin for SAP Fiori Launchpad Service on SAP BTP (Multi-Cloud Environment) with SAP Business Application Studio | SAP Blogs

      Best regards,

      Lukas

      Author's profile photo Silviu Vladut Tanasie
      Silviu Vladut Tanasie

      Thank you for reply.
      Last question :D, do you gave any idea why I`m not able to pass the context?
      I followed the tutorial, but it`s not working.
      Maybe there are some updates in BAS / Qualtrics?

      Author's profile photo Lukas Riederle
      Lukas Riederle
      Blog Post Author

      Hi Silviu, are you capturing the filled global variable "qualtricscontext" using the "Value from JavaScript" within Qualtrics?

      Best regards,
      Lukas

      Author's profile photo Andrey Lugnov
      Andrey Lugnov

      Hi Lukas,

      thank you for your post.

      It is not clear whether only BTP FLP is supported or S/4 onPremise FLP as well supported?

      best regards,

      Andrey

      Author's profile photo Lukas Riederle
      Lukas Riederle
      Blog Post Author

      Hi Andrey,

      it should be independent of the installation type. If you are able to create a FLP plugin, you should be able to integrate it.

      Best regards,

      Lukas