Getting started with Visibility Conditions

by Lucio Bordonaro
13,023 views Published on Oct 24, 2011
Applies to: 7.2 or higher
Table of contents

Introduction

The Visibility and Disable Conditions features allow you to hide, disable or show elements in the generated pages of the Web application if the conditions specified are verified.

You can integrate the functional profiling of the Web application, both horizontal and vertical, filtering data in rows and columns according to the user profile.

An example of horizontal profiling is filtering the product list according to the country of the current customer. For this purpose the Domain Model contains information that connects the "Product" entity with the country ("country iso code" attribute). The following image shows the modeled page and the attribute condition applied to the "Products" list.

Suppose that the country of the current user is "IT". All of the products highlighted in green below will be extracted.

An example of vertical profiling is to hide the product prices from guest users. This behavior of the application cannot be modeled through components and conditional expression. The only option you have is to apply a Visibility Condition on the "price" attribute, stating to hide this information to specific user profiles.

Moreover, these conditions enable functional profiling: You can hide navigation flows by triggering operations or leading to pages that must not be accessed.

For example, you can hide the flows to the shipping process from all users who are not customers. The functional profiling is very useful when some user profiles differ for a few features onlyand you don't want to duplicate IFML Model sections.

Visibility Conditions, along with Rich User Interactions, help realize rich and modular forms. You can disable fields according to specific conditions and hide portions of a form according to the number of filled fields.

Because they decide visibility and disabling of page items, you can be apply the conditions to all the hierarchy of layout elements shown on the page:

  • Attributes
  • Fields
  • Flows
  • Components
  • Cells
  • Grids

When applying a condition, it is possible to choose to apply its negation using a dedicated button. This means to apply the condition using a logical negation that reverses the expected result.

Before you can use Visibility and Disable Conditions, you need to learn two basic concepts: Variables and Activation Expressions.

How to define a Variable

The starting point for defining a condition is the concept of a Variable. A Variable is used to store values in the page scope that can be used to create Activation Expression. It can be created as a sub-element of pages. There can be two types of Variables:

  1. Free. Their value is not bound to component attributes.
  2. Component Based. Their value strictly depends on component attributes.

A Variable, according to its type, has specific properties that must be configured in the Properties View. You can add a new variable in this way:

  1. Right-click on a page or a master page.
  2. Select the Add > Variable option.
  3. Write a name for the variable (e.g., "isCustomer") in the Name property. The name must respect Java naming conventions because the defined variable corresponds to a Groovy scripting variable.
  4. Choose a data type in the Type property. If left empty, no data conversion will be made.
  5. Press the Select button next to the Component property to choose the component of the page on which the Variable is based (optional).
    If you fill in this property, you define a component-based variable.
  6. Press the Select button next to the Parameter property to choose one of the output parameters of the component chosen into the Component property (optional).
    You can choose the output parameter from a drop-down menu (you can also choose values not used as Display Attributes). You must set this property if you want to define a component-based variable.
  7. Write the default value of the variable in the Value property (optional).
    If you fill in this property and leave the Component one empty, you can define a free variable.

How to define an Activation Expression

An Activation Expression is a Groovy expression that returns a Boolean value specifying if the condition is fulfilled or not. You can define Activation Expressions based on variables starting from pages or master pages.

You can create an Activation Expression in this way:

  1. Right-click on a page or master page.
  2. Select the Add > Activation Expression option.
  3. Move to the Properties View and write a name for the Activation Expression. Although not strictly necessary, it is a good practice to use a Java naming convention for the expression.
  4. Press on the Edit button next to the property to open the built-in editor. The Groovy expression defines the condition. Yyou can write a Groovy script that uses the variables defined on the page or master page.
    1. Take a look of all the available variables using the Variables… button in the upper right.
    2. See all of the available Groovy variables and methods, using the CTRL and SPACE shortcut to open the list of autocomplete suggestions.

Conditions Examples

Flow Visibility Condition

The Flow Visibility Condition lets you configure when to show or hide an outgoing navigation flow of a view component.

Suppose you have a page that enables order management and shipment. This page shows the details of an order, with two outgoing navigation flows:

  • The "Confirm Order" navigation flow, which connects the Details Component to the "Confirm" action, is used to set the final confirmation for an order and should be shown only if the order is not yet confirmed.
  • The "Ship Order" navigation flow, which connects the Details Component ot the "Ship Order" action, is used to proceed with the order shipment and should be shown only when the order is confirmed.

The following image shows the explained model.

The "Order" entity has a Boolean attribute to track the status of the order confirmation.

You have to define Visibility Conditions on the page to hide and show, alternatively, the "Confirm Order" and "Ship Order" navigation flows.

Because there is a Boolean attribute that tracks the status, it is a good practice to create a component-based variable that reads its value and use it to manage the visibility of the navigation flows.

