reRender in <a4j:commandLink> in t:dataTable or t:dataList N
nils_eckert May 22, 2007 6:43 PMHello together,
I have a Problem similar to http://jboss.com/index.html?module=bb&op=viewtopic&t=105067&postdays=0&postorder=asc&start=0
My Environment is:
* Ajax4JSF 1.1 an 1.1.1-SNAPSHOT tried
* Tomcat 5.5
* MyFaces 1.1.5
* Facelets 1.1.11
* Tomahawk
* Trinidad 1.0.0 Incubating
On my page there is a h:inputText, where the user can enter a String. When the form is submitted, a customers, that match this string are listed with a h:dataTable or h:dataList.
Each row / element contains a a4j:commandLink with a a4j:actionparam to set the customer to the accountForm.
If I click the link, the request is done. But nothing happens.
If I render the list with a c:forEach and create the a4j:commandLink "by hand" it works.
So I think there is a Problem, detecting the correct element.
I tried the Ajax4jsf 1.1.1 SNAPSHOT. And build a ajax4jsf from the current svn trunk yesterday. All that didn't help.
Thanks for your help.
Regards,
Nils Eckert
Here is the Code:
accountForm.xhtml
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:c="http://java.sun.com/jstl/core"
 xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
 xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:t="http://myfaces.apache.org/tomahawk"
 xmlns:a4j="https://ajax4jsf.dev.java.net/ajax">
<f:view>
 <ui:composition template="layout.xhtml">
 <ui:define name="title">#{text['accountForm.title']}</ui:define>
 <ui:define name="content">
 <a4j:log hotkey="L" />
 <t:saveState id="account" value="#{accountForm.account}" />
 <f:loadBundle var="text" basename="#{accountForm.bundleName}" />
 <t:messages showDetail="true" showSummary="false" />
 <h:form id="accountForm">
 <div style="float: right;"><h:panelGroup styleClass="buttonBar bottom">
 <h:commandButton value="#{text['button.save']}" action="#{accountForm.save}" id="save" styleClass="button" />
 <c:if test="${not empty accountForm.account.id}">
 <h:commandButton value="#{text['button.delete']}" action="#{accountForm.delete}" id="delete" styleClass="button" />
 </c:if>
 <h:commandButton value="#{text['button.cancel']}" action="cancel" immediate="true" id="cancel" styleClass="button" />
 </h:panelGroup></div>
 <h1>#{text['accountForm.heading']}</h1>
 <table>
 <tr>
 <td><t:panelGroup>
 <h:outputLabel styleClass="desc" for="id" value="#{text['account.id']}" />
 <h:inputText styleClass="text small" id="id" value="#{accountForm.account.key.id}" readonly="true" />
 </t:panelGroup></td>
 <td><t:panelGroup>
 <h:outputLabel styleClass="desc" for="date" value="#{text['account.date']}" />
 <t:inputCalendar id="date" styleClass="text small" value="#{accountForm.account.date}" renderAsPopup="true"
 popupTodayString="#{example_messages['popup_today_string']}" popupDateFormat="dd.MM.yyyy"
 popupWeekString="#{example_messages['popup_week_string']}" helpText="dd.MM.yyyy" forceId="true"
 popupButtonImageUrl="images/fam_silk_icons/calendar.png" renderPopupButtonAsImage="true">
 <f:convertDateTime pattern="dd.MM.yyyy" timeZone="CET"/>
 </t:inputCalendar>
 <t:message for="date" styleClass="fieldError" />
 </t:panelGroup></td>
 <td><t:panelGroup>
 <h:outputLabel styleClass="desc" for="customer" value="#{text['customer.fullname']}" />
 <h:inputText styleClass="text large" id="customer" value="#{accountForm.account.customer.fullName}"
 readonly="true" />
 <t:message for="customer" styleClass="fieldError" />
 </t:panelGroup></td>
 </tr>
 </table>
 </h:form>
 </ui:define>
 <ui:define name="right">
 <div class="box"><a4j:form ajaxSubmit="true" reRender="customerSearchResult">
 <h:outputLabel for="input" styleClass="desc" value="Kundensuche:" />
 <h:inputText id="userName" styleClass="text medium" value="#{customerList.searchString}" />
 <a4j:commandButton value="GO" image="images/fam_silk_icons/zoom.png" />
 </a4j:form><a4j:outputPanel id="customerSearchResult">
 <c:choose>
 <c:when test="#{not empty customerList.searchResult}">
 <h:form class="smallHeightOverflow">
 <h:dataTable value="#{customerList.searchResult}" var="customer" styleClass="table" rowClasses="odd, even">
 <h:column>
 <a4j:commandLink id="chooseCustomer" value="#{customer.fullName}" reRender="customer, customerno"
 action="#{accountForm.update}" styleClass="output">
 <a4j:actionparam name="customerNo" assignTo="#{accountForm.customerNo}" value="#{customer.key.id}" />
 </a4j:commandLink>
 </h:column>
 </h:dataTable>
 </h:form>
 </c:when>
 <c:when test="#{customerList.searchString}">
 <p>Keine Kunden gefunden.</p>
 </c:when>
 </c:choose>
 </a4j:outputPanel></div>
 </ui:define>
 </ui:composition>
