Getting started with Visibility Conditions
From Wiki
Visibility Conditions
Introduction
WebRatio introduced the chance to use visibility conditions in a Web project. This feature allows you to disable or show elements in the generated Web application if the conditions specified for those elements are verified.
It's now possible to integrate the Horizontal Profiling of the Web application (which means to filter the records of a table according to the user profile) with the Vertical Profiling that allows to filter the columns of that table according to the user profile. Consider for example the Acme project. Horizontal Profiling can be modeled filtering the product list according to the country of the current customer. This implies that the data model has to contain information that connect products with the country. The following image shows an example.
|
An example of Vertical Profiling is, for instance, hiding the information related to the product and combination prices to guest users. This "behaviour" of the application can not be modeled through units and selectors as the previous one. Using a visibility condition on the "price" attribute you can hide this information to the user profiles that have not to access it.
Moreover visibility conditions allows Functional Profiling. You can hide links that brings the user to specific operations or to pages that must not be visible to a user profile. For example you can hide the links to the shipping process to all the users who are not customers. This is very useful when some user profiles differ for few features and you don't want to duplicate portions of Web Model. Finally you can realize Modular Forms. It's possible to disable fields according to specific conditions and also to hide a portion of a form till the user filled in all the information needed in order to have access to that set of fields.
How to create a Visibility Condition
The starting point to define a visibility condition is the concept of Variable. A variable can be created at the page and master page level. To add a new varible right click on the page or on the master page and choose the "Add Variable" command. In order to create a variable you have to specify its property in the Properties View:
- Name. The name of the variable. This name must respect the Java code conventions because it identifies the variable name in the script expressing the visibility condition.
- Unit. A unit of the page which the variable is based on. Click the button next to the property in order to choose the unit. If you fill this property you are going to define a unit-based variable.
- Parameter. An output parameter of the unit chosen in the previous property. You can choose the output parameter directly from a list showing the possible parameters.
- Value. The default value of the variable. If you fill this property and you haven't choose a unit you are defining a free variable.
The next step is to define a Condition Expression. A condition expression is a Groovy expression that returns a boolean value specifing if the condition is fulfilled or not. You can define condition expressions based on variables starting from pages or master pages. To create a condition expression right click on a page or master page and choose the "Add condition expression" command. In the Properties View fill the properties for the condition:
- Name. The name of the condition expression. Although not striclty necessary, it is a good practice to choose distinct names for different condition expressions.
- Expression. The Groovy expression defining the condition. Click on the button next to the property to open the editor. Here you can write a script Groovy that uses the variables defined on the page or master page.
Visibility Condition can be applied to different elements belonging to Web Projects. Here is the elements list:
- attributes
- fields
- links
- units
- cells
- grids
In all cases the steps to create and apply conditions are the same. Let's see some examples.
Link Visibility Conditions
Suppose you want to model an e-commerce part in the Acme project. In particular you want to model the page that allows the orders management. The page shows the "Checkout" link only if the order isn't already checked out and the "Create Invoice" link only if the order is checked out. First of all, add in the data model the entities for storing orders and order lines. In the following figure there is an example of the data model. It's important that the "Order" entity has a boolean attribute for the order state (e.g. state).
Then you have to model the hypertext accessing the order information like in the following figure.
In order to alternatively hide or show the "Checkout" and "Create Invoice" links you have to define visibility conditions on the page.
- Add a Variable to the "Order" page. In the Properties View type "orderState" for the variable name. Choose the "Order" data unit for the Unit property and then select the "state" attribute in the Parameter property. Note that you can choose one of the unit output parameters that are not related to the display attributes chosen for the same unit.
- Add a Condition Expression to the "Order" page. This condition verifies whether the order is checked out or not. In the Properties View type "CheckedOut" for the condition expression Name. Then click on the button next to the Expression property and write the following Groovy script in the editor:
return orderState
- Add a Condition Expression to the "Order" page. This condition verifies if the order is not checked. In the Properies View type "NotCheckedOut" for the condition expression Name. Then click on the button next to the Expression property and write the following script Groovy in the editor:
return !orderState
Now you have to associate the condition to the links.
- Click first on the Grid View and then choose "Checkout" link in the Outline View. In the Properties View you can see a new tab for the link, the Condition tab. In this tab there are two different properties. The Link Visibility Condition property allows to set a condition to hide or show a specific link; the Link Disable Condition property allows to set a condition to disable or enable a specific link. Suppose that you want that the user sees the link only if he/she can use it. In this case select the Link Visibility Condition condition property and choose from the dropdown menu the "NotCheckedOut" condition expression.
- Click first on the Grid View and then choose the "Create Invoice" link in the Outline View. In the "Condition" tab select the Link Visibility Condition property and choose from the dropdown menu the "CheckedOut" condition expression.
Now you can generate the Web application and see the result. You can see an example of the final result in the following figures.
|
Link Visibility Conditions (with AJAX Features)
You can use the previous example and create the correspondent AJAX version. You just have to select the "Checkout" link and, in the Properties View, check the Enable AJAX property. In this way when the user tries to check the order out, the application reloads only the information of the order and shows the "Create Invoice" link.
Link Disable Conditions
Suppose that you want to change the previous example in order to get the links disabled if not accessible. We have just to change the logic used to apply the conditions to the links and to set another property in the "Condition" tab of the Properties View, that is the "Link Disable Condition" property.
- Click first on the Grid View and then choose "Checkout" link in the Outline View. Select the Link Disable condition property and choose from the dropdown menu the "checkedOut" condition expression.
- Click first on the Grid View and then choose the "Create Invoice" link in the Outline View. In the "Condition" tab select the Link Disable condition property and choose from the dropdown menu the "notCheckedOut" condition expression.
Now you can generate the Web application and see the result. You can see an example of the final result in the following figures.
|
Link Disable Conditions (with AJAX Features)
Suppose you want to model a registration page. In this page the user has to fill some fields with his/her personal data and then he has to accept the terms of registration. You want that the user can proceed with the registration and click to the "Register" button only when the user has chosen the "Yes" option of the "Accept Agreement" field. The Web model can be something like in the following figure:
To complete correctly the model you have to:
- Select the the "Accept Agreement" field and select the "AJAX" tab in the Properties View. Choose the Enable Event property and then choose the link going to the "Set Accepted" operation unit for the Event Link property.
- Choose the link incoming into the "Set Accepted" operation unit and uncheck the Validate property if you have modeled some Validation Rules on the fields. Then open the Coupling Dialog and choose the "Agreement field" as Passing parameter.
- Add a variable to the "Registration page" page. In the Properties View type "accepted" for the variable name. Type "false" in the value property.
- Add a condition expression to the "Registration page" page. This condition verifies whether the user has accepted the agreement or not. In the Properties view type "agreementNotAccepted" for the condition expression Name. Then click on the button next to the Expression property and write the following script Groovy in the editor:
!accepted
- Click first on the Grid View and then choose the "Register" link in the Outline View. In the "Condition" tab select the Link Disable Condition property and choose from the dropdown menu the "agreementNotAccepted” condition expression.
- Select the OK link outcoming the "Set Accepted" operation unit and open the Coupling Dialog. In the "Variable" tab couple the passing parameter with the "accepted" variable.
|
Field Visibility Conditions
Suppose you want to model a page in which a customer can create an order filling his shopping cart. You want that when the user confirm his shopping cart, the application creates the order and shows to the user the same page with the fields necessary to fill the shipping address.
To obtain this model you have to:
- Add two fields to the Multi Entry unit. The first field is a selection field filled with the products list. The second field is the quantity field.
- Add three fields to the Entry unit ("Shipping Address", "Shipping Country","Shipping City").
- Add a variable to the "Shopping cart" page. In the Properties View type "orderConfirmed" for the variable Name. Type "false" in the Value property.
- Add a condition expression to the "Shopping cart" page. This condition verifies whether the user has confirmed the order or not. In the Properties View type "isConfirmed" for the condition expression Name. Then click on the button next to the Expression property and write the following script Groovy in the editor:
orderConfirmed == "true"
- Click first on the Grid View and then select each field of the Entry unit from the Outline View. In the "Condition" tab select the Field Visibility Condition property and choose from the dropdown menu the "isConfirmed" condition expression.
- Select the OK link pointing to the page. In the Properties View check the Preserve Form and then open the Coupling Dialog. In the "Variable" tab write "true" in the source field related to the "orderConfirmed" variable.
The following images show an example of the Web application result:
|
Field Visibility Conditions (with AJAX Features)
Suppose you want to improve the registration page of the previous AJAX example allowing the user to specify a shipping address. You suppose that, by default, primary and shipping address are the same, but, if the user unchecks the field "Use Primary address as Shipping Address" he have to type information into the shipping address fields. The Web model becomes as follows:
To obtain this model you have to:
- Add to the "Registration" Entry unit three fields ("Shipping Address", "Shipping Country" and "Shipping City").
- Add to the "Registration" Entry unit another boolean field named "Use Primary Address as Shipping Address." Add a Slot to this field and in the Properties View type "true" in the Value property of the slot.
- Connect the "Registration" Entry unit with the "Set accepted" operation unit with a normal link named "Shipping Address". In the Properties View uncheck the Validate property and open the Coupling Dialog. Choose the "Use Primary Address as Shipping Address" field as Passing parameter.
- Add a variable to the "Registration page" page. In the Properties View type "useSameAddress" for the variable Name. Type "true" in the Value property.
- Add a condition expression to the "Registration page" page. This condition verifies whether the user has unchecked the boolean field "Use Primary Address for Shipping Address" or not. In the Properties View type "showShippingFields" for the condition expression Name. Then click on the button next to the Expression property and write the following script Groovy in the editor:
useSameAddress == "false"
- Click first on the Grid View and then select each "Shipping" field from the Outline View. In the "Condition" tab select the Field Visibility Condition property and choose from the dropdown menu the "showShippingFields" condition expression.
- Select the OK link outcoming the "Set Accepted" operation unit and open the Coupling Dialog. In the "Variable" tab couple the passing parameter related to the "Use Primary Address as Shipping Address" with the "useSameAddress" variable.
The following images show an example of the Web application result:
|
Field Disable Conditions
Suppose you want to improve the previous example regarding the shopping cart. You want that when the user confirm his shopping cart, the application creates the order and shows to the user the same page with all the fields disabled, just to have a summary of the order. The Web model can be something like the following figure:
To obtain this model you have to:
- Click first on the Grid View and then select each field of the Multi Entry unit from the Outline View. In the "Condition" tab select the Field Disable Condition property and choose from the dropdown menu the "isConfirmed" condition expression.
- Select the OK link pointing to the page. In the Properties View check the Preserve Form and then open the Coupling Dialog. In the "Variable" tab write "true" in the source field related to the "orderConfirmed" variable.
The following images show an example of the Web application result:
|
Field Disable Conditions (with AJAX Features)
Suppose you want to modify the registration page of the previous AJAX example showing as disbaled the fields to specify the shipping address. You suppose that, by default, primary and shipping address are the same, but, if the user uncheks the field "Use Primary address as Shipping Address" he is able to type information into the shipping address fields. The Web model becomes something like in the following figure:
To obtain this model you have to:
- Select the three fields "Shipping Address", "Shipping Country" and "Shipping City" and set all of them as preloaded.
- Add a NoOperation unit named "Copy value into Shipping field".
- Connect the "Registration" Entry unit with the "Copy value into Shipping field" unit through a normal link named "Blur". Uncheck the Validate property for this link. Open the Coupling Dialog and choose all the fields related to the primary address as Passing parameters.
- Connect the NoOperation unit and the Entry unit with an OK link. In the Properties View check the Preserve Form property. Then open the Coupling Dialog and couple the passing parameter with the shipping fields.
- For each "Primary" field select the "AJAX" tab in the Properties View. Check the Enable Event property, choose "On Blur" for the Event Type and select the link going to the "Copy value into Shipping field" as the Event Link.
- Add a condition expression to the "Registration page" page. This condition verifies whether the user has unchecked the boolean field "Use Primary Address for Shipping Address" or not. In the Properties View type "usePrimaryAddress" for the condition expression Name. Then click on the button next to the Expression property and write the following script Groovy in the editor:
useSameAddress == "true"
- Click first on the Grid View and then select each "Shipping" field from the Outline View. In the "Condition" tab select the Field Disable Condition property and choose from the dropdown menu the "usePrimaryAddress" condition expression.
- Select the OK link outcoming the "Set Accepted" operation unit and open the Coupling Dialog. In the "Variable" tab couple the passing parameter related to the "Use Primary Address as Shipping Address" with the "useSameAddress" variable.
The following images show an example of the Web application result:
|
Context Parameter based Visibility Conditions
You can also create and use Visibility Conditions starting from context paramaters declared in the Web project. Suppose you want to hide the price attribute to all the users that are not registered customers. The first thing you need to do is to declare a condition expression veryfing whether the current group of the user is "customer" or not. Let's see how to obtain the desired result. First of all create a page to show the product list and see the product details as the following figure:
- Select the Project tab from the workarea.
- Right click in the workarea and choose the Add condition expression command.
- In the Properties View type "isCustomer" for the condition expression Name. Then click on the button next to the Expression property and write the following script Groovy in the editor:
GroupCtxParam == "2"
- Select the Product page and select the Grid View. Select the Data unit and choose the "price" attribute from the Outline. In the Properties View, choose the "Condition" tab. Select the Attribute Visibility Condition property and choose from the dropdown menu the "isCustomer" condition expression.
N.B. In this example we are supposing that the "customer" group has "2" as its identifier. You have to change the number in the condition expression if this group has a different identifier on your database.
Here is an example of the final result with manager/manager login and then with customer/customer login:
|
How to apply a Visibility Condition using Groovy Conditions
You can also associate a Groovy condition to the Visibility Conditions to choose the elements to which the Visibility Conditions apply according to some model properties. Taking into consideration the previous example, suppose that you want that in the whole project, only users belonging to the "customer" group can see the price attribute of the product. In this case it's useless to choose each single element in the project and apply the visibility condition to it. It's better to have a single place in which you specify this Visibility Condition. Let's see how to do that.
- First of all, in the "Products" page select from the Outline of the Grid the price attribute of the Data unit and clear the "Attribute Visibility Condition" property.
- Select the Project tab.
- In the Properties View select the Condition tab.
- Click on the button next to the Attribute Visibility Condition property.
- In the opening dialog choose the "is Customer" Condition Expression. In the editor write the following Groovy script:
return element["name"] == "price"
Generating the Web project, you will get the same result of the previous example, but if you add to the Web model other units or pages having the "price" attribute as display attribute, the Visibility Condition will be automatically applied to all these display attributes. You can define Groovy conditions for Visibility Conditions at any Web project level (Site View, Area, Page, Grid, Cell, Unit, Attribute, Field, Link).
Visibility Conditions in Custom Templates
Everytime you define a visibility condition on an Web Project element you are assuming that this condition will be written somehow in the resulting JSP page. All the WRDefault templates have been refactored taking into account this new feature and so if you are using the WRDefault style you will see all the visibility conditions work properly.
If you want to use visibility conditions with your own style and templates, you have to make adjustments on the templates, in order to make them consider these new information stored in the Web Model. WebRatio provides a new WR tag, the <wr:Visible> tag, that allows to retrieve the visibility conditions specified on a specific element and writes the related code. The template you have to modify are:
- Unit templates. You have to add here the <wr:Visible> tag for each attribute and link you print in this template. Let's make an example. Suppose to have the following Data Unit template in which the "address" and the "city" attributes are printed individually.
#?delimiters [%, %], [%=, %]
[%
def address = unit.selectSingleNode("layout:Attribute[@name='Address']")
def city = unit.selectSingleNode("layout:Attribute[@name='City']")
%]
<c:if test="${not(empty <wr:UnitId/>) and (<wr:UnitId/>.dataSize gt 0)}">]
<wr:Frame>
<div class="plain <wr:StyleClass/>">
<div class="plain DataUnit">
<table border="0" width="100%" cellspacing="0" cellpadding="0" >
<tr>
<th class=" header" nowrap="nowrap">
<wr:Label context="address"/>
</th>
<td class="value">
<table border="0" cellspacing="1" cellpadding="2">
<tr>
<td style="font-size:100%">
<wr:Value context="address"/>
</td>
</tr>
<tr>
<td style="font-size:100%">
<wr:Value context="city"/>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</div>
</wr:Frame>
</c:if>
[% } %]
You have just to surroung the two <wr:Value> tags with the <wr:Visible> tag. Moreover you have to pass to the tag the "context" attribute in order to tell it which is the attribute of which you want to print the visibility condition.
....
<wr:Visible context="address">
<wr:Label context="address"/>
</wr:Visible>
....
....
....
<wr:Visible context="address">
<wr:Value context="address"/>
</wr:Visible>
....
....
....
<wr:Visible context="city">
<wr:Value context="city"/>
</wr:Visible>
....
The logic is the same of all the other WR tags. This means that, if the tag is placed inside a <wr:Iterate> you do not have to pass the context since it is able to retrieve it from the current iteration context. See the WebRatio User Guide for other information. Let's see an example on the link iteration.
// before visibility conditions <wr:Iterate var="link" context="unit" select="layout:Link[not(Property[@name='lightbox'])]"> <td> <wr:Link class="link"/> </td> </wr:Iterate> //after visibility conditions <wr:Iterate var="link" context="unit" select="layout:Link[not(Property[@name='lightbox'])]"> <wr:Visible> <td> <wr:Link class="link"/> </td> </wr:Visible> </wr:Iterate>
- Link templates. These templates has to be modified if you are going to use Disable Conditions on links. Take into account the following template in which these conditions are not managed. The code reported is only the portion interested in the change.
//before disable conditions
...
[% def visibility = getVisibilityPolicy(getById(link["to"]))
if (isProtectedAncestorOrSelf(getById(link["to"]))) {
if ( visibility == "" || visibility == "hide") { %]
<c:if test="${[%=getLinkId(link)%].targetAccessible}">
[% } else if (visibility == "inactive") { %]
<c:choose>
<c:when test="${[%=getLinkId(link)%].targetAccessible}">
[% }
}%]
// code to print accessible links
[%
if (isProtectedAncestorOrSelf(getById(link["to"]))) {
if (visibility == "inactive") { %]
</c:when>
<c:otherwise>
//code to print inactive links
</c:otherwise>
[% } %]
[% if ( visibility == "" || visibility == "hide" ) { %]
</c:if>
[% } else if (visibility == "inactive") { %]
</c:choose>
[% } %]
[% } %]
//after disable conditions
[%
def disableCond = getDisableCondition(link)
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>
[% } %]
Download the Sample Project
Right click on the following link to download a sample project containing all the resources to test this article.














































