Tuesday, June 9, 2015

Clicking a button on Page Load

Assume you have the following scenario:

On Page1.jspx, you have a task flow dropped as a region. Within that task flow, you have just one fragment, that contains a GoLink component that points to Page2.jspx. What we need to do is as soon as Page1.jspx is loaded, we need to redirect to Page2.jspx by programatically creating the link click (or action) event. We can pass some parameters as well during this call.
If you are using 11gR2 and up, then you can use the following tutorial for this requirement:

https://blogs.oracle.com/jdevotnharvest/entry/jdeveloper_11g_r2_and_12c

But if you are using JDeveloper version before 11gR2, then you have to manually take care as suggested below. Here is how GoLinkView.jsff looks like:

<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:af="http://xmlns.oracle.com/adf/faces/rich"
          xmlns:f="http://java.sun.com/jsf/core">
  <af:panelGroupLayout id="pgl1" layout="vertical">
    <af:commandLink text="Second Link" id="linkToHome" actionListener="#{GoLinkViewBean.navigateLink}" clientComponent="true"
                    partialSubmit="true" visible="false"/>
  </af:panelGroupLayout>
</jsp:root>

And the GoLinkViewBean looks like:

package view.bean;

import java.io.IOException;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

public class GoLinkViewBean {
    public GoLinkViewBean() {
    }

    public void navigateLink(ActionEvent actionEvent) {
        // Add event code here...
        String destination = "http://127.0.0.1:7001 /GoLinkRedirectApp-ViewController-context-root/faces/Page2.jspx";
             try {
                 FacesContext.getCurrentInstance().getExternalContext().redirect(destination);
             } catch (IOException e) {
                 e.printStackTrace();
             }
    }
}

To initiate the navigateLink action event on page load, I have used javascript solution. The key is to add a clientListener on the document tag of Page1.jspx as shown below:

<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
    <jsp:directive.page contentType="text/html;charset=UTF-8"/>
    <f:view>
        <af:document title="Page1.jspx" id="d1">
            <af:clientListener type="load" method="onPageLoad"/>
            <af:resource type="javascript">
                function onPageLoad(){
                        var button = AdfPage.PAGE.findComponentByAbsoluteId("r1:0:linkToHome");
                        AdfActionEvent.queue(button,true);
                }
            </af:resource>         
            <af:form id="f1">
                <af:region value="#{bindings.RedirectTaskFlow2.regionModel}" id="r1"/>
            </af:form>
        </af:document>
    </f:view>
</jsp:root>

So as soon as the Page1.jspx is called, after the page is loaded, the javascript takes control, find the goLink component in the nested region and adds the action even in the even queue. Once that is done, the action event is trigged on the component to redirect the request to Page2.jspx. Please not that if you remove the clientListener tag, the javascript will fail as it will run even before the page is loaded and will not be able to find the component. 

Thats all.