Tuesday, October 4, 2016

ADF: Format negative currency with brackets

Displaying UI attribute which holds both positive ,negative currency and displaying negative currency with brackets ex:($123.00 ) instead of -$123.00 .

Solution:
In convertNumber tag change pattern to "#,##0.00;(#,##0.00)" 

Here semi-colon(;) is separating the value of the format which is secondary format for negative currency.

Tuesday, September 20, 2016

ADF : Export to Excel Programmatically using fileDownloadActionListener tag

Another way exporting table results into excel is by using fileDownloadActionListener on button action 

Drop fileDownloadActionListener  tag on button , set content type to application/vnd.ms-excel and bind it to bean method.




In Bean code get desired rows append attribute value with '\t' for next cell and '\n' next line for next row in excel

private static final String LINEBREAK = "\n";
private static final String NEXTCELL = "\t";

public void exportToExcel(FacesContext facesContext, OutputStream outputStream) throws IOException {
    DCBindingContainer dc = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
    DCIteratorBinding binding = dc.findIteratorBinding("EmployeesVO1Iterator");
    ViewObject vo = binding.getViewObject();
    StringBuilder sb = new StringBuilder();
    sb.append("First Name").append(NEXTCELL).append("last Name").append(NEXTCELL).append("Email").append(LINEBREAK);
    vo.setCurrentRow(vo.first());
    Row current = vo.getCurrentRow();
    while (current != null) {
        String firstName = (String)current.getAttribute("FirstName");
        String lastName = (String)current.getAttribute("LastName");
        String email = (String)current.getAttribute("Email");
        sb.append(firstName).append(NEXTCELL).append(lastName).append(NEXTCELL).append(email).append(NEXTCELL).append(LINEBREAK);
        current = vo.next();
    }
    outputStream.write(sb.toString().getBytes());
    outputStream.flush();
}

Output
Employees table will show only 3 rows

Click on export results button will export data into excel ,below is result




Happy Learning !!

Wednesday, September 14, 2016

Setting table current row using custom selection listener

For implementing custom selection listener on table, update default selection listener by creating SelectionEvent bean reference 

New custom table selection listener will be 

selectionListener="#{pageFlowScope.SampleBean.customSelectionListener}"

Snippet code to set current row on row selection , for this sample First name is printed on row selection 

public void customSelectionListener(SelectionEvent selectionEvent) {
    RichTable _table = (RichTable)selectionEvent.getSource();
    CollectionModel model = (CollectionModel)_table.getValue();
    JUCtrlHierBinding _binding = (JUCtrlHierBinding)model.getWrappedData();
    DCIteratorBinding iteratorBinding = _binding.getDCIteratorBinding();
    Object _selectedRowData = _table.getSelectedRowData();
    JUCtrlHierNodeBinding node = (JUCtrlHierNodeBinding)_selectedRowData;
    Key rwKey = node.getRowKey();
    iteratorBinding.setCurrentRowWithKey(rwKey.toStringFormat(true));

    DCBindingContainer bindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
    DCIteratorBinding itorBinding = bindings.findIteratorBinding("EmployeesVO1Iterator");
    System.out.println(itorBinding.getCurrentRow().getAttribute("FirstName"));
}

Output





Getting current date and time stamp in oracle.jbo.domain.Date format

To get the current system date and time stamp use below snippet code

import oracle.jbo.domain.Date;

public Date getCurrentDomainDate(){
    return new Date(new java.sql.Timestamp(System.currentTimeMillis()));
}

Output format

“2016-09-14 14:47:31.0”.




Tuesday, September 13, 2016

Passing Parameters from Manage bean to JavaScript in af:resource tag

There are certain scenario where on button click you execute some logic and send parameter to JavaScript to perform some operation. If you ran into similar kind of scenario ,below is one of the way to implemented.

For this sample on button click JavaScript Function is invoked sending parameter to open a URL('www.google.com') in this case

//Execute some logic above
FacesContext facesContext = FacesContext.getCurrentInstance();
ExtendedRenderKitService service =
org.apache.myfaces.trinidad.util.Service.getRenderKitService(facesContext, ExtendedRenderKitService.class);

