Wednesday, November 16, 2011

Conditionally Displaying Table Records Based on Another records's attribute value. Conditionally making required attributes of those rows. ADF BC 11g


In this example we are going to create a small application demonstrating the following case:

Using a table, a value of  an attribute of a row, will determine if some other rows will be visible or not.
Furthemore, on those rows, specific attributes will be required or not.

Download Sample Application.

Lets get into the details.
We have a table, that we want to filter it's data. Ok, so far so good. We can do that by using the iterator's filter property in the pageDef. Additionally we are going to use a transient attribute that will keep the value we want to filter with.

Then, we want to have some attributes of those hidden rows to be mandatory only when those rows are visible.
The condition that will determine wether those attributes will be required or not will be based on a value of an attribute of another row.


We Have Row A, Row B, Row C and Row D which they are visible.
We have Row E, Row F which are not visible.

When we will set value to attribute d of  Row D, row E and row F will be visible with the same attributes to be required.

In fact we are going to make things a bit more difficult. We want to have validation erros only when pressing commit. This is due to ease of use reasons. Simply put, we do not want mandatory field messages to be thrown every time we change a row.
Last but not least, the attribute that will determine the visibility of other rows, will be a Yes/No radio Button.
So, this means that, when the user selects Yes on a RadioButton of a row, there will be some logic that will make other, specific rows, be visible and make their radioButtons be required.

The logic that will make the rows visible and the radio required is purelly in the scope of business requirements. In this example we are going to use a simple case. The scope of this post is to demonstrate the implementation in order to achieve this functionality.

We are going to create a table in the HR Schema.

The Sql Script is already included in the application.
Download the application and find the script called SampleData.sql

As you can see from the table, there is not something weird.. Columns may have different names depending on requirements.
After we run the script, we create our BC from JDeveloper wizard.

And we have the following BCs:

It is quite obvious that attribute SelectRadio is going to be our radioGroup of yes/no. So we are going to add a List of Values to this attribute. The List of Values is going to be a new view object with static values.
The attributes are going to be the following:

With the following DATA:

We set the Y and N just for simplycity.
After finishing the creation of the static VO we create an LOV in our sample View Object:

Then we just add the Static View object as an accessor.
We map the Selectradio attribute with the selectradio attribute with the choice attribute. and that is it.

Ok, so far we have created the VO with an LOV.

What we want now is to make the radio Group conditionally required. As we see in the db table. it is not required. We could have a entity validation method. But in this example we are going to try something different. We are going to use the required property of the radioButton.

Since, we will have another row determining the required property, we are going to follow this approach:

We will place a transient attribute in our viewObject called  ReqRadio. This attribute is going to determine if this the RadioButton is going to be required or not. So we add this attribute:

Now, the only thing left is to place the logic where this transient attribute will get a value.
Since a radioButton will determine if another radioButton of another row will be mandatory, we will have to do an iteration over all those rows that are dependent of that row.
For this example, we keep things simple. we have a column in our table in the DB which is called, typeofdata. As you will see in the rows, we have a record that has a value of MasterFormC and others that have value of formC. This example logic says that all rows that have formC and the radioButton of MasterFormC is with value Y, then, those records will have their radioButton required.

The simplest way to do that is to create a ViewCriteria in our ViewObject that we will use it to filter our rows. The Execution Mode will be set to memory

As you can see from the screen above, we set the typeofdata to be equal to "formC".
Next, we are going to create a method in our Application Module that will do the following:
First, we will check if the typeofdata is MasterFormC and then:
Will get the ViewCriteria of the View Object, apply it, get the RowSetIterator and set value to the transient attribute ReqRadio of each record.
The value to be set will be given as a parameter.

As you can see from the code, we return a message that we will use it later in our page.
Next, we expose this method to the client interface of our AM.

Next, we will create our page and we will drag and drop our table onto the page:

Then, we will surround our table with a panelCollection container and insert Commit and RollBack operations as toolbar Buttons in the toolbar which will reside in the toolbar facet of the panelCollection

As we mentioned earlier, we do not want to have validation errors every time we change a row... For that reason, we are gong to set the immediate property of the table to true.

The last thing to do onthe UI for the RadioButton is the requiredProperty. the required Property will be based on the value of the reqRadio:

Now that we have a pageDef, we will expose our AM method as a methodAction:

Additionally, we want to filter our iterator with all those rows that can be visible due to our business logic.
For that, we are going to create a transient attribute that will be called IsVisible. We are going to change a bit the code in the getter of this attribute (we have to create the ViewRowImpl jav class of our view object first and select the generateAccessors property):

With the above code, we will know if this row is to be visible or not.
Onto our pageDefinition:
in the pageDef, we select the iterator of our View Object and we wil enable the filtering:

Now we will be able to filter our table properly.
Last but not least, is our radioButton. We set it to autoSubmit=true in the page. We then create a valueChangeListener for our RadioButton.
Additionally we will create a popup with a dialog and an outputFormatted text with value of a pageFlowScope variable.

Then, we create bindings for the popup and the table. This will allow us to programmatically show the popup and partialTarget our table.

And That is it.

If you run the application You will see that initially, the data are filtered and depending on the value of the MasterFormC typeofdata, the rows are becoming visible and required. Additionally there is a popup Shown when the rows are becoming visible notifying the user that the following rows must have a value on their radioButtons.

Download Sample Application.


1 comment:

  1. well.. good post but very long. main point though was setting the filter for the tree.



Related Posts Plugin for WordPress, Blogger...