Thursday, September 20, 2012

Handling fileDownloadActionListener in ADF

If you got to work with Download Action Listener in ADF, you will find an issue that, the listener will prompt you to download file even though file is not available. To handle this bug in ADF, we can use Java Script in our JSF page or managed bean. It's little bit tricky, but easy to do it.

Create two buttons in JSF page, one to search file & another one(visible=false) to handle download file:

<af:commandButton text="SearchFile"
                            id="cl1"
                            actionListener="#pageFlowScope.managedBean.searchFile}"                              
                            partialSubmit="true"
                           clientComponent="true"/>
                              
<af:commandButton text="Downloadfile"
                                  id="cb1"
                                  visible="false"
                                  partialTriggers="cl1"
                                  partialSubmit="false"
                                  binding="#{pageFlowScope.managedBean.fileDLButton}"
                                  clientComponent="true">
        <af:fileDownloadActionListener
                     filename="SampleFileName.pdf"
                     contentType="application/pdf; charset=utf-8"
                     method="#{pageFlowScope.managedBean.downloadFile}"/>      
 </af:commandButton>  


Bind button in JSF using accessor method in managed bean:

    public void setfileDLButton(RichCommandButton fileDLButton) {
        this.fileDLButton= fileDLButton;
    }

    public RichCommandButton getfileDLButton() {
        return fileDLButton;
    }

Create two methods in Managed bean to Search & Download file, and in the Search file method use Java Script to trigger second button defined in JSF:

public void searchFile() {
          ............................................................................
     FacesContext fctx = FacesContext.getCurrentInstance();

     String buttonId = getfileDLButton().getClientId(fctx); 

     StringBuilder script = new StringBuilder();

     script.append("var dlButton = AdfPage.PAGE.findComponentByAbsoluteId('" + buttonId + "');");
     script.append("dlEvent = new AdfActionEvent(dlButton);");
     script.append("dlButton.queueEvent(dlEvent, true);");
     ExtendedRenderKitService erks = Service.getService(fctx.getRenderKit(), ExtendedRenderKitService.class);
     erks.addScript(fctx,script.toString());
 }

public void downloadFile(FacesContext context,OutputStream outputStream) {
            ..............................................................................
}


6 comments:

  1. Thanks for the post..It helped me solve my issue..

    ReplyDelete
  2. Is there a way to stop file from getting published programmatically from backend?

    ReplyDelete
  3. Great solution...thanks for your help.

    ReplyDelete
  4. I have a scenario :
    On a button click, download a file and reset UI component (checkbox).
    In action listener, I reset the check box and also have fileDownloadActionListener on the button.
    Either of them is possible but not both.
    Any ideas?

    Thanks
    Vishnu

    ReplyDelete
  5. this solution is not working properly in two pager application.
    i have a two page Paga A and Page 2. The flow is page A contains master date and page B have edit details for per row .Example first page contains all employees as a table. In Page B . particular Employe edit details.
    So when i used this solution in Page A its working fine, but when i am using this solution in Page B. its not working , when i refreshed the page then its working.
    I analysed this case and found that first time all id's of second page starts r1:1:button1 but after refreshing the page id's becomes change like r1:0:button1. so when i am calling the the javascript from managed bean its not getting proper id . so download action listener is not calling .
    please help to resolve this issue.

    ReplyDelete

Provide your thoughts !