service.addScript(facesContext, "launchURL('" + "https://www.google.com/" + "');");

On the page resource tag is added and a function which accepts a parameter inside function window.open()  is called with the pararmeter send from bean




Happy Coding !!!

Programmatically invoking URL/TaskFlow in new window tab using JavaScript from bean

One way of invoking JavaScript call from bean and invoking a URL / TaskFlow in new window Tab

Following snippet is way to invoke JavaScript from bean, which accepts url as an input parameter


 StringBuffer sb = new StringBuffer();
 sb.append("var winPop = false;");
 sb.append("if(winPop && !winPop.closed){  ");
 sb.append(" winPop.focus();  }");
 sb.append("else{   ");
 sb.append("winPop = window.open(\"" + url + "\", \"winPop\"); } ");
 ExtendedRenderKitService erks =
            Service.getRenderKitService(FacesContext.getCurrentInstance(), ExtendedRenderKitService.class);
 StringBuilder script = new StringBuilder();
 script.append(sb.toString());
 erks.addScript(FacesContext.getCurrentInstance(), script.toString());

As per this Sample ,on button click TaskFlow/URL will be launched in new window tab.

For invoking TaskFlow as URL following property need to be set on TaskFlow


Bean snippet to invoke TaskFlow programmatically using JavaScript on button click


Output

Button on page


Click on button ,TaskFlow opens in new window tab


Saturday, September 10, 2016

Set current row programmatically for af:table programmatically from managead bean using POJO

Set POJO table current row 

One of the ways to set current row is 

//Table binding
private RichTable tableBinding;


 RowKeySet rowKeySet = tableBinding.getSelectedRowKeys();

 rowKeySet.clear();
 //Add row index in rowKeySet.add();
 //rowKeySet.add();
 SelectionEvent selectEvent = new SelectionEvent(tableBinding.getSelectedRowKeys(), rowKeySet, tableBinding);
selectEvent.queue();

A  POJO based table is created and setting the current row when we add a item.

1.Person Object is created with first name , last name and middle initials



2. Create a managed bean for af:table, this managed bean uses Person Object to add data to table ,A List with person is used to add data. I have declared first name, last name and middle initials to bind to input value .


3.Drag and drop af:table from component palette ,keep necessary columns and in Value attribute of table bind with List<Person> and change column output text values .



4. Add a button , bind input text values with bean first name, last name and middle initials references . Add action listener for button in bean.


5. In action listener we will add the values from first name, last name and middle initials to personList and set current programmatically. 


Run the application 






As current row is set for the last added person added , that person detail row is highlighted here 




Happy Coding !!!



Wednesday, September 7, 2016

ADF : Export only some columns to excel by exportCollectionActionListener using setPropertyListener tag

Exporting only some columns in excel by exportCollectionActionListener

In some use cases you might want export only some columns to excel , for these find of use cases you can use setPropertyListener tag


update column visible proper



Text wrap for ADF Input text

Wrapping word when long text is entered in inputText tag

I have a inputText tag as below




When some long text is entered horizontal scroll bar appears.



If you want to achieve word wrap and avoid horizontal scroll bar on a input text with long text, you can add inline style tag to input like below text .

inlineStyle="white-space: pre-wrap; word-wrap:break-word; display:inline-block;"




Tuesday, September 6, 2016

Invoking Application module method as default activity with return parameter from bean

Sometimes when task flow is initialized before loading page/fragment we need to execute Application Module method which returns parameter to manipulate some logic. 

Shown below is one way to achieve this kind of use case .

  1. Have a method in AMImpl which returns parameter , here Map is returned .
  2. Drag and drop the AM method on task flow , which creates binding in DataBinding.cpx


DataBinding.cpx will have a page map and page definition usages

<page path="/Sample-TF.xml#Sample-TF@employeeAMMethod"                         usageId="view_Sample_TF_Sample_TF_employeeAMMethodPageDef"/>

