Showing posts with label ADF Master Detail. Show all posts
Showing posts with label ADF Master Detail. Show all posts

Tuesday, March 6, 2012

Group Detail VO records as SelectOneRadios and the power of LOV (List of Values) and View Criteria. ADF 11g

Hi,

This is an example demonstrating the usage of selectOneRadio component.

Download Sample Application.

User Requirement:

We want to be able to change the manager of a department  by selecting one of the already existing Employees in a form of radio Buttons. This will enable us the functionality to always see every information we want and select accordingly.


Model: We are going to use the HR schema.
We are going to generate the following tables

  • Department
  • Employees


Thoughts:
How are we going to create the radio buttons?? All we have is a master detail relationship between Departments and Employees.


Our BC generation with the help of  the JDev wizard. As you will see below, all unneeded stuff for this case are removed.



Basically we want to change the managerId of the Departments table.. (how about an LOv?)


NOTE: in this post, we are going to follow another approach of explaining things...
We are going to follow the first thing that it might come in mind. Then we are going to think it over and see the simplicity of things. This is an experimental way of approaching a matter and covers the case where things are not that clear in our mind regarding the best approach to follow. Sometimes I find people accepting solutions "as is" without considering to challenge them. With this approach, we are going to rethink some approaches in order to determine which is the simplest and best

I know! We can use the selectOneRadio UI Component!  (Do not hold your breath just yet... we are still thinking here!  :F  )
Each Employee will be represented as a selectOneRadio! (How about an LOV?)
Great.
This means that we are going to create our af:table with our Departments:



select Single Row::



Then, create another column inside that table:



OK, we now have our own departments table. All we have to do is to drop the Employees in the new Column:



From the attributes wizard we can expand the  choice list and select multiple items:




By now, according to plan (Still, do not hold your breath just yet... we are just following one thought.. Unfortunately these thoughts are the ones that come in mind first...... so lets see where this leads us...)


And how are we going to actually set the new value of the selected Employee as a the new managerId?

UUh.. we are going to override the setter of... uuh.. I do know just yet.. I have to thing about it.
OK..
Lets see the out of the box behavior of our application.. Lets just run the application.

The that we developed here is the following:

As you will see, we have the same employees for every Department!!!

After we change the row of the Departments, all of the sudden, we new Employees!!!



Obviously, this is not that good.....

Why is this happening? It should not be happening.... should not it?
Well, it should and it does so..

The detail here (Employees) is refreshed after the change of the current row of the Master (Departments). That is why we see the radiogroup change after we select a new row.

We make the new row current. The framework queries (or gets the appropriate collection) the detail.
This is the out of the box functionality.

Can we make it work?  Yes, we have to make several changes in order to make this working..

But is it not already  complicated as it is?????

Are we really considering in continuing towards this approach? This approach already produced many issues to think of . Not to mention that we have not yet figured out how are we going to update the managerId of the Department..

At this point, we have a very clear indication that the above approach is not the appropriate one.




Re-thinking:


Ok. lets start over..
What do we exactly want?
We want to be able to "appoint" an employee as a manager for a specific Department.
We want to do that, by selecting the appropariate Radio Button.
Furthermore, as the user or someone else would say:

" I would like to be able to see a table with all the departments and inside each Department, I would like to see a list of all employees and be able to see which of them is the manager and be able to choose and change the Manager"

Ok... I know, it might not be that detailed in many cases.... but lets follow it..

As we saw earlier, the first approach, the one that came to mind was not that easy to implement. for that reason we dropped it and we will Re-think everything in order to find a better solution.

How about LOVs???

We could create an LOV in the managerId attribute of the DepartmentsView...
This LOV will represent only the Employees of the specific Department.

What do we gain by this??

  • The Framework handles the setting and the getting of the managerId.
  • we ensure that the appropriate employees will be shown in the list of employees.
  • We ensure that all employees will be grouped together and will be treated as a group. This means that only one will be always selected.

How are going to do the following?

  • How are we going to create the LOV?