Let's add a Variable to the "Order Details" page using the procedure explained in the "How to define a Variable" section (e.g., "isOrderConfirmed"). This variable is based on the "Your Order Status" component, and has the "confirmed" value as the Parameter property. 

When a variable is Boolean, it is not strictly necessary to use an Activation Expression to evaluate the result, but you can apply it directly as a Visibility Condition to the element (in this case the navigation flow).

  1. Select the "Your Order Details" component from the "Order Details" page.
  2. Open the Layout View. The Outline View becomes a Layout Outline so you can browse all of the objects shown in the page.
  3. Expand the Main Grid and the "Your Order Status" nodes; the two outgoing navigation flows are now visible in the Outline View.
  4. Select the "Confirm Order" navigation flow and move to its Properties View.
  5. Switch to the Condition tab.
  6. Choose the "isOrderConfirmed" variable from the drop-down to the Flow Visibility Cond. property.
  7. The navigation flow is visible when the order is not confirmed, so to apply the desired condition, you need to revert the logical result. Set the NOT operator at the right of the property.

 

NOTE. As you can see, when a Visibility Condition is applied on an element, the eyeglasses appear on the icon to indicate it.

 

Now, let's apply the Visibility Condition to the "Ship Order" navigation flow.

  1. Select the navigation flow from the Outline and move to its Properties View.
  2. Set the "isOrderConfirmed" variable in the drop-down list for the Flow Visibility Cond. property.

In this way, the "Ship Order" navigation flow is shown only when the order is confirmed.

This is the result of the generated Web application.

  

Flow Disable Condition

The Flow Disable Condition lets you configure when to disable an outgoing navigation flow from a view component.

Suppose you want to change the previous example in order to disable navigation flows instead of hiding them when not accessible. When a navigation flow is disabled, it is still shown on the page, but the user cannot interact with it.

You need to change the type of condition applied to navigation flows, setting the Flow Disable Cond. property instead of the Flow Visibility Condition.

  1. Open the Outline Layout View, selecting the "Your Order Status" detail component from the page and then from the Layout Grid.
  2. Expand the Main Grid and then the "Your Order Status" nodes.
  3. Select the "Confirm Order" navigation flow.
  4. Move to its Properties View and in the Condition tab, restore the "<Undefined>"option for the Flow Visibility Cond. property, clicking on the empty space in the drop-down.
  5. Apply the "isOrderConfirmed" variable as Flow Disable Cond. property choosing this Variable from the drop-down list.

In this way, when the order is confirmed, the navigation flow will be disabled on the page.

Repeat the same steps for the "Ship Order" navigation flow:

  1. Restore the "<Undefined>" option for the Flow Visibility Cond. property.
  2. And set "isOrderConfirmed" variable to the Flow Disable Cond. property.
  3. Because the logic is opposite with regard to the "Confirm Order" navigation flow, you need to revert the logical result using the NOT operator on the right.

In this way, the navigation flow is disabled on the page until the order is confirmed.

This is the result of the generated Web application.

 

Field Visibility Condition

The Field Visibility Condition lets you configure when to show or hide a field from a form component.

Suppose you have a page in which a customer can create an order by choosing the products and payment type. The user can confirm his order and proceed by adding the payment details; only when the ordered products are confirmed can the user select the payment type.

The "New Order" page contains a Multiple Form Component to manage all of the products that can be purchased and their quantity, as well as a Form Component with the date and type of payment. Both the Form-based Components have Mandatory validation rules on Fields. Data is loaded into Form and Multiple Form with Selector Operations, while today's date is loaded using a Time Operation.

The following image shows the explained model.

Now, let's add the logic to hide the payment type selection until the user confirms the ordered products.

Add a free Variable to the "New Order" page using the procedure explained in the "How to define a Variable" section (e.g., "areDetailsConfirmed"). See the configuration in the following image.

By default, when the page is loaded, the payment detail fields are hidden. The value of this variable changes when the user confirms the order details. 

The value of a variable can be changed when the user presses on a navigation flow, and for this reason, you need to set the parameters binding.
In this case, consider the OK Flow of the "Confirm Ordered Products" action. Double-click on the OK Flow to set the new value for the "areDetailsConfirmed" variable: Set the "true" value, and then press OK to confirm your choice.

Let's hide the "payment" field:

  1. Select the "Payment" form component from the model; in the Layout View, select the component again to open the Outline Layout.
  2. Expand the "Payment" node.
  3. Select the "payment" field and move to its Properties View.
  4. Switch to the Condition tab.
  5. Set the "areDetailsConfirmed" variable to the Field Visibility Cond. property.

This is the result on the generated Web application.

Before pressing the button:

After pressing the button:

Field Disable Condition

