-
Available since OmniFaces 1.0
The <o:methodParam>
is a tag handler that can be used to pass a method expression as attribute into a Facelets tag. By default this is not possible, and the expression that's intended to be a method expression will be created and made available as a value expression.
This handler wraps a value expression that's actually a method expression by another value expression that returns a method expression that gets the value of first value expression, which as "side-effect" executes the original method expression. This somewhat over-the-top chain of wrapping is done so a method expression can be passed as attribute into a Facelet tag.
This page demonstrates the passing of an EL reference to a method to a Facelets tag in a variety of
different ways. Note that the <demo:xxx>
tags in the example are purely for demonstration,
it should represent your own custom Facelets tag.
<p>
This page demonstrates the passing of an EL reference to a method to a Facelets tag in a variety of
different ways. Note that the <code><demo:xxx></code> tags in the example are purely for demonstration,
it should represent your own custom Facelets tag.
</p>
<h:form>
<ul>
<li>Action invoked: #{methodParamBean.actionInvoked}</li>
<li>Listener invoked: #{methodParamBean.listenerInvoked}</li>
<li>Lisitener with event invoked: #{methodParamBean.listenerWithEventInvoked}</li>
</ul>
<h3>Actions</h3>
<p>
Passing method with zero arguments
<demo:actionmethod action="#{methodParamBean.doAction}" />
</p>
<p>
Passing method with zero arguments but explicit parenthesis
<demo:actionmethod action="#{methodParamBean.doAction()}" />
</p>
<p>
Passing method with 1 view provided argument:
<demo:actionmethod action="#{methodParamBean.doActionWithParam('test')}" />
</p>
<p>
Passing method to second bean with 1 view provided argument:
<demo:actionmethod action="#{methodParamBean.bean.doActionWithParam('test')}" />
</p>
<h3>Listeners</h3>
<p>
Passing listener method with zero arguments
(always needs trick to pass!)
<demo:actionlistenertrick listener="#{methodParamBean.actionListener}" />
</p>
<p>
Passing listener method with zero arguments but explicit parenthesis
(needs trick on older EL impl. like JBoss 6, not needed on AS 7)
<demo:actionlistenertrick listener="#{methodParamBean.actionListener()}" />
</p>
<p>
Passing listener method with 1 view provided argument:
<demo:actionlistener listener="#{methodParamBean.actionListenerWithParam('test')}" />
</p>
<p>
Passing listener method with declared event parameter, no provided arguments
<demo:actionlistener listener="#{methodParamBean.actionListenerWithClientParam}" />
</p>
<h3>Direct bindings</h3>
<p>
Direct binding (no method passing) with zero arguments:
<h:commandButton value="test" action="#{methodParamBean.doAction()}" />
</p>
</h:form>
package org.omnifaces.showcase.taghandlers;
import jakarta.enterprise.context.RequestScoped;
import jakarta.faces.event.ActionEvent;
import jakarta.inject.Named;
@Named
@RequestScoped
public class MethodParamBean {
private boolean actionInvoked;
private boolean listenerInvoked;
private boolean listenerWithEventInvoked;
public void doAction() {
actionInvoked = true;
}
public void doActionWithParam(String dummy) {
actionInvoked = true;
}
public void actionListener() {
listenerInvoked = true;
}
public void actionListenerWithParam(String dummy) {
listenerInvoked = true;
}
public void actionListenerWithClientParam(ActionEvent event) {
listenerWithEventInvoked = true;
}
public MethodParamBean getBean() {
return this;
}
public boolean getActionInvoked() {
return actionInvoked;
}
public boolean getListenerInvoked() {
return listenerInvoked;
}
public boolean isListenerWithEventInvoked() {
return listenerWithEventInvoked;
}
}
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="jakarta.faces.html"
xmlns:ui="jakarta.faces.facelets"
xmlns:o="http://omnifaces.org/ui"
>
<o:methodParam name="method" value="#{action}" />
<h:commandButton value="test" action="#{method}" />
</ui:composition>
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="jakarta.faces.html"
xmlns:ui="jakarta.faces.facelets"
xmlns:o="http://omnifaces.org/ui"
>
<o:methodParam name="method" value="#{listener}" />
<!--
This is only needed for the "Passing listener method with zero arguments" test, and is
only needed for implementations of Mojarra before 2.1.8. (see https://github.com/eclipse-ee4j/mojarra/issues/2351)
The problem is that Mojarra 2.1.7 and before copy a method expression based on the literal EL expression only, which
means the variable mapper isn't copied. As it's the variable mapper that contain the reference
to our method, this copied expression can't be resolved.
A workaround is to put the method into request scope with nested visibility via the ui:repeat trick.
-->
<ui:repeat var="method" value="#{method}">
<h:commandButton value="test" actionListener="#{method}" />
</ui:repeat>
</ui:composition>
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="jakarta.faces.html"
xmlns:ui="jakarta.faces.facelets"
xmlns:o="http://omnifaces.org/ui"
>
<o:methodParam name="method" value="#{listener}" />
<h:commandButton value="test" actionListener="#{method}" />
</ui:composition>