ads

X

Wednesday, October 8, 2014

ADF Contextual Events

Oracle provides us with a very powerful feature to implement view-to-region, region-to-view, and region-to-region communication without requiring the region or the reference bounded task-flow to be refresh or restarted.

In this example, i will be showing you on how you can achieve region-to-region communication using the HR schema. I will create two task-flows, each consisting of a single JSF page fragment. The first JSF page fragment (named PageA.jsff) includes the employeess ADF form with some navigation controls and a submit button and the second JSF page fragment (names PageB.jsff) includes the employees ADF table.

I have created a third JSF page, demo.jspx, which will include the above stated pages as regions. I will use ADF Contextual Events to refresh the employees ADF table once a change has been made in an employee using the employee ADF form in the first page.

I have created a new application (named "ADFContextualEvents") with the "Fusion Web Application (ADF)" application template and using the "Business Components from Tables" i have created a connection to the HR schema, creating the Employees entity, a default view for the Employeess entity (EmployeesView) and an Application Module which includes the EmployeesView.


I created two task-flows, TaskFlowA and TaskFlowB. Both task-flows include a single JSF page fragment (TaskFlowA includes PageA and TaskFlowB includes PageB). The first page includes the Employees ADF Form
while the second page includes the employees ADF table.
I then created a normal jspx page (called demo.jspx) which includes the two task-flows created above as an ADF region. If you run the page and try to do a change in one of the employees, you will see that the changes are not reflected in the table below.
To refresh the view and subsequently the table to show the changes made in the form above, I will use Contextual Events. So the first thing that I will do is to create a method in the Application Module that will refresh (by re-executing) the view.
public void refreshEmployees(){
getEmployeesView().executeQuery();
}
Please make sure that you expose this new method to the UI using the client interface option of the Application Module.
You need to add this method in PageB’s bindings as a method action using the page definition file.
Next, you need to define when the event should be triggered. This should be every time the user clicks the “Submit” button that is included in PageA (where the ADF Form is).
Finally, in the page that includes both task-flows as regions (demo.jspx), we need to define the subscriber for the event that will be triggered with the Submit button. To do so, go the page definition and select the “Contextual Events” and then the “Subscibers” tab and click on the green plus icon “Add a New Subscription”.
In the “Subscribe to Contextual Event” window, select the event that you have created, the publisher of the event and the handler (in our case, it is the method that we have created in the Application Module and included it in the second page’s page definition as a method action, and click OK.
If you run the demo page that includes both task-flows as regions, you will see that by doing a change in one of the employees using the employee form, the employees table displays the new changes without needing to refresh the region or page.
Download: ADF Contextual Events

Tuesday, May 20, 2014

ADF UI - Beginner: Creating data control for java bean

Sometimes, it is necessary to create java bean as a data control so that we can directly drag and drop bean methods into task flows, or add the bean properties as attributes in jsf pages. So, for those who is looking out how to generate a data control for a java bean, it's quite simple. Steps below:

For a simple java bean with the content below,


1. Right click the Java bean and select 'Create Data Control..'


2. Now, it generates an xml data control in the same package. That's it. Data control is generated for the bean.

3. If you expand 'Data Controls' pallette, you would be able to see the bean data control that you just created and you can drag and drop the data control properties and methods into your jsff pages or task flows.

Read more: Oracle ADF - Tips and Techniques: ADF UI - Beginner: Creating data control for java bean http://www.adftips.com/2010/11/adf-ui-beginner-creating-data-control.html#ixzz32F2EcaH9

Tuesday, May 13, 2014

ADF TaskFlow Transaction Basics

Transaction is a collection of works either committed or rollback.Create a calling and called task flow to go through some of the transaction basics of task flow

Calling Task flow :


Called Task flow : 
From the behavior section of the called task flow you can see the following options

  •  No Controller transaction is the default option means the called task flow does not participate any transaction management.
  • Always begin New Transaction - Transaction is created when enter to the task flow and completes the task flow when exists the task flow 
  • Always Use Existing transaction - Called task flow participates the existing transaction 
  • User Existing transaction if possible - Participate the existing transaction if available or start a new transaction if not available 
  • restore-save-option
Use restore-save-option =true if you want to discard the changes the end user makes with in a called bounded task flow when the called bounded task flow exits.This option apply only if the bounded task flow is entered by joining the existing transaction and a save point created on entry

No save point on task flow entry if selected prevent the creation of ADF model save point on task flow entry if taskflow participate in 'Always Use existing transaction ' or 'User existing transaction if Possible' . In this case overhead associated with a save point is not created for the transaction.
End the transaction from task flow return activity by selecting the End transaction property to commit or rollback.
Shared Data control behavior and transaction
Share data controls with calling task flow have the options Shared and Isolated
Transaction setting
Shared Data Control scope
Isolated Data Control scope
No controller txn
DataControlFrame shared without open txn
New DataControlFrame is created without an open transaction
Always begin new txn
Begin new if one is not open
Always begin new one
Always Use existing txn
Throws exception if txn is already open
Invalid.The checkbox cannot be deselected
Use Existing txn if possible
Begin a new txn if one is not already open
Always begin a new txn

Handling exceptions in the ADF taskflow

-         Through exception handling we can designate an Activity as exception handler
-          For the flow from the exception handling activity uses the standard exception handling activity
-          You can use router as exception handling activity and reaching the exception from here it will can route to various control flow cases based on exception.
-          A task flow can have only one exception handling activity
-          If no exception handling mechanism provided the exception propagated to the top level tf till the webcontainer
-          ADF Model also provide exception handling mechanism. An exception thrown by any type of binding is caught by the ADF Model which calls the reportException() stores the exception in the binding container

-          Later page renders error displays

Create a task flow below 

For the testMeth1 activity attch the method as 
#{pageFlowScope.handleException.exception}

View1.jspx

<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
  <af:panelGroupLayout id="pgl1">
    <af:button text="button 1" id="b1" action="toMeth"/>
  </af:panelGroupLayout>
</jsp:root>
testMeth1
#{pageFlowScope.handleException.exception}
The managed bean handleException
package view.test;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import oracle.jbo.JboException;
public class TestException {
    public TestException() {
        super();
    }
    public void exception() {
        throw new JboException("test here");
    }
    public void exceptionMessage() {
        System.out.println("Here");
        try {
            System.out.println("Inside Handeler");
            FacesMessage message = new FacesMessage("This is custom Message for Jbo Exception-Exception Handeler");
            message.setSeverity(FacesMessage.SEVERITY_WARN);
            FacesContext fc = FacesContext.getCurrentInstance();
            fc.addMessage(null, message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void badCall() {
          
       }
    public String badActionHere() {
System.out.println("Here...");
        return null;
    }
}

Create a page to test by drag and drop the page as region and run.Click on the button and you see the custom exception message.

Sunday, May 11, 2014

Parent to Region Communication using Shared & Isolated DataControls

In this post we will look at how Parent and Region communications are done in ADF. We will take two cases in this post. One is when by default Task Flows are set to have Shared Data Control scope and the other one is when Task Flows are set to use Isolated Data Control Scope.

Below is the picture which depicts what we are targeting to achieve.





We have a page which has two buttons. Next and Previous. These buttons are from DepartmentsVO which will move to the next and previous row of department table. Inside the page, there is a Employees Task Flow which is added as a Region.

The communication use case is , that when next and previous buttons on the page are clicked, the list of employees inside the EmployeesTaskFlow should change accordingly. Employees shown should be in a particular department which is being pointed by the buttons in iterator.

So lets get our hands on and start developing the use case.

Created a simple ADF Project with Model and ViewController. Created ADF BC out of HR schema for Employees and Departments table.

We have two use cases. First one is for Shared Data Control and Second one is for Isolated Data Control :

TaskFlow with Shared Data Control

Created a task flow parent-region-case1 having one View default activity.
In the jsff, created a ADF Table using EmployeesVo which is has a master Vo as DepartmentsVO.
Now created one jspx - ParentPageCase1.jspx where added Next and Previous operations of DepartmentsVO which is master of EmployeesVO which we dragged in the Jsff.
We also dragged the task flow in ParentPageCase1.jspx as a region.
Run the jspx and you will see that when one scrolls to next department , region is refreshed to show employees present in that department.
Now lets do one thing. Lets change the data control scope of Task Flow to Isolated.
Now if we run the page and click on the next button, the region will not refresh and will not show the employees for the department we clicked next for. 
For this case we need to have another approach which is described next.
TaskFlow with Shared Data Control

Since we saw that using above implementation, task flow with Isolated Data Control won't work, we need to have different approach. 
For this create another view object EmployeesVOForIsolatedDC out of EmployeeVO having a view criteria for DepartmentId.
Add EmployeesVOForIsolatedDC in the AM Data Model and add view criteria to it.
Created a new task flow parent-region-isolateddc having first activity as executeWithParams having parameters as #{pageFlowScope.deptId} for deptId.
It has two view activities. One is regionToParentIsolatedDC.jsff which just shows the AF Table out of EmployeesVOForIsolatedDC VO.
The other activity is just a next jsff which previous fragment can navigate to. It just has an output text.
If we see this task flow accepts parameter which is nothing but department id.
Lastly lets create as jspx ParentToRegionIsolated.jspx and drag this task flow and provide the input parameter value.
ParentToRegionIsolated binding looks like below. Created attribute value for DepartmentId for using it.
Now lets run the page.
You will see we were able to navigate to next departments and employees in the region were refreshed to that department.
There is one more button next at bottom which takes you to next View Activity which has just output text.
Now on the next fragement and on click of Next button in the parent page, again first page is shown. Important :- This is because, Whenever anything in parent page is changed , it will Re Instantiate the task flow and will refresh the region.
This means if user is in middle of any transaction and parent page navigation is pressed, all of its data will be lost and user will be greeted with the default activity in the task flow.
 When clicked on Next (Which is on parent page) below is the first screen of task flow.
If we want that task flow should not be restarted /  Re Instantiate , there are different approaches which should be followed.

Future posts will be on how to achieve this.

Thursday, May 8, 2014

ADF Basics : Selecting and showing time-stamp in ADF Faces using af:inputDate & af:convertDateTime

how to show & select time with date in ADF Faces ?
We use af:inputDate to show and select Date & Timestamp type of attributes, by default it looks like this



ADF provides a default converter (af:convertDateTime) to format date & timestamp field, we can define a pattern to change it's format & to show time selector in calendar box
Suppose pattern is- dd-MMM-yyy HH:mm:ss , now see there is a hour/minute/second selector appears in calendar box



you can change this pattern as per your format , suppose you want to show AM or PM after time just use dd-MMM-yyy HH:mm:ss a



see xml source of af:inputDate-


<af:inputDate label="Label 1" id="id1" contentStyle="width:250px;padding:5px;">
                        <af:convertDateTime pattern="dd-MMM-yyy HH:mm:ss a"/>
                    </af:inputDate>

Tuesday, May 6, 2014

Pre-populate selected values in viewObject based shuttle component (multiple selection)- Oracle ADF

while using shuttle component sometimes we need to show some values on selected side of af:selectManyShuttle , so to do this normally we use a custom shuttle component that is populated from managed bean code
but when i have all data in a viewObject so why should i iterate viewObject to get all data in managed bean and then set some values in an arrayList to populate selected shuttle values.
it is time consuming and requires lot of coding, so for viewObject based shuttle we can do it in efficient way.


  • In this example I'm using Departments table of HR schema to populate af:selectManyShuttle, i think you all know how to create a shuttle in ADF
  • so next is to populate selected shuttle values on some event, created a fusion web application using Departments table

  • it's time to drop Departments ViewObject on page as shuttle component

  • <af:selectManyShuttle value="#{bindings.Departments1.inputValue}" label="#{bindings.Departments1.label}"
                                          id="sms1" size="15" binding="#{pageFlowScope.ShuttleSelectBean.shuttleBind}"
                                          partialTriggers="b1">
                        <f:selectItems value="#{bindings.Departments1.items}" id="si1"/>
                        <f:validator binding="#{bindings.Departments1.validator}"/>
                    </af:selectManyShuttle>
    

  • So suppose on a button click i want to set selected values in shuttle, so i have created a actionEvent for button in managed bean and binding of af:selectManyShuttle, so basic structure of page is like this


  • see the code of actionEvent , create an arrayList and add all values in it that you want to set as selected values and then just set the value in shuttle using binding

  •     /**Method to set selected values in af:selectManyShuttle
         * @param actionEvent
         */
        public void selectValuesShuttle(ActionEvent actionEvent) {
            DCIteratorBinding iter = (DCIteratorBinding) getBindingsCont().get("Departments1Iterator");
            ViewObject vo = iter.getViewObject();
            RowSetIterator rsi = vo.createRowSetIterator(null);
            ArrayList listVal = new ArrayList(20);
    
            while (rsi.hasNext()) {
                Row nextRow = rsi.next();
                if (nextRow.getAttribute("DepartmentId") != null) {
                    listVal.add(nextRow.getAttribute("DepartmentId"));
                }
            }
            shuttleBind.resetValue();// Reset Shuttle Component
            System.out.println("Setting values -" + listVal);
            shuttleBind.setValue(listVal.toArray()); // Setting selected values 
            AdfFacesContext.getCurrentInstance().addPartialTarget(shuttleBind);
        }
    

  • now run this page and test your shuttle component



  • Cheers- Happy Coding

  • But this method works only when you have to set values on some action or other event after page load, because before page load , binding of shuttle component will not be accessible
  • so if you have a requirement of setting selected values on page load then you must use a list defined in managed bean and bind it to  value property of shuttle component, value property denotes selected values of shuttle 


  • and just write same code on getter of List, in this case selected values in shuttle are populated on page load

  •     List pageLoad = new ArrayList(20);
        public void setPageLoad(List pageLoad) {
            this.pageLoad = pageLoad;
        }
    
        public List getPageLoad() {
            DCIteratorBinding iter = (DCIteratorBinding) getBindingsCont().get("Departments1Iterator");
            ViewObject vo = iter.getViewObject();
            RowSetIterator rsi = vo.createRowSetIterator(null);
            while (rsi.hasNext()) {
                Row nextRow = rsi.next();
                if (nextRow.getAttribute("DepartmentId") != null) {
                    pageLoad.add(nextRow.getAttribute("DepartmentId"));
                }
            }
            return pageLoad;
        }
    

    Cheers- Use both method as per your requirement :-) Download Sample App

Friday, May 2, 2014

Open pdf file in New window or in Popup using InlineFrame



This is a draft version of ADF sample application for opening PDF file in New Window or Inline Frame.
You can download the code from here / here

Birds eye view of the app:


To Show the contents of the file, we are registering a servlet(ShowPdfServlet)  in web.xml which takes care of reading and displaying .
On the same lines, we can tweak the code to read from data base or any other place.

Application assumes, the existence of file "c:\\webcenter.pdf". Hence before you run the application make sure you place a pdf with above name. (PdfServlet.java : 44 hard coded value says the same)

To open the file in new window, I have followed ADF Code Corner Example (33).


The task flow enabled for url-invoke allowed and it should be bounded taskflow "with pages". More info @ ADF Code Corner Example.

Sample output when opens in popup.





Soon will come out with detailed post.

Tuesday, April 29, 2014

BarCode Reader - SBA | Oracle ADF

Integration of BarCode Readers with Oracle ADF Applications Specially our Charity SBA Package (Smart Business Applications) and how to make Oracle ADF Easy & Flexible for one purpose which is "Enable End user from Controlling & Coding Stock Element Fast" !
Demo Link here !




BarCode From Basic Definition is just Fast Keyboard to read Unique keys, and it is common used in Operational Systems like Point of Sale & Inventory Applications !.

for this reason, i will show complete solution from our SBA Charity Package just to use barcode to scan & Define Element Description before using in Stock Level.

Solution is a complete Back Bean Methods, Art of Controlling of Interface in ADF is the best way to cover, Control the Barcode Solution into your Application, so before going to implement, you have to understand well below Back Bean Scripts.
 Result 

 

Source Code

 



References