The Field Disable Condition lets you configure when to disable a field from a form component.

Suppose you want to improve the previous example by adding this feature: When the user confirms the ordered products all the fields of the Multiple Form are disabled to avoid changes. There is another outgoing navigation flow from the "Payment" form that once again enables the Multiple Form fields, to let the user edit the ordered products.

The following image shows the explained model.

Let's start by disabling the fields and the navigation flows of the Multiple Form Component when the user presses on the "Add Payment Details" button.

  1. Select the "Order" form component from the modeled page.
  2. Select it from the Layout Grid and move to the Layout Properties View.

The Disable Condition for fields and navigation flows can be set directly at the component level so that all the sub-elements will inherit this setting.

  1. Set the "areDetailsConfirmed" variable for the Field Disable Cond. and Flow Disable Cond. properties.

This is the result of the generated Web application.

Before pressing the "Add Payment Details" button:

After pressing the "Add Payment Details" button:

Let's now add the Visibility Condition for the "Edit Order Details" navigation flow. Right now it is already shown when the page is loaded, while the desired result would be to show this button only when the user presses on the "Add Payment Details" button.

  1. Select the "Payment" form component from the modeled page and then pick the Form Component from the Layout to open the Outline Layout.
  2. Expand the "Payment" node, then select the "Edit Order Details" navigation flow and move to its Properties View. Switch to the Condition tab and set the "areDetailsConfirmed" variable to the Field Visibility Cond. property.

This is the final result of the generated Web application.

Before pressing the "Add Payment Details" button:

After pressing the "Add Payment Details" button:

Context Parameter based Conditions

You can also create and use conditions starting from Context Parameters declared at the Web Project level. Suppose you have a "Master and Details" page of products where you want to hide the "price" attribute from all users that are not registered as customers.
The List Component shows the code and name of the product, while the Details Component shows all of the product's attributes. 

The following image shows the management explained.

Let's declare an Activation Expression verifying whether the currently logged-in user belongs to the customer group or not.

At Web Project level there is the definition of the "GroupCTXParam" context parameter, which already stores the current group assigned to a user and you can use it to check the condition. You need to create a condition at the Project level because all the required information is known so that it can be reused anywhere in the Web Project.

  1. Move to the Project View and select the Project node from the Outline View.
  2. Right-click on it and choose the Add > Activation Expression command. The new Activation Expression is created as a sub-node of the Project.
  3. Select it and from its Properties View.
  4. Give a meaningful name to the variable (e.g., "isCustomer").
  5. Set up the Expression by pressing on the Edit button on the right of the property and write the following Groovy script in the editor:
    return (groupCtxParam == "2")

    In this example, suppose that the "Customer" group identifier is "2". If you want to change the group or use another condition, update the Activation Expression script.

  1. Press the OK button to confirm.

Now, let's apply the condition to the "price" attribute of the Details Component.

  1. Select the "Catalogue" page and then from the Layout View, select the "Product Details" component.
  2. Move the Layout Outline View, expand the "Product Details" node, and select the "price" attribute.
  3. Move to its Properties View, switch to the Condition tab and choose the "isCustomer" option for the Attribute Visibility Condition property.

This is the result, before and after logging in as Customer, on the generated Web application.

Indexed Conditions

The Visibility and Disable Conditions can be applied to a list of information to show, hide or disable Attributes, Fields or Flows, using a condition on the value of a variable.

Suppose you have a List Component that shows the "Product" entity’s instances. The "Details" navigation flow outgoing from the List Component will be shown only if the product price value is greater than 100.

The following image shows the management explained:

Add a Variable using the procedure explained in the "How to define a Variable" section (e.g., "productPrice"). This variable is based on the "Products" list component, selecting the "price" value as the Parameter property.

Let's add to the page an Activation Expression using the procedure explained in the "How to define an Activation Expression" section (e.g., "checkProductPrice"). The Expression property must contain the following line of Groovy:

Return (price > 1000)

Now, apply this Activation Expression to the "Details" navigation flow:

  1. Select the "Catalogue" page, and then, from the Layout View, select the "Products" list component.
  2. Move to the Layout Outline View, expand the "Products" node, and select the "Details" navigation flow.
  3. Move to the Properties View, switch to the Condition tab and choose the "checkProductPrice" option for the Flow Visibility Condition property.

This is the result on the generated Web application.

How to centralize the Visibility Condition

If objects of the same type must comply with the same Visibility Condition in several points of the Web Project, you can centralize the condition.

For this purpose, you can use a Groovy condition to choose the elements to show, hide or disable, basing the choice on one of the element’s properties.
Consider the Indexed Conditions example. Suppose you want only users belonging to the customer group to be able to see the "price" attribute of the product. In this case, it is useless to choose each single element in the project and apply the condition to it. It is better to have a single place in which you can specify it.

