Pages

Fire an methodAction from a component without an actionEvent

I had an use case in which I needed to execute a methodAction from a selectOneChoice.
Looking around on the net I found this blog from Frank Nimphius which was usefull: https://blogs.oracle.com/jdevotnharvest/entry/how-to_navigate_in_bounded_task_flows

But there are more ways to achieve what we needed.
The selectOneChoice component doesn’t support action or actionListener. So I misused the valueChangeListener to do this. We cannot call a taskflow action, nor can we programmatic call the actionListener because of the JSF Lifecycle phase we are currently in (JSFProcess Validations), the methodAction will use the oldValue from the selectOneChoice and not the newValue.

I will describe two more options to achieve the correct result:
1.       Programmatic queue the task after the InvokeApplicationPhase.
2.       Use the bindings to invoke the Action.

Programmatic queue the task After the Invoke Application phase
On the page, set the valueChangeListener to a method in your backingBean.
In this method you have to perform the following steps:
  • Get the OperationBinding.
  • Get the AdfFacesContext.
  • Put the OperationBinding on the queue for after the invokeApplicationPhase.
    //get the OperationBinding.
    final BindingContext bctx = BindingContext.getCurrent();
    final BindingContainer bc = bctx.getCurrentBindingsEntry();
    final DCBindingContainer dcbc = (DCBindingContainer) bc;
    final OperationBinding action = dcbc.getOperationBinding("bindingName");

    //Queue action.execute after InvokeApplicationPhase.
    final AdfFacesContext afc = AdfFacesContext.getCurrentInstance();
    afc.queueTaskForAfterPhase(FacesContext.getCurrentInstance(), PhaseId.INVOKE_APPLICATION, new Runnable()
    {
      public void run()
      {
        action.execute();
      }
    });

Use the bindings to invoke the Action
Create a new executable:
Choose an id and choose the (method)Action that you want to bind.
In the properties choose refresh: renderModelIfNeeded.
Point the refreshCondition to a Boolean in the BackingBean.
On the page point the valueChangeListener from the component to a method that sets the boolean to true.

No comments:

Post a Comment