Passing action method names as arguments to facelets componenets
Asked Answered
S

2

18

I am calling a template and am passing in parameters like below:

<ui:include src="WEB-INF/Subviews/ProductEdit.xhtml">
    <ui:param name="items" value="#{produtList}"></ui:param>
    <ui:param name="itemToEdit" value="#{productToEdit}"></ui:param>
</ui:include>

and in the ProductEdit.xhtml, I have something like

<ui:repeat value="#{items}" var="item">
  <tr>
    ...
    ...
    <td style="text-align: center">
      <h:commandLink style="cssGenericColumn" action="#{productEditAction}">
         <f:setPropertyActionListener target="#{itemToEdit}" value="#{item}"/>
      </h:commandLink>    
    </td>
  <tr>
</ui:repeat>

which works fine.

I now want to parameterize the #{productEditAction} in the ProductEdit.xhtml and so I did the following

<ui:include src="WEB-INF/Subviews/ProductEdit.xhtml">
    <ui:param name="items" value="#{produtList}"></ui:param>
    <ui:param name="itemToEdit" value="#{productToEdit}"></ui:param>
    <ui:param name="itemEditAction" value="#{productEditAction}"></ui:param>
</ui:include>

in the first page and then in ProductEdit.xhtml I do

<ui:repeat value="#{items}" var="item">
  <tr>
    ...
    ...
    <td style="text-align: center">
      <h:commandLink style="cssGenericColumn" action="#{itemEditAction}">
         <f:setPropertyActionListener target="#{itemToEdit}" value="#{item}"/>
      </h:commandLink>    
    </td>
  <tr>
</ui:repeat>

and this fails on the following error

javax.faces.el.EvaluationException: /WEB-INF/Subviews/ProductEdit.xhtml @45,89 action="#{itemEditAction}": Identity 'itemEditAction' does not reference a MethodExpression instance, returned type: java.lang.String
at com.sun.facelets.el.LegacyMethodBinding.invoke(LegacyMethodBinding.java:    at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:    at javax.faces.component.UICommand.broadcast(UICommand.java:109)....
 ....
 ....
 ....

This however works if the action bound to the model object. So something like

 <h:commandLink style="cssGenericColumn" action="#{item.editAction}">

Any ideas?

Synecious answered 14/4, 2011 at 6:26 Comment(0)
A
54

Passing a method as a parameter should be done in this way:

itemBean="#{bean}"
itemEditAction="productEditAction"

and in your component you will put them togheter:

action="#{itemBean[itemEditAction]}"
Alvin answered 14/4, 2011 at 8:17 Comment(3)
Bless you sir! You saved me putting my fist through the monitor, or worse, having to redesign my application.Ratter
If there wasn't a method named "productEditAction" in the controller, it will give an error at runtime instead of compile time because we are passing method name as a string instead of passing method directly (kinda like javascript) right?Intumescence
Wait, where does this itemEditAction parameter assignation take place? Neither ui:param nor ui:include have such parameters.Heaver
C
2

Maybe the ActionMapperTagHandler would work.

Cosmos answered 3/8, 2012 at 8:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.