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 &&
in between your conditions, like this: visible="{= ${notifications>/error} === true && ${notifications>/showNotifications} === true}"
<MessageStrip text="Warning. All fields are required." type="Warning" showIcon="true" showCloseButton="true" class="sapUiMediumMargin" visible="{= ${notifications>/error} === true && ${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:
- 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 thecontroller
folder create a file calledConditions.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; } } }; });
- Inject
Conditions.js
into controller. Using dependency injection make the functions available to the view via the Welcome controller. This is whatWelcome.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!