2 Replies Latest reply on Oct 11, 2012 1:30 AM by christian.yttesen

    CommandLink howto use "runtime" value for action/actionListener

    christian.yttesen

      Hi,

       

      Using RichFaces 3.3.3 GA.

       

      I have dataTable component which is currently being constructed server-side using the binding attribute. My goal is to get rid of this server-side construction but I face problems when it comes to my command link.

       

      I have a list of MessageAction value objects, defined as

       

      public class MessageAction {
        protected String cssIcon;
        protected String label;
        protected String link;
        protected MethodExpression action;
        protected MethodExpressionActionListener actionListener;
      }
      

       

      My component binding code iterate those and constructs instances of the CommandLink object and sets the action/actionListener attributes, like:

       

      AjaxCommandLink link = new AjaxCommandLink();
      link.setValue(JsfUtils.getResource(action.getLink()));
      link.setImmediate(true);
      if (action.getActionListener() != null) {
        link.addActionListener(action.getActionListener());
      }
      if (action.getAction() != null) {
        link.setActionExpression(action.getAction());
      }
      

       

      So I need help as to how I can use the runtime value of messageAction.action and messageAction.actionListener when the dataTable is generated in my JSF page.

       

      <rich:dataTable value="#{messageActionBean.messageActions}" var="item">
        ...
        <rich:column>
          <a4j:commandLink value="#{msgs[item.link]}" immediate="true" actionListener="#{item.actionListener}" action="#{item.action}" />
        </rich:column>
      </rich:dataTable>
      

       

      The effect of above is not the runtime evaluated #{item.actionListener}.

       

      I'm very open to other ways of doing this - I just want to move away from the component binding as the table is getting more complex and its much easier to maintain in JSF page.

       

      If I create a binding on the commandLink I somehow need access to the "current" messageAction being iterated - can this be accomplished somehow?.

       

      Thanks.

       

      Regards,

      Christian

        • 1. Re: CommandLink howto use "runtime" value for action/actionListener
          christian.yttesen

          If I create a binding on the commandLink I somehow need access to the "current" messageAction being iterated - can this be accomplished somehow?.

           

          Tried out a component binding on the commandLink:

          <a4j:commandLink binding="#{messageActionBean.actionLink}" />

           

          Added logic in the binding get-method that construct the link + action/actionListener. Current row (MessageAction) was simply obtained by finding the dataTable component (enumerating parents) and invoke the dataTable.getRowData() to get the current row.

           

            public HtmlCommandLink getActionLink() {

              MessageAction curr = getCurrentMessageAction(actionLink);

              if (actionLink != null && curr != null) {

                actionLink.setValue(JsfUtils.getResource(curr.getLink()));

                actionLink.setImmediate(true);

                if (curr.getActionListener() != null) {

                  actionLink.addActionListener(curr.getActionListener());

                }

                if (curr.getAction() != null) {

                  actionLink.setActionExpression(curr.getAction());

                }

              }

              return actionLink;

            }

           

          Seems not to work either - the link is not displayed at all :-(. Might be me not fully understanding component bindings.

           

          Regards,

          Christian

          • 2. Re: CommandLink howto use "runtime" value for action/actionListener
            christian.yttesen

            Found a solution that works for me. Essentially I assign the action and actionListener to the MessageActionBean that holds the list of MessageActions - inside these methods I simply "forward" the calls.

             

            JSF:

            <h:commandLink value="#{msgs[item.link]}" actionListener="#{messageActionBean.actionListener}" action="#{messageActionBean.action}" immediate="true">

                      <f:attribute name="current" value="#{item}" />

                      <f:setPropertyActionListener value="#{item}" target="#{messageActionBean.current}" />

            </h:commandLink>

             

            ManagedBean:

            public String action() {

              return (String) current.getAction().invoke(FacesContext.getCurrentInstance().getELContext(), null);

            }

             

            public void actionListener(ActionEvent evt) {

                      current = (MessageAction) evt.getComponent().getAttributes().get("current");

                      current.getActionListener().processAction(evt);

            }    

             

            Still interessed in hearing about other possible solutions.

             

            Regards,

            Christian

            1 of 1 people found this helpful