I have a template that's part of a form to edit some element. The action to be performed is different depending on the page in which it is included. So I pass the action method as a parameter:
<ui:param name="option" value="#{someOptionBean}" />
...
<ui:include src="/WEB-INF/jsf/value-edit.xhtml">
<ui:param name="controllerParam" value="#{optionController}" />
<ui:param name="elementParam" value="#{option}" />
<ui:param name="actionParam" value="updateOption" />
</ui:include>
or:
<ui:param name="property" value="#{somePropertyBean}" />
...
<ui:include src="/WEB-INF/jsf/value-edit.xhtml">
<ui:param name="controllerParam" value="#{propertyController}" />
<ui:param name="elementParam" value="#{property}" />
<ui:param name="actionParam" value="updateProperty" />
</ui:include>
and in value-edit.xhtml
there is a command button:
<p:commandButton value="Update" action="#{controllerParam[actionParam](elementParam)}" />
So far everything works fine.
My problem is that now the action methods don't have the same number of parameters. They are:
public void updateOption(Option option) { ... }
public void updateProperty(Item item, Prop property) { ... }
so I now want to be able to also define the action parameters to have something like:
<ui:param name="actionParam" value="updateOption(option)" />
<ui:param name="actionParam" value="updateProperty(item, property)" />
or something like:
<ui:param name="method" value="updateProperty" />
<ui:param name="parameters" value="item, property" />
I've read the docs (Value and Method Expressions / Parameterized Method Calls) and I'm not sure if this is possible.
Is there any way to achieve this?
Finally I solved this creating a MethodExpression
in the controller
Now the ui:include
looks like:
<ui:param name="option" value="#{someOptionBean}" />
...
<ui:include src="/WEB-INF/jsf/value-edit.xhtml">
<ui:param name="actionParam" value="#{optionController.getUpdateAction()}" />
</ui:include>
and
<ui:param name="item" value="#{someItemBean}" />
<ui:param name="property" value="#{somePropertyBean}" />
...
<ui:include src="/WEB-INF/jsf/value-edit.xhtml">
<ui:param name="actionParam" value="#{propertyController.getUpdateAction()}" />
</ui:include>
In value-edit.xhtml
the command button is:
<p:commandButton value="Update" action="#{actionParam}" />
The getUpdateAction
creates the MethodExpression
with the corresponding parameters for each controller:
public class OptionController {
...
public void updateOption(Option option) { ... }
public MethodExpression getUpdateAction() {
return createMethodExpression("#{optionController.updateOption(option)}", String.class, Option.class);
}
...
}
public class PropertyController {
...
public void updateProperty(Item item, Prop property) { ... }
public MethodExpression getUpdateAction() {
return createMethodExpression("#{propertyController.updateProperty(item, property)}", String.class, Item.class, Prop.class);
}
...
}
where createMethodExpression
is:
public static MethodExpression createMethodExpression(String expression, Class<?> expectedReturnType, Class<?>... expectedParameterTypes) {
FacesContext facesContext = FacesContext.getCurrentInstance();
return facesContext.getApplication().getExpressionFactory().createMethodExpression(
facesContext.getELContext(), expression, expectedReturnType, expectedParameterTypes);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With