That is easy. We will locate the managerId Attribute in the DepartmentView and then we will create the LOV. Just follow the screens below:

locate the attribute:


Add the new accessor:




Select the corresponding Attribute:




go the UI Hints tab and select the type of the LOV to Radio Group



Then select the attributes you want to be visible  in each row of the List Of Values:



 Click ok.

We have now created our List Of Values and set its type to Radio Group. I was not that easy was not it?


Next Question:


  •  How are we going to filter the Data to the corresponding Department?

this is quite Simple, we will create a view Criteria to EmployeesView. Just follow the screens below:

Locate the EmployeesVie



in the Create View Criteria Wizard, add an Item:




locate the managerId and select it. Then select Bind Variable and press the green sign.
In the new window, change the name of the bind Variable and change also the type to Number. Since we are creating a Bind Variable to bind an Attribute it must have the same type. Click ok in both dialogs.




and there you go. the View Criteria is created:


 Next Question:


  • How are we going to set the appropriate DepartmentId value for every department??
That is even more easy.. All we have to do is to "enable" the View Criteria we have created. 
After the creation of the LOV in the DepartmentsView, a ViewAccessor was created in that DepartmentsView:





If you select the accessor and click on the pencil button you will see that we can have access to the View Criteria!




In order to always apply the View Criteria we have created. we will have to shuttle it on the right. with this way the View Criteria will be on the Selected side. Below you see that we also have access to the Bind Variables of that View Criteria. The value column is empty. In Order to set the proper value, we have to provide the name of the Department Id attribute of the DepartmentView, which is "DepartmentId". We verify this by checking the Attributes of the DepartmentsView.






Next Question:

  • How are we going to represent this properly.
That is even more easy!! We will simply drag and drop the DepartmentsView onto the page and select af:table.

As you can see below, while drag and drop as shown in our previous thought the managerId is already set as a Select OneGroup:



After fixing a bit the layout. Once we run the page we will see the following:







One Last Question:

  • Do we need the hierarchy represented in the Application Module?
Nope.. we dont. all we need is the DepartmentsView shuttled in the Application Module. Since we will be using the LOV, we do not need to have additional View Objects in our Application Module. So, we can remove the EmployeesView from our Application Module and keep only the DepartmentsView.



NOTE: This is a purely illustrative example of the benefits of using List Of Values. This is not a  real example and for that reason it might not fit your needs in terms of data.


Download Sample Application.


Regards.

Friday, November 18, 2011

Master-Detail-Detail. Using Tree Table and Table. Using Target Data Source featrue. ADF BC 11g

Hi,
This is an example demonstrating the usage of treeTable and table of ADF all together.


Download Sample Application.


We are going to use the HR Schema and more specifically the following tables:
Departmens,
Employees,
EmployeesViewDetails.

Departments and Employees are going to be the Master detail that will be displayed in the Tree Table
the EmployeesViewDetails will be the detail table shown below the tree Table.

After generating the appropriate Business Components through JDeveloper wizard, we are going to create an additional association and a viewLink.
Because the EmployeesViewDetails is a database view, the associations are not provided by JDeveloper wizard.
Furthermore, we are changing the the Primary Key of the EmployeesViewDetails from RowId to EmployeeId.


Association:


ViewLink based on that association:


Finally we reach to a point where we will create the Application Module hierarchy:
This is the tricky part. at this point, we have to understand two things:
One, we are going to use the Target Data Source feature. This feature according to the following documents
http://www.oracle.com/technetwork/developer-tools/adf/master-detail-moredetail-154767.html

http://www.oracle.com/technetwork/developer-tools/adf/learnmore/sept2011-otn-harvest-508189.pdf

needs to point value that corresponds to a key of the other iterator..
Additionally the JDeveloper documentation for this feature says:

 So, what we have to do is to point the right value to the right Key..

Two, Our hierarchy is not going to be the following:


Is going to be the following:


