Tuesday, February 9, 2010

ADF Faces RC: A simple but robust implementation of a conditional confirmation dialog/ pop-up

Sometimes you may need to display a confirmation dialog in response to a user action. You can easily launched a pop-up by adding a popup and a showPopupBehavior component inside your commandButton, commandToolbarButton, and etc. like below:
<af:commandToolbarButton text="Post" id="ctb4">
  <af:showPopupBehavior popupId="confirmPostingPopup"
                           triggerType="action"/>
</af:commandToolbarButton>

But in case your requirement is to conditionally display a pop-up dialog based on some premise, then you need to programmatically launch your pop-up from your backing bean. The following method could make this daunting task a breeze:
protected void showDialog(RichPopup popup){
      FacesContext context = FacesContext.getCurrentInstance();
      StringBuilder script = new StringBuilder();
      script
        .append("var popup = AdfPage.PAGE.findComponent('")
        .append(popup.getClientId(context))
        .append("'); ")
        .append("if (!popup.isPopupVisible()) { ")
        .append("var hints = {}; ") 
        .append("popup.show(hints);}");
      ExtendedRenderKitService erks = 
          Service.getService(context.getRenderKit(), ExtendedRenderKitService.class);
        erks.addScript(context, script.toString());
    }   
Below is a sample popup declared on one of my page.
<af:popup id="confirmPostingPopup" clientComponent="true" contentDelivery="lazy"
            binding="#{backingBeanScope.acctgEntryEditForm.confirmPostingPopup}">
    <af:dialog title="Confirm Posting" type="yesNo" id="pt_d2"
               dialogListener="#{backingBeanScope.acctgEntryEditForm.handleConfirmPostingDialog}">
      <af:panelGroupLayout id="pgl0" layout="vertical">
        <af:outputText value="Posted entries can no longer be edited."
                       id="pt_ot4"/>
        <af:outputText value="Are you sure to post this entry? " id="pt_ot3"/>
      </af:panelGroupLayout>
    </af:dialog>
  </af:popup>
The button that could potentially launched that popup...
<af:commandToolbarButton text="Post" id="ctb4" actionListener="#{backingBeanScope.acctgEntryEditForm.postEntry}"/>
You need to take note of three points on the above codes:
1) The popup has a "binding" attribute to bound it to your backing bean so that you could pass it later as parameter to your showDialog()method.
2) The enclosing dialog inside the popup has a declared "dialogListener" attribute. The listener here will take charge on what to do based on the user response(Yes or No).
3) The commandToolbarButton has no declared showPopupBehavior tag but an actionListener. Inside the actionListener method is the decision to call the showDialog() method.
Please see illustrative codes below:
public class AcctgEntryEditForm{
    private RichPopup confirmPostingPopup;
    //getter and setter
    public void setConfirmPostingPopup(RichPopup confirmPostingPopup){
        this.confirmPostingPopup = confirmPostingPopup;
    }

    public RichPopup getConfirmPostingPopup() {
        return confirmPostingPopup;
    }
    //actionListener
    public void postEntry(ActionEvent event) {
        // some codes
        if (true) {//subtitute true with your own criteria
            showDialog(confirmPostingPopup);
        }
    }
    //dialogListener
    public void handleConfirmPostingDialog(DialogEvent ev){
      if (ev.getOutcome().equals(DialogEvent.Outcome.yes)){
         //the user confirms, do your stuff here...
         System.out.println("The user confirmed");
      }
    }
    
    protected void showDialog(RichPopup popup){
      FacesContext context = FacesContext.getCurrentInstance();
      StringBuilder script = new StringBuilder();
      script
        .append("var popup = AdfPage.PAGE.findComponent('")
        .append(popup.getClientId(context))
        .append("'); ")
        .append("if (!popup.isPopupVisible()) { ")
        .append("var hints = {}; ") 
        .append("popup.show(hints);}");
      ExtendedRenderKitService erks = 
          Service.getService(context.getRenderKit(), ExtendedRenderKitService.class);
        erks.addScript(context, script.toString());
    }
}

Cheers!

No comments:

Post a Comment