This discussion is archived
5 Replies Latest reply: May 22, 2013 9:21 AM by Jeet_A RSS

Using Contextual Events for <af:commandToolbarButton ...>

DzmitryP Newbie
Currently Being Moderated
Hi all,

I am using 11.1.1.7.0 jdev and I can't update to some newer version.

I need to fire an event in one region, and perform some actions according to it in other one. I want to use ContextualEvent functionality as it was described in here . All seems clear, but I stuck in how to declare Contextual event.

I have a <af:commandToolbarButton ...> element to produce contextual event, I can't change it to another element. "af:commandToolbarButton" doesn't have Behaivor - ContextualEvents inside-tab to declare a Contextual event. May I need to specify it in other way, for example using a actionListener="#{viewScope.BeanName.callToEventProducer}" and perform attempt to rise contextual event programmatically?


in my code I have:
<af:commandToolbarButton ... actionListener="#{BBean.commandUndoRedo}"/>
and in bean code:
    public void commandUndoRedo(ActionEvent actionEvent) {
        BindingContainer bindings = BindingContext.getCurrent().getCurrentBindingsEntry();
        JUEventBinding eventBinding = (JUEventBinding) bindings.get("undoRedoEvent");
        ActionListener al = (ActionListener)eventBinding.getListener();
        al.processAction(actionEvent);
    }
and in taskFlow page def:
  <bindings>
    <eventBinding Listener="javax.faces.event.ValueChangeListener" id="undoRedoEvent">
      <events xmlns="http://xmlns.oracle.com/adfm/contextualEvent">
        <event name="undoRedoPublisherEvent"  eventType="Action Event"/>
      </events>
    </eventBinding>
  </bindings>
and when I try to find this event in other task flow in pageDef - Bindings - ContextualEvents - Subscribers -

I don't see any 'undoRedoEvent' or 'undoRedoPublisherEvent'

Am I doing all right?

