How to pass parameters into a p:commandbutton? [duplicate] - jsf

How can I in JSF 2.0 invoke direct methods or methods with arguments / variables / parameters in EL?
For example, getting the list size in EL:
<h:outputText value="#{bean.list.size()}" />
Or invoking an action method with arguments:
<h:commandButton value="edit" action="#{bean.edit(item)}" />
This does not seem to work in my environment. It doesn't seem to like parentheses.
javax.el.ELException: Error Parsing: #{bean.list.size()}
com.sun.el.parser.ParseException: Encountered "("

In standard EL prior to EL 2.2 from Java EE 6 you cannot directly invoke methods like
#{bean.method()} nor invoke methods with arguments like #{bean.method(arg1, arg2).
If upgrading to a EL 2.2 / Java EE 6 compliant container (Tomcat 7, Glassfish 3, JBoss AS 6, etc) is not an option and you're currently using EL 2.1 / Java EE 5 (Tomcat 6, Glassfish 2, JBoss AS 4, etc), then your best bet is to install JBoss EL. JBoss EL is an EL 2.1 compliant implementation which supports the same features as EL 2.2. Installing JBoss EL is a matter of putting the jboss-el.jar in /WEB-INF/lib and adding the following to the web.xml, assuming that you're using Mojarra:
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
Or, when you're using MyFaces:
<context-param>
<param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
An alternative for your particular case is to use JSTL's fn:length:
<h:outputText value="#{fn:length(bean.list)}" />
Another alternative is to add a getter to the bean which returns List#size() or in some specific cases a custom EL function.
Please note thus that invoking methods with arguments in EL is not a JSF 2.0 specific feature. It's an EL 2.2 specific feature. EL 2.2 is part of Java EE 6, which JSF 2.0 is also part of. So it look like a JSF 2.0 specific feature, but it isn't. JSF 2.0 is backwards compatible with Servlet 2.5 / EL 2.1 which lacks this feature. On the other hand, JSF 1.x is forwards compatible with Servlet 3.0 / EL 2.2, so it would also be possible to use this feature in JSF 1.x then, also using JBoss EL on Servlet 2.5 / EL 2.1.

BalusC's answer is correct, however, when you use maven, you should exclude el-api 1.0 transitive dependency like this:
<dependency>
<groupId>org.jboss.seam</groupId>
<artifactId>jboss-el</artifactId>
<version>2.0.0.GA</version>
<!-- exclude el-api 1.0 transitive dependency -->
<exclusions>
<exclusion>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
</exclusion>
</exclusions>
</dependency>

Related

jsf - el function with bean

Hi i can define functions like this for el:
<function>
<function-name>areAllGranted</function-name>
<function-class>org.springframework.faces.security.FaceletsAuthorizeTagUtils</function-class>
<function-signature>boolean areAllGranted(java.lang.String)</function-signature>
</function>
</facelet-taglib>
but what can i do if i want to use a spring bean with initalised autowired-fields, instead of a plain new instance of an class?
If your're using a Servlet 3.0 container which supports EL 2.2 (Tomcat 7, Glassfish 3, etc), just do it.
<h:someComponent rendered="#{bean.areAllGranted('someString')}">
If your're using an old Servlet 2.5 container which doesn't support it, then install JBoss EL so that you can use the new EL 2.2 syntax. This is answered in detail here: Invoking methods with parameters by EL in JSF 1.2

How to pass a method argument to getter?

I want to use a datalist
<rich:dataList value="#{bean.itemsOnLevel}" var="item">
<h:outputText value="#{item.value}" />
</rich:dataList>
but my getter needs a parameter
public List getItemsOnLevel(int level);
how can I pass the level?
If you're already targeting a Servlet 3.0 compatible container (Tomcat 7, Glassfish 3, JBoss 6, etc) with a Servlet 3.0 compatible web.xml in your webapp, then you can make use of the new EL 2.2 feature of invoking methods with arguments:
<rich:dataList value="#{bean.getItemsOnLevel(1)}" var="item">
<h:outputText value="#{item.value}" />
</rich:dataList>
If you're however targeting an older Servlet 2.5 compatible container (Tomcat 6, Glassfish 2, JBoss 4/5, etc), then your best bet is to install JBoss EL to achieve the same. See also this answer for details: Invoke direct methods or methods with arguments / variables / parameters in EL

Passing parameters to a method in h:outputtext tag