Now, why is that???
Simply because, we want to use the target Data Source feature, and for that reason, we need to map the same key attributes.
Further more, we do not want to show the details on our tree.... We just want to show it on a separate table.

The concept is simple: We have to have the same keys to synchronize properly.
Now, to our case, apparently, we cannot synchronize Employees and EmployeesViewDetails directly, for the simplest reason that we are on a master-detail-detail situation...

In fact, our example is a very special case, because it is a pure coincidence that Employees and EmployeeViewDetails have the same attribute as a primary key.

According to documentation, a draft and general explanation would be the following:

the targeted Data Source iterator, will find a row where it's key value is the same as the key value of the selected row of the iterator that invokes the target Data Source iterator and will set this row to current.

well, reading it again, it is not simple at all!! :D
ok lets try again...

The targeted iterator will simply search for a row in the list and make it current. 
The key of that row, will have the same value as the key of the selected row in the tree.

hmm... still not good..

The iterator that uses the target Data Source  feature, will force the specified iterator to find a row with the same key value as the previous one.

I give up.... :D
Well, so if we had just added the EmployeesViewDetail without having it as a detail under Employees... we should have seen all employees and every time we selected an employee, the employeesViewDetail table would simply change the current row.
And of course, we do not want that..
So, the best approach is the one showed in the screen.
Why? Well, when we select an employee from the tree, the target Data Source feature will invoke the other employees iterator, which in turn will invoke the employeesViewDetails iterator to refresh because, after all, it is a detail right?..


Next, we are going to Create our page.
First, we will create a task flow and a jspx on it.
Onto jspx, we drag and drop the departments Iterator from the dataControl and we select, treeTable.
Then, we add a rule for the Employees as shown in the Screen below.



For Departments rule, we shuttle DepartmentId and Department Name attributes.
For Employees rule, we shuttle EmployeesId, firstName and lastName.
Next, we surround our treeTable with a panelCollection.  We Simply right click on the tree table component and we select panelCollection.



Since treeTable component, does not create other than the node column, we will create them ourselves.



After that, we surround the panelCollection with a panelGroupLayout with type Scroll. This will be the parent Container of both, our treeTable and table.


At this point, we have to apply the target Data Source feature. As we explained earlier, we are going to set this feature for the Employees detail iterator of the Departments master iterator. This Employees iterator will point to "other" Employees iterator.
But first, we have to add this iterator. So in our page definition we add the other Employees as iterator.

Then, we are going to set our Target Data Source value.
We simply select the tree of Departments and then the rule of Employees,
after that, we expand the target data source option and open the help wizard to choose our iterator. The iterator would be the "other" Employees iterator.


Now, every time we select an employee from our tree, the "other" employees iterator will change the current row to the same as the selected in the tree.
All we have to do now is to drag and drop the EmployeesViewDetails from our Data Control


After that, we surround the table with a panelCollection (the usual best practice..) and set partial triggers to table from the tree table.

And that is it!
When you run the page you will see a row in the empsDetailsView ofcourse, since it is querying, but this is not the scope of this post.. When ever you select an employee the table will be refreshed with the employee's details.


Download Sample Application

Regards.

Thursday, November 10, 2011

Master Detail CRUD operations with Regions ADF 11g

Hi,

This is an example that demonstrates how to create a Master Detail relationship between tables by using Regions. The main purpose of regions is the notion of reusability. With regions and bounded task flows we can reuse our pages into many other pages keeping the same functionality and having a more cleaner approach.

Download the Sample Application.

For this example we are going to use only one Model project and keep things simple.
We are going to create our Business Components through JDeveloper and it's wizards.
We are using Master Detail for Departments and Employees.


So, we are going to create two Bounded Task Flows that use fragments.
One for the Departments
One for the employees.

In each bounded task flow we drag and drop a view and place the appropriate names of departments and employees.



Then in the unbounded flow we create a jspx that will have two Regions defined.
One for the Department BTF
One for the Employees BTF

For Departments we are going to drag and drop the Departments iterator as a form with navigation buttons and submit button. Additionally, we add the createInsert and Delete Operation buttons next to submit