</f:view>
</html>
AccountForm.java
package de.neckert.webapp.action;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Map;
import java.util.TreeMap;
import javax.faces.context.FacesContext;
import de.neckert.model.Account;
import de.neckert.model.AccountItem;
import de.neckert.model.Customer;
import de.neckert.service.AbstractAccountManager;
import de.neckert.webapp.action.base.BasePage;
public class AccountForm extends BasePage implements Serializable {
 private static final long serialVersionUID = 4604220211994183235L;
 private AbstractAccountManager<Account> accountManager;
 private Account account = new Account();
 private AccountItem currentItem;
 private Long id;
 private Map<String, String> unities;
 private TreeMap<String, Float> taxPositions;
 public void setAccountManager(AbstractAccountManager<Account> accountManager) {
 this.accountManager = accountManager;
 }
 public Account getAccount() {
 return account;
 }
 public void setAccount(Account account) {
 this.account = account;
 }
 public AccountItem getCurrentItem() {
 if (currentItem == null) {
 currentItem = new AccountItem();
 currentItem.setQuantity(1.0f);
 currentItem.setUnity("Std.");
 currentItem.setTax(0.19f);
 currentItem.setPrice(new BigDecimal(60));
 currentItem.setName("Administration");
 }
 return currentItem;
 }
 public void setCurrentItem(AccountItem currentItem) {
 this.currentItem = currentItem;
 }
 public void setId(Long id) {
 this.id = id;
 }
 public String edit() {
 if (id != null) {
 account = accountManager.get(getKey(id));
 } else {
 account = new Account();
 }
 return EDIT;
 }
 public String addItem() {
 getAccount().addItem(currentItem);
 currentItem = null;
 return EDIT;
 }
 public String update() {
 return null;
 }
 public void setCustomerNo(Long id) {
 if (id != null) {
 Customer customer = getCustomerManager().get(getKey(id));
 if (customer != null) {
 account.setCustomer(customer);
 }
 }
 }
 public String save() {
 boolean isNew = (account.getId() == null);
 account.getKey().setUser(getUser());
 accountManager.save(account);
 String key = (isNew) ? "account.added" : "account.updated";
 addMessage(key);
 if (isNew) {
 return LIST;
 } else {
 return EDIT;
 }
 }
}
CustomerList.java
package de.neckert.webapp.action;
import java.util.ArrayList;
import java.util.List;
import de.neckert.model.Customer;
import de.neckert.service.CustomerManager;
import de.neckert.webapp.action.base.BasePage;
public class CustomerList extends BasePage {
 private CustomerManager customerManager;
 private String searchString;
 private List<Customer> searchResult;
 public CustomerList() {
 setSortColumn("id");
 }
 public void setCustomerManager(CustomerManager customerManager) {
 this.customerManager = customerManager;
 }
 public String getSearchString() {
 return searchString;
 }
 public void setSearchString(String searchString) {
 this.searchString = searchString;
 }
 public List<Customer> getCustomers() {
 return customerManager.getAll(sortColumn, ascending, getUser());
 }
 public List<Customer> getSearchResult() {
 if (searchResult == null) {
 List<Customer> result;
 if (searchString != null && searchString.length() != 0) {
 result = customerManager.find(searchString, getUser());
 } else {
 result = new ArrayList<Customer>();
 }
 sortColumn = "fullName";
 searchResult = sort(result);
 }
 return searchResult;
 }
}
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd"> <faces-config> <application> <variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver> <locale-config> <default-locale>de</default-locale> <supported-locale>en</supported-locale> </locale-config> <message-bundle>ApplicationResources</message-bundle> <view-handler>com.sun.facelets.FaceletViewHandler</view-handler> </application> SNIP... </faces-config>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>NEFO3</display-name> <distributable /> <!-- precompiled jsp mappings --> <!-- Define the default CSS Theme --> <context-param> <param-name>csstheme</param-name> <param-value>neis</param-value> </context-param> <!-- Define the basename for a resource bundle for I18N --> <context-param> <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name> <param-value>ApplicationResources</param-value> </context-param> <!-- Fallback locale if no bundles found for browser's preferred locale --> <!-- Force a single locale using param-name 'javax.servlet.jsp.jstl.fmt.locale' --> <context-param> <param-name>javax.servlet.jsp.jstl.fmt.fallbackLocale</param-name> <param-value>en</param-value> </context-param> <!-- Context Configuration locations for Spring XML files --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:/applicationContext-resources.xml classpath*:/applicationContext-dao.xml classpath*:/applicationContext-service.xml classpath*:/applicationContext.xml /WEB-INF/applicationContext*.xml /WEB-INF/security.xml </param-value> </context-param> <!-- FaceletViewHandler configuration --> <context-param> <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name> <param-value>com.sun.facelets.FaceletViewHandler</param-value> </context-param> <context-param> <param-name>javax.faces.DEFAULT_SUFFIX</param-name> <param-value>.xhtml</param-value> </context-param> <context-param> <param-name>org.apache.myfaces.trinidad.ALTERNATE_VIEW_HANDLER</param-name> <param-value>com.sun.facelets.FaceletViewHandler</param-value> </context-param> <context-param> <param-name>org.apache.myfaces.trinidad.CACHE_VIEW_ROOT</param-name> <param-value>false</param-value> </context-param> <!-- Use client-side state saving. In Trinidad, it is an optimized, token-based mechanism that is almost always a better choice than the standard JSF server-side state saving. --> <context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>client</param-value> <!--param-value>server</param-value--> </context-param> <context-param> <param-name>facelets.DEVELOPMENT</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>facelets.SKIP_COMMENTS</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>facelets.LIBRARIES</param-name> <param-value>/WEB-INF/taglibs/corejsf-validator.taglib.xml; /WEB-INF/taglibs/tomahawk.taglib.xml</param-value> </context-param> <filter> <filter-name>ajax4jsf</filter-name> <filter-class>org.ajax4jsf.Filter</filter-class> </filter> <filter> <filter-name>trinidad</filter-name> <filter-class>org.apache.myfaces.trinidad.webapp.TrinidadFilter</filter-class> </filter> <!-- <filter> <filter-name>cacheFilter</filter-name> <filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class> </filter> --> <!-- <filter> <filter-name>clickstreamFilter</filter-name> <filter-class>com.opensymphony.clickstream.ClickstreamFilter</filter-class> </filter> --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter> <filter-name>extensionsFilter</filter-name> <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class> <init-param> <param-name>maxFileSize</param-name> <param-value>2m</param-value> </init-param> </filter> <filter> <filter-name>gzipFilter</filter-name> <filter-class>net.sf.ehcache.constructs.web.filter.GzipFilter</filter-class> </filter> <!-- Remove this filter if you're using iBATIS, use OpenEntityManagerInViewFilter if using JPA --> <filter> <filter-name>lazyLoadingFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> <!--<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>--> </filter> <filter> <filter-name>localeFilter</filter-name> <filter-class>org.appfuse.webapp.filter.LocaleFilter</filter-class> </filter> <filter> <filter-name>messageFilter</filter-name> <filter-class>org.appfuse.webapp.filter.MessageFilter</filter-class> </filter> <filter> <filter-name>rewriteFilter</filter-name> <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class> <init-param> <param-name>logLevel</param-name> <param-value>log4j</param-value> </init-param> </filter> <filter> <filter-name>securityFilter</filter-name> <filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class> <init-param> <param-name>targetClass</param-name> <param-value>org.acegisecurity.util.FilterChainProxy</param-value> </init-param> </filter> <filter> <filter-name>sitemesh</filter-name> <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class> </filter> <filter-mapping> <filter-name>ajax4jsf</filter-name> <servlet-name>faces</servlet-name> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> <filter-mapping> <filter-name>trinidad</filter-name> <servlet-name>faces</servlet-name> </filter-mapping> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>securityFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>extensionsFilter</filter-name> <servlet-name>faces</servlet-name> </filter-mapping> <filter-mapping> <filter-name>extensionsFilter</filter-name> <url-pattern>/faces/myFacesExtensionResource/*</url-pattern> </filter-mapping> <!-- Commented out for 2 reasons: 1) it's a pain when developing JSPs, and 2) it causes the Signup webtest to fail --> <!--filter-mapping> <filter-name>cacheFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping--> <filter-mapping> <filter-name>lazyLoadingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- <filter-mapping> <filter-name>clickstreamFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> --> <filter-mapping> <filter-name>localeFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>gzipFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>rewriteFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> <!-- <filter-mapping> <filter-name>sitemesh</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping>--> <filter-mapping> <filter-name>messageFilter</filter-name> <url-pattern>*.html</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> </filter-mapping> <listener> <listener-class>com.opensymphony.clickstream.ClickstreamListener</listener-class> </listener> <listener> <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> <listener> <listener-class>org.appfuse.webapp.listener.StartupListener</listener-class> </listener> <listener> <listener-class>org.appfuse.webapp.listener.UserCounterListener</listener-class> </listener> <listener> <listener-class>net.sf.navigator.menu.MenuContextListener</listener-class> </listener> <servlet> <servlet-name>faces</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <!-- resource loader servlet --> <servlet> <servlet-name>resources</servlet-name> <servlet-class>org.apache.myfaces.trinidad.webapp.ResourceServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>faces</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>resources</servlet-name> <url-pattern>/adf/*</url-pattern> </servlet-mapping> <session-config> <session-timeout>10</session-timeout> </session-config> <security-constraint> <web-resource-collection> <web-resource-name>Protect XHTML Templates</web-resource-name> <url-pattern>*.xhtml</url-pattern> </web-resource-collection> <auth-constraint /> </security-constraint> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <error-page> <error-code>500</error-code> <location>/error.jsp</location> </error-page> <error-page> <error-code>400</error-code> <location>/index.jsp</location> </error-page> <error-page> <error-code>403</error-code> <location>/403.jsp</location> </error-page> <error-page> <error-code>404</error-code> <location>/404.jsp</location> </error-page> </web-app>
 
    