Easy to Maintain Context Help in UI5 Apps
UI5 apps should be designed such that they are intuitive. Nevertheless, users still occasionally need some guidance. This post provides one way of including contextual help in SAPUI5 and OpenUI5 apps.
Requirements
Before we decide on an approach, we need to consider what our requirements are. A good start would be that the help documentation must be:
- easy to maintain,
- maintainable by non-developers, and
- in the user's language.
Approach
We'll use the Markdown syntax, maintaining a Markdown file for each sap.ui.View
. If we support multiple languages, each View will need a separate Markdown file for each language.
The Markdown files as well as a JavaScript Markdown parser are deployed to the server as part of the app. At runtime, the relevant Markdown file will be chosen based on View and language, parsed into HTML and displayed in a sap.m.Dialog
when the user requests help.
Implementation
Let's have a look at how we can realize this approach to providing contextual help in our app.
The Markdown Parser
There are a number of options, but we'll use marked. We put the marked.js
file in our app folder structure, for example at webapp/utilities/
.
webapp
├── Component.js
├── index.html
├── manifest.json
├── controller
│ ├── App.controller.js
│ └── Another.controller.js
├── i18n
│ └── i18n.properties
├── utilities
│ └── marked.js
└── view
├── Home.view.xml
└── Another.view.xml
Now we need to make the parser available to the app. If the app will not be run in the Fiori Launchpad, we can include the parser in index.html
after the bootstrap script. Assuming we have data-sap-ui-resourceroots='{"myapp": "./"}'
in the bootstrap, we can include the parser as follows:
<script>
sap.ui.getCore().attachInit(function () {
sap.ui.require([
"sap/m/Shell",
"sap/ui/core/ComponentContainer",
// Include Markdown parser here if the app won't run in Fiori Launchpad:
"myapp/utilities/marked"
], function (Shell, App, ComponentContainer) {
new Shell({
app: new ComponentContainer({
name: "myapp",
height: "100%"
})
}).placeAt("content");
});
});
</script>
If the app may be run in the Fiori Launchpad, we can include the parser in an appropriate Controller using:
sap.ui.require(["myapp/utilities/marked"]);
Markdown can then be parsed using:
// data: contents of Markdown file
marked(data); // result: html
For earlier versions of the SAPUI5 or OpenUI5 libraries, use
jQuery.sap.require("myapp/utilities/marked");
instead ofsap.ui.require
.
The Documentation
Our documentation will be maintained in folders per language code so that we can show contextual help in the user's language. Inside the language folders, we create Markdown files per View. For example, for Home.view.xml
we maintain help documentation in Home.md
.
webapp
├── Component.js
├── index.html
├── manifest.json
├── controller
│ ├── Home.controller.js
│ └── Another.controller.js
├── documentation
│ ├── en
│ │ ├── Home.md
│ │ └── Another.md
│ └── es
│ ├── Home.md
│ └── Another.md
├── i18n
│ └── i18n.properties
├── utilities
│ └── marked.js
└── view
├── Home.view.xml
└── Another.view.xml
Each of these files is simply a plain text file using Markdown syntax. For example, Home.md
could contain something like this:
# Using MyApp
In this screen, you can find a widget and navigate to detailed information about it.
1. Tap the Search field and start entering a widget name. The list of widgets will be filtered as you type.
2. Tap the widget in the list to navigate to detailed information about it.
Serving the Documentation
Now that we have a parser and some documentation, we're ready to incorporate contextual help into our app.
We could build the help dialog directly in our Controller, but we'll use an xml View fragment instead:
<core:FragmentDefinition
xmlns="sap.m"
xmlns:core="sap.ui.core">
<Dialog
id="helpDialog"
title="My App Help"
stretch="true"
type="Standard"
class="sapUiPopupWithPadding">
<endButton>
<Button text="Close" press="closeHelpDialog" />
</endButton>
</Dialog>
</core:FragmentDefinition>
We'll also need a help button on each page:
<customHeader>
<Toolbar>
<Button icon="sap-icon://menu" press="openMenu" />
<ToolbarSpacer/>
<Title text="{i18n>homePageTitle}" />
<ToolbarSpacer/>
<!-- Help button -->
<Button icon="sap-icon://sys-help" press="openHelpDialog"/>
</Toolbar>
</customHeader>
The final bit: a function in a suitable Controller that selects and parses a Markdown file and opens a help dialog with the relevant content.
openHelpDialog : function () {
this.helpDialog = sap.ui.xmlfragment(
"myapp.view.dialogHelp",
this
);
this.getView().addDependent(this.helpDialog);
var sPath, sLanguage, sView, sFile, sUrl, sUrlFallback, oHtml;
sPath = jQuery.sap.getModulePath("myapp");
sLanguage = sap.ui.getCore().getConfiguration().getLocale().getLanguage();
sView = this.getView().getViewName();
sFile = sView.split(".")[2] + ".md";
sUrl = sPath + "/documentation/" + sLanguage + "/" + sFile;
sUrlFallback = sPath + "/documentation/en/" + sFile;
$.ajax({
url: sUrl,
success: function(data) {
// Display help in user's language if available
oHtml = new sap.ui.core.HTML({
// content: markdown.toHTML(data)
content: marked(data)
});
oHtml.placeAt("helpDialog");
},
error: function(data) {
// Display help in English if not available in user's language
$.get(sUrlFallback, function(data) {
oHtml = new sap.ui.core.HTML({
// content: markdown.toHTML(data)
content: marked(data)
});
oHtml.placeAt("helpDialog");
});
}
});
this.helpDialog.open();
}
The resulting help dialog looks like this:
The styling can of course be improved quite easily...
Please contact us to discuss SAPUI5 apps for your business, or if you're interested in joining in the BPSE team.