Easy to Maintain Context Help in UI5 Apps

SAP UI5 1 June 2016

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 of sap.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>

Help button

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:

Help dialog

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.

Next Post Previous Post