<page id="view_Sample_TF_Sample_TF_employeeAMMethodPageDef"

   path="view.pageDefs.Sample_TF_Sample_TF_employeeAMMethodPageDef"/>

Now implement a bean method activity on task flow , below i have execute AMImpl method ,result is returned and setting to bean variable which i will be showing as output text in fragment.


            //Get the current binding context
        BindingContext binding = BindingContext.getCurrent();

        //Find our binding container by name (page id in the DataBindings.cpx)
        DCBindingContainer dcBinding =
            binding.findBindingContainer("view_Sample_TF_Sample_TF_employeeAMMethodPageDef");
        //Execute the method
        OperationBinding operation = dcBinding.getOperationBinding("employeeAMMethod");
        operation.execute();





Output on fragment 



Happy Learning !!!

Friday, September 2, 2016

Creating Document Template Sample using Docx4j and OpenDoPE in ADF Application

Sample Document Template generation using Docx4j

Docx4j is an open source (ASLv2) Java library for creating and manipulating Microsoft Open XML (Word docx, Powerpoint pptx, and Excel xlsx) files. 
Download Docx4j and dependices here Jar's and add them in Libraries and Classpath



Download OpenDoPE Microsoft word extension and run extension.You should OpenDoPE extension on Microsoft as below



Save the Template you want to create first . Click on 'Bind this text' for the text you wanted to generate dynamically.


Click Bind this.. on the extension panel 


Then it should open a XML text editor, paste the XML .which we will be generate using JAXBMarshalling



Select the XML element to Bind with , enter a unique XPath ID and Click Use this XPath



Repeat same for other elements also and template should look like below

Drag and drop EmployeeVO as a form , create a button , Action Listener for that button and change text to 'Create Template' .

Below is code snippet for ActionListener , which gets current row from EmployeesVO and set's Person Object with First Name, Last Name, Email and Phone. Using JAXBMarshalling current row is converted into XML String .



Below snippet code is for binding template with XML String


Finally,After generating Word document will replace the text with dynamic data.




Happy Learning!!!

Creating an Object to XML and XML to Object to using JAXB marshalling

JAXB stands for Java Architecture for XML Binding, using JAXB annotation to convert Java object to / from XML file

Create a Person Object for this object to convert to / from XML , we should annotate with JAXB annotation .Root element/Class with @XmlRootElement and @XmlElement for variables.


