Can't make ajax tags work properly on autocomplete/calendar
jonathan.man Mar 18, 2012 12:11 PMHi everyone.
I'm having trouble making ajax work with richfaces component.
I played with autocomplete and calendar, and my results are :
Both component :
- Change event : call to listener and rendering both ok
- Autocomplete :
blur : listener never called, render done only with a4j:ajax tag, but not with f:ajax
selectitem : same as blur
- Calendar :
inputblur : listener never called, render never done even with a4j:ajax
dateselect : same as inputblur
I search the net for similar problems, but ended up on Jiras marked as resolved with richfaces 4.0 or 4.1.
My setup :
Eclipse indigo 3.7.2
Tomcat 7.0.25
jdk1.7.0
Mojarra 2.1.7
Richfaces 4.2.0
This is my setup at home, but i encountered similar problems at work with a different setup.
My setup at work is jdk1.6 and Indigo 3.7.0.
In fact, my problems at work were the reason i tried it at home with a different setup.
I even built an entire app with many test cases (f:ajax tag, a4j tag, different events...)
Here is one of these test case. Events tested are blur (autocomplete) and inputblur (calendar), both with f:ajax tag.
For autocomplete, using a4j:ajax would make the rendering work, but still not the listener.
<h:form>
<rich:panel header="Autocomplete Test">
<h:panelGrid columns="2">
<h:outputText value="Chose value : " />
<rich:autocomplete value="#{autocompleteTestBean.value}" 
    autocompleteList="#{autocompleteTestBean.values}"
    showButton="true">
<f:ajax event="blur" listener="#{autocompleteTestBean.onEventTested}" render="autoSelectedValue autoNumCall messages" />
</rich:autocomplete>
        
<h:outputText value="Chosen value : " />
<h:outputText id="autoSelectedValue" value="#{autocompleteTestBean.value}" />
            
<h:outputText value="Number of calls to listener : " />
<h:outputText id="autoNumCall" value="#{autocompleteTestBean.count}" />
</h:panelGrid>
</rich:panel>
    
<rich:panel header="Calendar Test">
<h:panelGrid columns="2">
<h:outputText value="Chose value : " />
<rich:calendar value="#{calendarTestBean.value}"
        enableManualInput="true"
        datePattern="dd-MM-yyyy">
<f:ajax event="inputblur" listener="#{calendarTestBean.onEventTested}" render="calSelectedValue calNumCall messages" />
</rich:calendar>
    
<h:outputText value="Chosen value : " />
<h:outputText id="calSelectedValue" value="#{calendarTestBean.value}" />
                
<h:outputText value="Number of calls to listener : " />
<h:outputText id="calNumCall" value="#{calendarTestBean.count}" />
</h:panelGrid>
</rich:panel>
<h:messages id="messages"/>
</h:form>
The change event works fine for both.
Here is my basic bean, since code is similar for both component :
package fr.testcomp;
import java.io.Serializable; 
import javax.faces.event.AjaxBehaviorEvent;
import org.richfaces.event.ItemChangeEvent;
public class BaseTestComp implements Serializable {
    
    private static final long serialVersionUID = -408484402711572130L;
    private int count = 0;
    private Object value = null;
    
    public void onEventTested() {
        this.doCall("void do()");
    }
    
    public void onEventTested(AjaxBehaviorEvent event) {
        this.doCall("void do(javax.faces.event.AjaxBehaviorEvent event)");
    }
    
    public void onEventTested(ItemChangeEvent event) {
        this.doCall("void do(org.richfaces.event.ItemChangeEvent event)");
    }
    
    private void doCall(String pSignature) {
        System.out.println("Listener call - Signature : " + pSignature);
        System.out.println("Listener call - Class : " + this.getClass());
        System.out.println("Listener call - Value : " + this.value);
        System.out.println();
        this.count++;
    }
    
   //getters and setters
}
Both my managed beans inherits this one, with @ManagedBeans and @ViewScope annotations.
The autocomplete one adds a random list of value :
package fr.testcomp.autocomplete;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import fr.testcomp.BaseTestComp;
@ManagedBean
@ViewScoped
public class AutocompleteTestBean extends BaseTestComp {
    private static final long serialVersionUID = 5379541731429097364L;
    private List<String> values = null;
    
    public AutocompleteTestBean() {
        //init the list with some values
    }
 //getter and setter
}
The calendar bean extends BaseTestComp without adding anything.
Here my dependancies.
<properties>
        <!-- <slf4j.version>1.6.4</slf4j.version> -->
        <spring.version>3.0.6.RELEASE</spring.version>
        <mojarra.version>2.1.7</mojarra.version>
        <richfaces.version>4.2.0.Final</richfaces.version>
        <hibernate.version>4.0.1.Final</hibernate.version>
        <junit.version>3.8.1</junit.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.richfaces</groupId>
                <artifactId>richfaces-bom</artifactId>
                <version>${richfaces.version}</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-api</artifactId>
            <version>${mojarra.version}</version>
        </dependency>
        <dependency>
            <groupId>com.sun.faces</groupId>
            <artifactId>jsf-impl</artifactId>
            <version>${mojarra.version}</version>
        </dependency>
        <dependency>
            <groupId>org.richfaces.ui</groupId>
            <artifactId>richfaces-components-ui</artifactId>
        </dependency>
        <dependency>
            <groupId>org.richfaces.core</groupId>
            <artifactId>richfaces-core-impl</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>javax.el</groupId>
            <artifactId>el-api</artifactId>
            <version>2.2</version>
            <!--<scope>provided</scope>-->
        </dependency>        
    </dependencies>
Here is web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>Test components</display-name> <context-param> <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name> <param-value>true</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping> </web-app>
faces-context.xml is empty.
I probably could make it work with a jsFunction, but I have that feeling that I must be missing something.
And i'm afraid i'll encounter that behaviour on other components as well.
Maybe I misunderstand the ajax tags?
Sorry for the long post, it doesn't look like it, but i tried to make it short.