How to show or hide content dynamically in SAPUI5/Fiori

The first SAPUI5/Fiori post on rikus-dev.com!

Intro

It is often necessary to show or hide different areas of your web page depending on certain conditions for a better user experience. It is quite easy to this in SAPUI5 once you wrap your head around the syntax. This post will highlight some methods I've been using recently in one of my projects.

Let's work with the following scenario: you want to show warning, error or success notifications at the top of the page when the user tries to submit a form. For example if the user presses save and all the required field are not filled in, an error message should appear.

Without further ado, let's begin!

Step 1: Project Setup

In your WebIDE click File > New > Project from Template and select SAPUI5 Application. Alternatively you can download the completed project here.

Give your project a name and specify the namespace (I called it rikus-dev-1 in namespace com.rikus-dev). Be sure to select View Type as XML, and give the view a name (I called it Welcome).

The project will now show up in the Workspace under the name you specified, with boilerplate code to run the application.

Open your controller and add an onInit function, so that it looks like this:

sap.ui.define([
    "sap/ui/core/mvc/Controller"
], function(Controller) {
    "use strict";
    return Controller.extend("com.rikus-dev.controller.Welcome", {
    });
});

Now, within the onInit function, create the following model and bind it to the view. In order to instantiate a JSONModel object you need to import its definition in the header. The controller now looks like this:

sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/ui/model/json/JSONModel"
], function(Controller, JSONModel) {
    "use strict";

    return Controller.extend("com.rikus-dev.controller.Welcome", {
        onInit: function(){
            var notifications = {
               "showNotifications": true,
               "warning": true,
               "error": false,
               "success": true
            };
            this.notificationModel = new JSONModel();
            this.notificationModel.setData(notifications);
            this.getView().setModel(this.notificationModel, "notifications");
        }
    });
});

In the XML View (Welcome.view.xml), add the following MessageStrip elements which we will show or hide dynamically, depending on the data:

<MessageStrip
     text="An error has occurred. Please complete the highlighted fields and try again."
     type="Error"
     showIcon="true"
     showCloseButton="true"
     class="sapUiMediumMargin">
</MessageStrip>

<MessageStrip
     text="Warning. All fields are required."
     type="Warning"
     showIcon="true"
     showCloseButton="true"
     class="sapUiMediumMargin">
</MessageStrip>

<MessageStrip
     text="The data was saved succesffuly."
     type="Success"
     showIcon="true"
     showCloseButton="true"
     class="sapUiMediumMargin">
</MessageStrip>

Step 2: Show/hide content dynamically

I have used two approaches to dynamically show/hide sections, and it usually depends on the complexity of the data I'm working with. Approach 1 involves entering the expression right within the XML tag. * Approach 2* uses your own JavaScript functions. Personally I have found that Approach 2 provides better separation of concerns and improves the readability of the code significantly.

You can apply this to any element that accepts the visible="" attribute (such as the Text or HBox elements).

Approach 1: checking conditions inline

Example 1: If you know you are working with a boolean data type, you can add the following attribute to the desired element visible="{notifications>/error}", for example

<MessageStrip
     text="An error has occurred. Please complete the highlighted fields and try again."
     type="Error"
     showIcon="true"
     showCloseButton="true"
     class="sapUiMediumMargin"
     visible="{notifications>/error}"
>
</MessageStrip>

Example 2: If you are comparing against a string type, use visible="{= ${notifications>/error} === true}", for example

<MessageStrip
     text="An error has occurred. Please complete the highlighted fields and try again."
     type="Error"
     showIcon="true"
     showCloseButton="true"
     class="sapUiMediumMargin"
     visible="{= ${notifications>/error} === true}"
>
</MessageStrip>

Example 3: If you want to use a Boolean Operator inline, you will write out &amp;&amp; in between your conditions, like this: visible="{= ${notifications>/error} === true &amp;&amp; ${notifications>/showNotifications} === true}"

<MessageStrip
     text="Warning. All fields are required."
     type="Warning"
     showIcon="true"
     showCloseButton="true"
     class="sapUiMediumMargin"
     visible="{= ${notifications>/error} === true  &amp;&amp; ${notifications>/showNotifications} === true}"
>
</MessageStrip>
Approach 2: JavaScript functions

The second approach showed in this tutorial is using JavaScript functions, and it is my preferred method because it makes readability of the XML views much easier and separates the logic from the view and controller. For this to work we will need to do three things:

  1. Create the functions that will perform the validation. I created them in a separate file called Conditions.js that gets injected into the controller (you can just make this part of the controller, but for reuse purposes I separate them out). In the controller folder create a file called Conditions.js and add the following snippet:

Conditions.js:

sap.ui.define([], function() {
    "use strict";
    return {
        checkSingleCondition: function(flag){
            if(flag){
                return true;
            } else {
                return false;
            }
        },
        checkTwoConditions: function(flag1, flag2){
            if(flag1 && flag2){
                return true;
            } else {
                return false;               
            }
        }
    };
});
  1. Inject Conditions.js into controller. Using dependency injection make the functions available to the view via the Welcome controller. This is what Welcome.controller.js file now looks like.
sap.ui.define([
    "sap/ui/core/mvc/Controller",
    "sap/ui/model/json/JSONModel",
    "com/rikus-dev/controller/Conditions"
], function(Controller, JSONModel, Conditions) {
    "use strict";

    return Controller.extend("com.rikus-dev.controller.Welcome", {
        conditions: Conditions,
        onInit: function(){
            var notifications = {
               "showNotifications": true,
               "warning": true,
               "error": false,
               "success": false
            };
            this.notificationModel = new JSONModel();
            this.notificationModel.setData(notifications);
            this.getView().setModel(this.notificationModel, "notifications");
        }
    });
});

Step 3: Add the conditions in the XML views

Example 1: Single element

visible="{path:'notifications>/error', formatter:'.conditions.checkSingleCondition'}"

Example 2: Multiple elements

visible="{parts:['notifications>/warning', 'notifications>/success'], formatter:'.conditions.checkTwoConditions'}"

Results

Change the different boolean values in the controller and run the application (Right click the project name > Run > Run as > Web Application) to see the results.

I want to hear from you: can you get it to work with different data types like strings or integers?

Here are a few screenshots of the results, with different settings in the controller.

Conclusion

In this tutorial I showed you how to create show/hide content dynamically depending on the data.

Remember to subscribe to my blog, follow me on Twitter and check out my posts on Instagram!


© 2017