We do the same with employees. The only difference here is that  we drop an editable table and not a form. Additionally we drag it from the hierarchy and not the alone one in our Data Control. This means that we drag the detailed employees.


Next, we are going to create an index page in our unbounded task flow that will contain our Bounded Task Flows as regions.

In order to that, after we created the index page, we simply drag and drop each Bounded Task Flow as a Region


We do the same for the Employees Bounded Task Flow.
Up to now, we have our hierarchy done and well placed. Since we share the same application module instance, we are good to go!!
All that is left now is to place commit and rollback buttons in our Departments fragment and we are done!
For the rollback button we have to make a specific adjustment:
The emps region needs to be refreshed and indicate that the rollback is performed. For this reason we are going to set the refresh property as follows:



So, what we do here is, to set a refresh condition on our detail region. What we say here is, refresh emps fragment when the dept fragments is refreshed.

NOTE: this is a simple application demonstrating the ease of use of Regions. It is not intended to cover all aspects of regions.


Download the Sample Application.

Regards.

Thursday, October 20, 2011

Master Detail Data presentation and CRUD Operations. Detail records in an Editable Popup. ADF 11g

Hi,

This yet another example of Master Detail data representation.
The difference here is that, the Detail rowsets will be presented in a popup.
We are going to use HR schema of Oracle XE for this example.

Download Sample Application.

We are going to use Departments as the Master and Employees as the Details.
Departments will be presented in an table.
The Departments table will have all CRUD operations. Insert, Update, Delete. Additionally there will be a Rollback button.
Every Record in the Departments table will have an additional column where an edit button will reside.
The edit button, when pressed, will show a popup which will present another table, the table of the Employees that work to this Department.

Using the Generate Business Components From Tables wizard of JDeveloper, we produce all the necessary entities, associations, view objects and viewlinks. It is a very straightforward process.




After having the BC created along with the Application Module, we proceed in creating the View controller components.
We will create a bounded task flow and within it, we will create our index jspx.

Inside the Jspx we will drag and drop the Departments iterator and we will choose to select a single row from the Row Selection.


 and select the single selection


After creating the table, we will surround it with a panelCollection  component. This container will hold the toolbar of the CRUD buttons for this table. Additionally, both in the panelCollectin and table, we set the AFStretchWidth   in the styleClass. It is recomended by Oracle in order to have properl full width layout.

The we drop a toolbar in the panelCollections toolbar facet and then we drop the Department's operation from the DataControl.

We will add, createInsert, delete, commit and rollback. Commit and Rollback operations are for the whole datacontrol and not only for the Departments table.


Next, we have to create a popup. This popup will show the employees of the corresponding Department.
Inside the popup we will add a Dialog. Inside this Dialog we will drag and Drop the Employees iterator and have exactly the same process as we did with Departments.


Eventually, we will have a similar table with Departments.


Popup component by default caches the first data that will be shown. In our case, we do not want that since we want a refreshed view of the employees. This means that we want to execute Query for employees for every Department.
So we have to set lazyUncached the contentDelivery property.


NOTE: Since we are using toolbars and toolbar buttons we have to  set the appropriate partial triggers. Toolbar buttons by default have the partialSubmit  property to  true. This means that we have to set the appropriate partialTriggers  to the tables.
Each table will be partially triggered by it's toolbar buttons. So in Every table, in the partialTriggers sections we will add the correspoing toolbar button ids.


After setting the appropriate partialTriggers, the only thing left is, the edit button.

We right click on the table and select insert Column.
Then, we right click on the column and insert ADF faces button.
After that, we right click on the button and insert ADF showPopupBehavior.
In the showPopupBehavior we enter the popupId and the type of action:



And that is it.
When pressing Employees button, ADF will invoke additionally the selectionListener and make the departments current row. So every time we press the edit button, the current Department becomes current and the corresponding employees are fetched.

Download Sample Application.

Regards.

LinkWithin

Related Posts Plugin for WordPress, Blogger...