Saturday, 21 December 2013

call af:fileDownloadActionListener from managed bean

There is one scenario where af:fileDownloadActionListener has to be called from managed bean.
Scenario: If user wants to download file however requested file does not exist. So there should be a alert that "file does not exist".
If you use af:fileDownloadActionListener directly then if there is no file to be downloaded then it will  be give error message because of the default behaviour of the af:fileDownloadActionListener component. So ,if there is no file to download in that case the fileDownloadListener method should be skipped.
To resolve this issue one commandButton and one CommandLink can be used.

#CommandLink is visible and it will just call the backing bean method where the logic is to check whether file exist or not.
#CommandButton will do actual task and button have fileDownloadListener method and this button's property visible = false.

Below is the sample code:

#download.jsff Code
 <af:commandButton text="HiddenBtn" id="HiddenBtn" clientComponent="true" visible="false"
                                binding="#{pageFlowScope.OpusDownloadBean.downloadButton}">
        <af:fileDownloadActionListener method="#{pageFlowScope.OpusDownloadBean.doDownload}"
                                                         contentType="application/pdf" filename="#{row.UploadName}"/>
 </af:commandButton>
 <af:commandLink text="Download" id="dwnloadBtn"
                    actionListener="#{pageFlowScope.OpusDownloadBean.prepareForDownloadAction}"
                    clientComponent="true">
        <f:param id="p1" name="uid" value="#{row.UploadId}"/>
 </af:commandLink>

JavaScript to be included in the jsff page:

<af:resource type="javascript">
      function customHandler(event) {
          var exportCmd = AdfPage.PAGE.findComponent(event);
          var actionEvent = new AdfActionEvent(exportCmd);
          actionEvent.forceFullSubmit();
          actionEvent.noResponseExpected();
          actionEvent.queue();
      }
    </af:resource>

Managed bean Method
public void prepareForDownloadAction(ActionEvent ae) {  
        //Logic to find that whether the file exists for uid in commandLink (<af:param/>).
        if (logic) {
            //Code to check whether the file is available
 
            RichPopup.PopupHints hints = new RichPopup.PopupHints();
            this.popup_File_Name.show(hints); // show message "requested file does not exist"
        } else {
            ADFContext ctxt = ADFContext.getCurrent();
            SecurityContext sctext = ctxt.getSecurityContext();
            ExtendedRenderKitService erks = Service.getService(context.getRenderKit(),                              
                                                                                                 ExtendedRenderKitService.class);
            FacesContext.getCurrentInstance();
            String id = downloadButton.getClientId(FacesContext.getCurrentInstance());
            System.out.println("id >>" + id);
            erks.addScript(context, "customHandler('" + id + "');");
        }
    }
}

In above method in else part the doDownload (fileDownloadListener) method is being called through java script, if that file exists.

3 comments:

  1. 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
  2. I was away and saw your comments now. I hope you might have found the solution. If you still have the issue. I can help you out.

    ReplyDelete
  3. As far as I remember, I had implemented this solution on same page.

    ReplyDelete