Using below snippet code we can create a file from Object to XML ,using JAXBMarshaller

        Person person = new Person();
        person.setFirstName("Steven");
        person.setLastName("Kinggfdgdf);
        person.setPhone("515.123.4567);
        person.setEmail("SKING);

        try {
            File file = new File("C:\\file.xml");
            JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

            // output pretty printed
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            jaxbMarshaller.marshal(person, file);
        } catch (PropertyException pe) {
            pe.printStackTrace();
        } catch (JAXBException jaxbe) {
            jaxbe.printStackTrace();
        }

We can also create a String from Object to XML , here we will use java.io.StringWriter 

        Person person = new Person();
        person.setFirstName("Steven");
        person.setLastName("Kinggfdgdf);
        person.setPhone("515.123.4567);
        person.setEmail("SKING);

        try {
            StringWriter sw = new StringWriter();
            JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

            // output pretty printed
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            jaxbMarshaller.marshal(person, sw);
            System.out.println(sw.toString());
        } catch (PropertyException pe) {
            pe.printStackTrace();
        } catch (JAXBException jaxbe) {
            jaxbe.printStackTrace();
        }

Output




Below snippet code is to create a Object from XML using JAXBUnmarshaller

            File file = new File("C:\\file.xml");
            JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);

            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            Person person = (Person)jaxbUnmarshaller.unmarshal(file);
            System.out.println(person);

Output

Person [email=SKING, firstName=Steven, lastName=Kinggfdgdf, phone = 515.123.4567]


JDeveloper: 11.1.2.4 - Unable to Print all pages in IE11 , prints only first page instead the all pages.

We came across a use case where we had to print content in JSF page and in IE it was printing only first page but works as expected in FireFox.

Below work around had fixed our issue:

If possible, upgrade to the latest  version of ADF. For IE 9 support, use the latest version of 11.1.1.x or 11.1.2.x, as appropriate. For IE 10,11 support, an upgrade to 12.1.2 or later is required.

If this is not possible, a potential workaround is to add one pixel of vertical space to the top of the JSF/JSPX page containing the table. For example:
<af:document title="test.jspx" id="d1" inlineStyle="padding:1px 0px 0px 0px;">

In most cases this spacing is hardly visible, and it appears to solve the problem for IE versions up to and including 10&11

Alternatively Issue can be addressed by setting the following CSS selector

@agent ie and (version: 9.0) and (version: 10.0)and and (version: 11.0) {
  af|document:printable {
  padding-top: 1px;
  }
 }

@agent ie and (version: 9.0) and (version: 10.0) and (version: 11.0){
  af|document:maximized:printable {
  padding-top: 1px;
}
}

JDev :11.1.2.4 - "Page can't be displayed" when using TaskFlow as Run as Dialog Popup


In couple use cases we had to use TaskFlow behavior as 'Run as Dialog' and we used to get "Page can't be displayed" first time when we try to access TaskFlow .It works fine after that .


Adding Below context-param in web.xml has fixed our issue.

    <context-param>
        <param-name>oracle.adf.view.rich.prettyUrl.OPTIONS</param-name>
        <param-value>off</param-value>
    </context-param>

Thursday, September 1, 2016

Allowing numeric characters only in Input text using JavaScript


We can always restrict user from entering non numeric / special characters in  input field by using JavaScript

For that to work you have to add the af:clientListener tag to your Input text component – af:inputText – to call out to JavaScript when users type in the input field

Input text code looks as shown below


<af:inputText label="Numbers:" id="it1">

            <af:clientListener method="processKeyDown" type="keyDown"/>
            <af:clientListener method="processKeyUp" type="keyUp"/>
   </af:inputText>

The JavaScript code that you use in af:resource tag to filter character inputs or numeric inputs is shown below


            var shiftDown = false;
             var ctrlDown = false;
             function processKeyUp (evt) {
                var key = evt.getKeyCode();
                if (key == 16) {
                  shiftDown = false;
                }
              }
             function processKeyDown (evt) {
                var key = evt.getKeyCode();
                if(key == 17){
                    ctrlDown = true;
                }
                if (key == 16) {
                  shiftDown = true;
                }
                //Allow: ctrl+c and ctrl+v
                if ((ctrlDown == true &amp;&amp; key == 86) || (ctrlDown == true &amp;&amp; key == 67)) {
                    // let it happen, don't do anything
                    ctrlDown = false;
                    return;
                }
                // Allow: backspace, delete, tab, escape, enter and .
                if (key == 8 || key == 9 || key == 27 || key == 13 ||
                // Allow: home, end, left, right
                (key >= 35 &amp;&amp; key &lt; 41)){
                  // let it happen, don't do anything
                  return;
                } else {
                  // If non numeric or shift is pressed then stop the keypress
                  if (shiftDown || (key &lt; 48 || key > 57) &amp;&amp; (key &lt; 96 || key > 105)) {
                      evt.cancel();
                  }
                }

              }

You can always find out JavaScript event keycode using http://keycode.info/ and press any key to get its keycode.


ADF : ApplicationModuleImpl to use its own version of Custom TransactionFactory

We could force each application using its own version of Custom TransactionFactory by adding code to each ApplicationModuleImpl.


In Application 1, that should use CustomDatabaseTransactionFactory1, f.ex.:

    ...

    static

    {
       oracle.jbo.server.DatabaseTransactionFactory.setFactory(new CustomDatabaseTransactionFactory1());

    }

In Application 2, that should use CustomDatabaseTransactionFactory2, f.ex.:

    ...

    static

    {
       oracle.jbo.server.DatabaseTransactionFactory.setFactory(new CustomDatabaseTransactionFactory2());

    }