Let's see how to do that.

  1. Move to the Project View of the Web Project.
  2. Select the Project node from the Outline View, and select the Condition tab from its Properties View.
  1. Press on the Conditional Visibility button next to the Attribute Visibility Condition property.
  2. Press the New button to create a new rule, in the opening dialog.
  3. Choose the condition to use (e.g., "isCustomer"), from the opened dialog.
  4. In the editor, write the following Groovy expression:
    return element["name"] == "price"

This scripts returns true, so it applies the condition only when the name of the attribute is equal to "price".

Generating the Web Project, you will get the same result of the previous example, but the Visibility Condition will be automatically applied to all the attributes called "price". You can define conditions with Groovy conditions at any Web Project level (Site View, Area, Page, Grid, Cell, Component, Attribute, Field, Flow).

Visibility Conditions in Custom Layout Templates

Every time you define a Visibility Condition on a Web Project element you are assuming that this condition will somehow be written in the resulting JSP page. This means that, if you are using a custom Style Project, you need to be sure that all of the Visibility Conditions are handled in your layout templates. You have to use a specific WebRatio Generation Tag to make Visibility Conditions work for this purpose: the <wr:Visible>, which manages the Visibility Conditions specified on a specific element.

The layout template types that must contain the Visibility and Disabled Condition management are:

Component Layout Template

You need to add the <wr:Visible> WebRatio Generation Tag for each attribute and navigation flow you print in this template.

If you are printing attributes or navigation flows singularly, you just surround each <wr:Value> and <wr:Link> occurrence with the <wr:Visible> WebRatio Generation Tag. Moreover, for the new WebRatio Generation Tag, you have to define the context attribute to evaluate the conditions for the specific attribute or navigation flow.

<wr:Visible context="address">
    <wr:Label context="address"/>
</wr:Visible>

If instead attributes or navigation flows are printed inside a <wr:Iterate>, you have to nest the <wr:Visible> WebRatio Generation Tag immediately after the iterate tag. Because the context is already set by the current iteration you do not have to define it.

<wr:Iterate var="link" context="unit" select="layout:Link">
  <wr:Visible>
    <td>
      <wr:Link class="link"/>
    </td>                                        
  </wr:Visible>
</wr:Iterate>

Flow Layout Templates

In these types of layout templates, you have to add the management if you are using a Disable Condition.

Take into account the following template lines of code.

[%
def disableCond = getDisableCondition(link, position)
def visibility = StringUtils.defaultIfEmpty(getVisibilityPolicy(getById(link["to"])), "hide")
def isProtected = isProtectedAncestorOrSelf(getById(link["to"]))

if (isProtected || disableCond != null) {
         if (isProtected && visibility == "hide" && disableCond == null) { %]
                 <c:if test="${[%=getLinkId(link)%].targetAccessible}">
         [% } else if (isProtected && visibility == "hide" && disableCond != null) { %]
                 <c:choose>
                          <c:when test="${not([%=getLinkId(link)%].targetAccessible)}"/>
                          <c:when test="${not([%=disableCond%])}">
         [% } else if (visibility == "inactive" || disableCond != null) { %]
                 [% def conds = []
                          if(isProtected && visibility != "always"){
                                   conds.add(getLinkId(link) + ".targetAccessible")
                          }
                          if(disableCond != null){
                                   conds.add("not(" + disableCond + ")")
                          }
                 %]
             <c:choose>
                 <c:when test="${[%=conds.join(" and ")%]}">
         [% }
}%]

// code to print active links
[% if (isProtected || disableCond != null) {
         if (visibility == "inactive"  || disableCond != null) { %]
         </c:when>
         <c:otherwise>
                 //code to print inactive links
         </c:otherwise>
</c:choose>     
[% } else if(visibility == "hide" && disableCond == null){ %]
         </c:if>
[% } %]
  • Lines 2-4. The "disableCond", "visibility" and "isProtected" are the Groovy variables that are used to manage all the possible situations due to applying a condition.
  • Lines 6-26. This code allows to check the possible situations to print the active navigation flows.
  • Lines 29-38. This code allows to check the possible situations to print the inactive navigation flows.

How to use the sample project

You can use the "ConditionsExample.zip" sample project attached to this article to test the proposed Visibility Conditions.

Follow these steps to use the project:

  1. Import the sample project in the WebRatio Platform. You can learn how to do this by watching the "Organize the Workspace" online lesson.
  2. Check the condition examples in the model.
  3. Generate the project with the "Generate and Run on Cloud" command if you have a WebRatio Community Platform version; otherwise, use the "Generate and Run" command.
  4. Visit http://localhost:8080/ConditionsExample/ or http://freeXXXXX-freeapp.eu.webratio.net/ using any browser, and follow the procedure.