I would like to display a text in jsf screen by passing an attribute to a method implemented in backing bean. I have to pass a dynamic value as an attribute. I tried the below but it seems to be an incorrect syntax -
<h:outputText value="#{getValue(#{item.product}).component.address}" />
Apart from the syntax error (you can never nest EL expressions like as #{#{}}), the following is valid in EL 2.2 which is in turn part of Servlet 3.0 / Java EE 6:
<h:outputText value="#{bean.getValue(item.product).component.address}" />
So if you have a Servlet 3.0 compatible target runtime (Tomcat 7, Glassfish 3, JBoss 6, etc) with a Servlet 3.0 compatible web.xml, then you can invoke non-getter methods with arguments like this.
However, based on your question history you're using JSF 1.2 and the chance is big that you're also targeting an older container where the above wouldn't work. If it is a Servlet 2.5 container, then you could use JBoss EL to get this EL syntax to work.
See also:
Invoking methods with parameters by EL in JSF 1.2
JSF 1.2 w/ EL 2.1 (the usual pairing) doesn't support calling methods with parameters on beans using EL expressions.
There exists one hack, abusing the fact that JSF EL expressions work on maps:
value="#{myBean['product']}"
This will assume myBean is implementing Map interface and will call get method with 'product' as parameter. I don't know if the key can be dynamically computed but it's worth a try.
Syntax would be:
value="#{myBean[item.product].component.address}"
Assuming here that myBean implements Map interface and returns the appropriate object and item.product is returns a string.
I am not sure this will work, but it's your only option beside implementing a getter that looks up item.product value in its implementation.

Invoking methods with parameters by EL in JSF 1.2

I am using a datatable and for each row I have two buttons, an "Edit" and a "Delete".
I need these buttons to be read-only, i.e. disabled, if a certain condition is met for the row in question. I have seen in JSF 2 that it is possible to pass parameters to method calls. Is there anything equivalent in JSF 1.2?
Ideally what I would like it something like (the looping variable is loop and there is another bean, helper, which contains the method I would like to invoke):
<h:commandButton value="Edit"
disabled="#{helper.isEditable(loop.id)}" />
In this case it does not make semantic sense to add an isEditable attribute to the bean and it is not practical to create a wrapper Object around the bean.
Thanks in advance.
I have seen in JSF 2 that it is possible to pass parameters to method calls. Is there anything equivalent in JSF 1.2?
Passing parameters to method calls is not specific to JSF 2. It is specific to EL 2.2, which is in turn part of JSP 2.2 / Servlet 3.0 / Java EE 6. JSF 2 just happens to be part of Java EE 6 as well. In other words, if you deploy your JSF 1.2 web application to a Servlet 3.0 compatible container like Tomcat 7, Glassfish 3, etc and your web.xml is declared conform Servlet 3.0 spec version, then it'll just work out the box for JSF 1.x as well.
If you're however still targeting a container of an older Servlet version, then you need to supply a different EL implementation which supports invoking methods with arguments. One of those implementations is JBoss-EL which you can install by just dropping the jboss-el.jar file in /WEB-INF/lib of your webapp and adding the following context parameter to the web.xml. Here's a Mojarra-specific example (Mojarra is the codename of JSF RI):
<context-param>
<param-name>com.sun.faces.expressionFactory</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
If you're using MyFaces as JSF implementation, you need the following context parameter instead:
<context-param>
<param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
See also:
Invoke direct methods or methods with arguments / variables / parameters in EL

Weblogic 10.3.4 jsf 1.2 encodes special characters

We have a web application, which uses weblogic jsf 1.2 implementation from deployable-libraries(jsf-1.2.war). We started to use weblogic jsf impl after having some problems with compatibility of packed jsf-impl and weblogic 10.3.4.
So the problem is that, we have outputLink with several params, these params' values could contain spacial chars, so we explicitly encode them(we have taglib function for this purpose), but jsf impl on weblogic 10.3.4 also encodes these chars, so we have double encoded link URL. Does anybody know is there a possibility to disable this option on weblogic and encode params only manually.
Just do not encode it yourself with a custom taglib. The <f:param> will already implicitly do it.
<h:outputLink value="page.jsf">
<h:outputText value="Click" />
<f:param name="foo" value="#{bean.foo}" />
<f:param name="bar" value="#{bean.bar}" />
</h:outputLink>
That's all. The #{bean.foo} and #{bean.bar} in above example can just return the raw and unencoded string value.
Update as per the comments, this suggests that those two servers JBoss AS 4.2.3 and WebLogic 10.3.2 are using a specific JSF implementation/version which exposes a bug in URL-encoding of <f:param>. As far, I can only find the following related reports (it's not clear if you're using MyFaces or Mojarra, so I searched in both):
Mojarra (a.k.a. Sun RI): http://java.net/jira/browse/JAVASERVERFACES-791 fixed in 1.2_10.
MyFaces: https://issues.apache.org/jira/browse/MYFACES-1832 fixed in 1.1.6 and > 1.2.2(?).
I recommend to replace/upgrade the JSF version of the servers in question to a newer version than the ones mentioned in those reports, or to ship JSF libraries along with the webapp itself and add web.xml context parameters to instruct the server to use the webapp bundled JSF instead.

Resources