How to call a method with a parameter in JSF

Solution 1:

Passing method arguments was introduced in EL 2.2. So this is only possible if you're running on a Servlet 3.0 / EL 2.2 capable container like Tomcat 7, Glassfish 3, JBoss AS 6, etc and your web.xml is been declared as per Servlet 3.0 specification.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
>
    <!-- Config here -->
</web-app>

If you aren't, then check this answer for alternatives with regard to obtaining current row in datatables, or this answer with regard to replacing the EL implementation by one which supports passing method arguments so that you can use it on Servlet 2.5 / EL 2.1 containers as well.

Solution 2:

Jboss Seam can also help to get the feature.

Seam uses JBoss EL which provides an extension to the standard Unified Expression Language (EL). JBoss EL provides a number of enhancements that increase the expressiveness and power of EL expressions.

Example:

pass literal strings using single quotes: <h:commandLink action="#{printer.println('Hello world!')}" value="Hello"/>

or for dynamic value <h:commandButton action="#{hotelBooking.bookHotel(hotel)}" value="Book Hotel"/>

Limitation:

JBoss EL can't currently be used with JSP 2.1 as the compiler rejects expressions with parameters in. So, if you want to use this extension with JSF 1.2, you will need to use Facelets. The extension works correctly with JSP 2.0.

Solution 3:

There has actually been a "hack" way of doing this since JSF 1.0. You just create a method on your backing bean that returns a Map, and you can use JSF EL to pass whatever object you want to that method, because JSF thinks that you are passing the key to the map.

Meanwhile, in your backing bean method you actually return an "imposter" map instance that is not really a map at all, whose get() method delegates to the method you wanted to call. In your .xhtml or .jsp file then you can use the square bracket notation to pass the variable.

Extending HashMap is one way to make the imposter map easy to define -- succinct enough to use an anonymous inner class that way.

This is a hack, but it has worked well for me in the past.