Sunday, October 31, 2010

ADF UI - How the default focus is set to popup dialog buttons?

When we use popup dialogs, we want to set default focus on one of the dialog's buttons as we want to navigate or execute some logic on pressing 'Enter' without loosing focus. But many of us not aware how to do that (at least I until sometime back). First, if you set 'type' (e.g., yesNo, okCancel, ok, cancel, yesNoCancel, etc.)of the af:dialog to specify the buttons you want to display, then you're safe. Because ADF framework will automatically set default focus to either 'OK' or 'Yes' button for yesNo, okCancel, ok, yesNoCancel types and to 'Cancel' button if the type is 'cancel'.

But, if you added your own buttons to the dialog buttonbar by specifying 'type' of the popup as 'none', then please note that you can't set default focus to any of these custom buttons. So, first you need to find why you require a custom button instead of the popup's default buttons by specifying 'type' attribute. You can always override the default 'OK' or 'Yes' button labels by setting 'AffirmativeTextAndAccessKey' and similarly 'No' and 'Cancel' button labels by specifying values for 'NoTextAndAccessKey' and 'CancelTextAndAccessKey' attributes. If your requirement is more than a label, like to have multiple actions in popup by specifying multiple buttons, then you need to consider adding additional buttons along with default buttons that comes by specifying the 'type' attribute for the dialog. If you just use the custom buttons only, then the default focus will be on the close(X) icon at the top right corner of the popup. That means, if you press 'Enter', the popup will be closed as the focus is on close icon.

If you want to execute some logic on pressing the default dialog buttons, you need to write the dialog listener. Similarly, if you need to do some processing on pressing the custom button that you added in the dialog buttonbar, you need to write actionlistener for the button. If you use both default buttons as well as custom buttons, you would require both dialoglistener and actionlistener.

Sample dialog listener code for dialog type 'yesNoCancel':
public void sampleDialogListener(DialogEvent dialogEvent) { if ("yes".equals(dialogEvent.getOutcome())) { ADFUtil.invokeEL("#{bindings.Commit.execute}"); FacesContext context = FacesContext.getCurrentInstance(); context.getApplication().getNavigationHandler().handleNavigation(context, null, "submit"); } else if ("no".equals(dialogEvent.getOutcome())) { ADFUtil.invokeEL("#{bindings.Rollback.execute}"); FacesContext context = FacesContext.getCurrentInstance(); context.getApplication().getNavigationHandler().handleNavigation(context, null, "noAction"); } else if ("cancel".equals(dialogEvent.getOutcome())) { FacesContext context = FacesContext.getCurrentInstance(); context.getApplication().getNavigationHandler().handleNavigation(context, null, "cancel"); }


So, the moral of the story is if you just use custom buttons and specify 'none' for type attribute of af:dialog, you won't be able to set focus to any of those buttons. If you use at least button by specifying 'type' to other than 'none', then the focus will be set to the most obvious button among the displayed buttons based on the specified 'type' attribute.

2 comments:

  1. You can set the focus on a custom button using a clientListener that you add to the popup component:

    <af:clientListener type="popupOpened" method="setFocus"/>

    The setFocus javascript method can look like this:

    function setFocus(){ comp = AdfPage.PAGE.findComponent('myButton'); comp.focus();}

    Steven Davelaar

    ReplyDelete
  2. Thanks Steven, that works perfectly

    ReplyDelete

Related Posts with Thumbnails