Thank you.
  • 1. Re: Using Contextual Events for <af:commandToolbarButton ...>
    Jeet_A Journeyer
    Currently Being Moderated
    Hi,


    Please refer to forum,

    ADF Contextual Event
    You need to create anonymous provider "*"
    (Check Frank's comment)
        <event name="*">
          <producer region="eventBinding"></producer>
        </event>
    and in its subsciber you can select your actual event.
      <eventMap xmlns="http://xmlns.oracle.com/adfm/contextualEvent">
        <event name="undoRedoEvent">
          <producer region="XXXXXXXX.eventBinding">
            <consumer region="" handler="YourHandler"/>
          </producer>
        </event>
      </eventMap>
    Thanks,
    Jit
  • 2. Re: Using Contextual Events for <af:commandToolbarButton ...>
    DzmitryP Newbie
    Currently Being Moderated
    I looked at your posts, but I have a little bit different situation.

    I have a Page 'Home'. Inside a 'Home' I have a bounded task flow 'A'. Inside the bounded task flow 'A' I have dynamic region 'B'. This dynamic region can be switched to 'B1' or 'B2'. Inside a 'B1' or 'B2' I have a same bounded task flow 'D'. I making an operation inside a region 'A':

    In this bounded task flow 'A' I generating an event in response of this operation (call it programmaticaly):
        <eventBinding Listener="javax.faces.event.ActionListener" id="undoRedoEvent">
          <events xmlns="http://xmlns.oracle.com/adfm/contextualEvent">
            <event name="undoRedoPublisherEvent" eventType="Action Event"/>
          </events>
        </eventBinding>
    , then I want region 'D' to refresh a table in response to this action. Note that region 'D' is inside a dynamic region: 'B1' or 'B2'

    As far as I understand, I need to edit event map for parent - 'Home' region. I expect that for now this event will be accessible for all child regions. Even this is not a direct child and they are in dynamic regions.

    Having the chain like:
    'Home' - 'regionA' - '(dynamic region)BX' - 'C'

    when I am throwing event in 'regionA' I want this event can be heard in region 'C'

    and registering it like
      <eventMap xmlns="http://xmlns.oracle.com/adfm/contextualEvent">
        <event name="*">
          <producer region="regionA">
            <consumer region="" handler="*"/>
          </producer>
        </event>
      </eventMap>
    Means that every event came from 'regionA' will be propagated to all the child regions.
    But it is not.

    Playing with events recently I found that I can achieve expected functionality in some strange case:
    For example I making a producer consumer pair in context of only 'regionA', means, when I call to bounded methodCall for DataControl, even this method is nothing to do (empty implementation), table in region 'C' got refreshed. That looks like throwing a Contextual Event causing all the 'regionA' refresh itself.

    But I don't think I can use such shamanic implementation in production.

    Personally for me, looks like Oracle implementation of this Contextual event is confused for complex cases.

    Spend some time investigating it, I think it would be better to find another way to handle refreshes.
  • 3. Re: Using Contextual Events for <af:commandToolbarButton ...>
    Jeet_A Journeyer
    Currently Being Moderated
    Hi,

    You can create Event Producer from A
      <eventMap xmlns="http://xmlns.oracle.com/adfm/contextualEvent">
        <event name="*">
          <producer region="regionA">
            <consumer region="" handler="handleRefresh"/>
          </producer>
        </event>
      </eventMap>
    And inside Consumer handler you can get handle of Region C bean (If it is different from A) and refresh only that part.

    eg.
    this would be your consumer method(Create Class + Create Data Control + Add as Method Action on jsff)
        public void handleRefresh(Object payLoad){
                 FacesContext fctx = FacesContext.getCurrentInstance();
            
            ELContext elctx = fctx.getELContext();
            ValueExpression valExpr =
                fctx.getApplication().getExpressionFactory().createValueExpression(elctx,
                                                                                   "#{backingBeanScope.backing_<YourbeanName>}",
                                                                                   YourBeanName.class);
            YourBeanName bean = (YourBeanName)valExpr.getValue(elctx);
            bean.refreshT1();
            
        }
    You can check
    http://www.jobinesh.com/2010/11/triggering-navigation-from-contextual.html
    http://www.jobinesh.com/2009/07/programmatically-publishing-contextual.html

    Thanks,
    Jit
  • 4. Re: Using Contextual Events for <af:commandToolbarButton ...>
    DzmitryP Newbie
    Currently Being Moderated
    Thank you, now I got it.

    I am using: this is to register event binding for page definition file (producer task flow):
      <bindings>
        <eventBinding id="undoRedoBinding"
                      Listener="javax.faces.event.ActionListener">
          <events xmlns="http://xmlns.oracle.com/adfm/contextualEvent">
            <event name="undoRedoEvent" eventType="Action Event"/>
          </events>
        </eventBinding>
      </bindings>
    this method is invoking action event (inside the event produser's bean):
        public void fireUndoRedoEvent(ActionEvent actionEvent){
           BindingContainer bindingContainer = BindingContext.getCurrent().getCurrentBindingsEntry();  
           JUEventBinding eventBinding = (JUEventBinding)bindingContainer.get("undoRedoBinding");         
           ActionListener actionListener = (ActionListener)eventBinding.getListener();  
           actionListener.processAction(actionEvent);
        }
    this is registration in child region (region C inside bounded dynamic task flow, who's region is inside producer's region)
      <bindings >
        <methodAction id="handleUndoRedoRefresh"
                      InstanceName="UndoRedoHandler.dataProvider"
                      DataControl="UndoRedoHandler" RequiresUpdateModel="true"
                      Action="invokeMethod" MethodName="handleUndoRedoRefresh"
                      IsViewObjectMethod="false"/>
      </bindings>
      <eventMap xmlns="http://xmlns.oracle.com/adfm/contextualEvent">
        <event name="undoRedoEvent">
          <producer region="*">
            <consumer region="" handler="handleUndoRedoRefresh" handleCondition=""/>
          </producer>
        </event>
      </eventMap>
    Just one trouble - when I am opening 'Contextual events' - 'Suscribers' for overview of page definition file and attempt to find event from parent region - I don't see any, but registering it manually through xml editor - seems 'ok'.

    Thank you.
  • 5. Re: Using Contextual Events for <af:commandToolbarButton ...>
    Jeet_A Journeyer
    Currently Being Moderated
    Hi,

    Yes, i too didnt find declarative way to add event raised on child page so follow same thing which you did.

    Inside Page Def below Bindings
    <bindings/>
      <eventMap xmlns="http://xmlns.oracle.com/adfm/contextualEvent">
        <event name="*">
          <producer region="*">
            </producer>
        </event>
      </eventMap>
    </pageDefinition>
    Once we have * we can alter both Publisher and subscriber.

    Thanks,
    Jit

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points