1 2 Previous Next 17 Replies Latest reply on May 2, 2007 1:17 PM by ishabalov

    reRender in <a4j:commandLink> NOT WORKING, generated 'affect

    rhinox

      Hi,

      I have the following:

      Ajax4jsf 1.1.0
      Apache Tomahawk 1.1.3
      Facelets 1.1.11
      JSF RI 1.2_04-b10-p01
      Sun App Server 9.1 (build b33e-beta)

      test.xhtml

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:t="http://myfaces.apache.org/tomahawk"
       xmlns:a4j="https://ajax4jsf.dev.java.net/ajax">
      <f:view>
       <t:document>
       <t:documentHead>
       <meta http-equiv="content-type" content="text/xhtml; charset=utf-8; pageEncoding=utf-8"/>
       <meta http-equiv="pragma" content="no-cache"/>
       <meta http-equiv="cache-control" content="no-cache"/>
       <meta http-equiv="expires" content="0"/>
       <title>Test</title>
       </t:documentHead>
       <t:documentBody>
       <a4j:form>
       <a4j:region>
       <div style="height: 300px; overflow: auto; border: 1px solid red">
       <a4j:log level="ALL" popup="false" width="400" height="200"/>
       </div>
      
       <a4j:outputPanel id="data">
       <t:dataList id="groups" var="group" value="#{bean.groups}">
       <t:div id="group">
       <h:outputText value="Group Name"/>
       <t:div>
       <h:outputText value="#{group.name}"/>
       <a4j:commandLink action="#{bean.delete}" value="delete group" immediate="true" reRender="data" limitToList="true">
       <!--<a4j:ajaxListener type="org.ajax4jsf.ajax.ForceRender"/>-->
       <f:param name="id" value="#{group.id}"/>
       </a4j:commandLink>
       </t:div>
      
       <t:dataList id="item" var="item" value="#{group.items}">
       <t:div>
       <h:outputText value="#{item.name}"/>
       <a4j:commandLink action="#{bean.delete}" value="delete" immediate="true" reRender="data" limitToList="true">
       <f:param name="id" value="#{item.id}"/>
       </a4j:commandLink>
       </t:div>
       </t:dataList>
      
       </t:div>
       </t:dataList>
       </a4j:outputPanel>
      
       </a4j:region>
       </a4j:form>
      
       </t:documentBody>
       </t:document>
      </f:view>
      </html>
      


      Bean.java
      package com.test.jsf;
      
      import javax.faces.context.*;
      import java.util.*;
      
      public final class Bean {
       private List<Group> groups;
      // private DataModel dataModel;
      
       public Bean() {
      // dataModel = new ListDataModel();
       groups = new ArrayList<Group>();
      
       Group group = new Group(1, "Group 1");
       group.addItem(new Item(group, 1, "Item 1"));
       group.addItem(new Item(group, 2, "Item 2"));
       group.addItem(new Item(group, 3, "Item 3"));
       groups.add(group);
      
       group = new Group(2, "Group 2");
       group.addItem(new Item(group, 4, "Item 4"));
       group.addItem(new Item(group, 5, "Item 5"));
       group.addItem(new Item(group, 6, "Item 6"));
       groups.add(group);
      
       group = new Group(3, "Group 3");
       group.addItem(new Item(group, 7, "Item 7"));
       group.addItem(new Item(group, 8, "Item 8"));
       group.addItem(new Item(group, 9, "Item 9"));
       groups.add(group);
       }
      
      // public DataModel getGroups() {
      // dataModel = new ListDataModel(groups);
      // return dataModel;
      // }
      
       public List<Group> getGroups() {
       return groups;
       }
      
       public String delete() {
       FacesContext facesContext = FacesContext.getCurrentInstance();
       ExternalContext externalContext = facesContext.getExternalContext();
       Item item = (Item) externalContext.getRequestMap().get("item");
       if (item != null)
       item.getGroup().removeItem(item);
       return null;
       }
      
       public String deleteGroup() {
       FacesContext facesContext = FacesContext.getCurrentInstance();
       ExternalContext externalContext = facesContext.getExternalContext();
       Group group = (Group) externalContext.getRequestMap().get("group");
       if (group != null)
       groups.remove(group);
       return null;
       }
      }
      


      Group.java
      package com.test.jsf;
      
      import javax.faces.model.*;
      import java.util.*;
      
      public final class Group {
       private int id;
       private String name;
       private List<Item> items;
      // private DataModel dataModel;
      
       public Group(int id, String name) {
       this.id = id;
       this.name = name;
       items = new ArrayList<Item>();
       }
      
       public int getId() {
       return id;
       }
      
       public void setId(int id) {
       this.id = id;
       }
      
       public String getName() {
       return name;
       }
      
       public void setName(String name) {
       this.name = name;
       }
      
      // public DataModel getItems() {
      // dataModel = new ListDataModel(items);
      // return dataModel;
      // }
      
       public List<Item> getItems() {
       return items;
       }
      
       public void addItem(Item item) {
       items.add(item);
       }
      
       public void removeItem(Item item) {
       items.remove(item);
       }
      }
      


      Item.java
      package com.test.jsf;
      
      public final class Item {
       private int id;
       private String name;
       private Group group;
      
       public Item() {
       }
      
       public Item(Group group, int id, String name) {
       this.group = group;
       this.id = id;
       this.name = name;
       }
      
       public int getId() {
       return id;
       }
      
       public void setId(int id) {
       this.id = id;
       }
      
       public String getName() {
       return name;
       }
      
       public void setName(String name) {
       this.name = name;
       }
      
       public Group getGroup() {
       return group;
       }
      }
      


      faces-config.xml
      <?xml version='1.0' encoding='UTF-8'?>
      <faces-config 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-facesconfig_1_2.xsd"
       version="1.2">
       <managed-bean>
       <managed-bean-name>bean</managed-bean-name>
       <managed-bean-class>com.test.jsf.Bean</managed-bean-class>
       <managed-bean-scope>session</managed-bean-scope>
       </managed-bean>
      </faces-config>
      


      web.xml
      <?xml version="1.0" encoding="UTF-8"?>
      <web-app 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_2_5.xsd"
       version="2.5">
      
       <description>Test</description>
       <display-name>Test</display-name>
      
       <!-- Facelets ViewHandler -->
       <context-param>
       <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
       <param-value>com.sun.facelets.FaceletViewHandler</param-value>
       </context-param>
      
       <!-- Custom Libraries -->
       <context-param>
       <param-name>facelets.LIBRARIES</param-name>
       <param-value>/WEB-INF/facelets/tags/tomahawk.taglib.xml</param-value>
       </context-param>
      
       <!-- Use Documents Saved as *.xhtml -->
       <context-param>
       <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
       <param-value>.xhtml</param-value>
       </context-param>
      
       <!-- Special Debug Output for Development -->
       <context-param>
       <param-name>facelets.DEVELOPMENT</param-name>
       <param-value>true</param-value>
       </context-param>
      
       <!-- Optional JSF-RI Parameters to Help Debug -->
       <context-param>
       <param-name>com.sun.faces.verifyObjects</param-name>
       <param-value>true</param-value>
       </context-param>
       <context-param>
       <param-name>com.sun.faces.validateXml</param-name>
       <param-value>true</param-value>
       </context-param>
      
       <!-- State Saving Method -->
       <context-param>
       <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
       <param-value>server</param-value>
       </context-param>
      
       <!-- Apache MyFaces Tunning -->
       <context-param>
       <param-name>org.apache.myfaces.ADD_RESOURCE_CLASS</param-name>
       <param-value>org.apache.myfaces.component.html.util.StreamingAddResource</param-value>
       </context-param>
       <context-param>
       <param-name>org.apache.myfaces.COMPRESS_STATE_IN_SESSION</param-name>
       <param-value>false</param-value>
       </context-param>
       <context-param>
       <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
       <param-value>false</param-value>
       </context-param>
       <context-param>
       <description>Only applicable if state saving method is "server" (= default).
       Defines the amount (default = 20) of the latest views are stored in session.
       </description>
       <param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name>
       <param-value>20</param-value>
       </context-param>
      
       <!-- Ajax4jsf Filter -->
       <filter>
       <display-name>Ajax4jsf Filter</display-name>
       <filter-name>ajax4jsf</filter-name>
       <filter-class>org.ajax4jsf.Filter</filter-class>
       </filter>
       <filter-mapping>
       <filter-name>ajax4jsf</filter-name>
       <servlet-name>Faces Servlet</servlet-name>
       <dispatcher>REQUEST</dispatcher>
       <dispatcher>FORWARD</dispatcher>
       <dispatcher>INCLUDE</dispatcher>
       </filter-mapping>
      
       <!--Apache MyFaces Extension Filter (Tomahawk requirement) -->
       <filter>
       <filter-name>MyFacesExtensionsFilter</filter-name>
       <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
       <init-param>
       <param-name>maxFileSize</param-name>
       <param-value>20m</param-value>
       </init-param>
       </filter>
       <!--extension mapping for adding <script/>, <link/>, and other resource tags to JSF-pages -->
       <filter-mapping>
       <filter-name>MyFacesExtensionsFilter</filter-name>
       <!--servlet-name must match the name of your javax.faces.webapp.FacesServlet entry -->
       <servlet-name>Faces Servlet</servlet-name>
       </filter-mapping>
       <!--extension mapping for serving page-independent resources (javascript, stylesheets, images, etc.) -->
       <filter-mapping>
       <filter-name>MyFacesExtensionsFilter</filter-name>
       <url-pattern>/faces/myFacesExtensionResource/*</url-pattern>
       </filter-mapping>
       <!--extension mapping for adding <script/>, <link/>, and other resource tags to JSF-pages -->
       <filter-mapping>
       <filter-name>MyFacesExtensionsFilter</filter-name>
       <url-pattern>*.faces</url-pattern>
       </filter-mapping>
      
       <!-- Faces Servlet -->
       <servlet>
       <servlet-name>Faces Servlet</servlet-name>
       <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
       <load-on-startup>1</load-on-startup>
       </servlet>
       <!-- Faces Servlet Mapping -->
       <servlet-mapping>
       <servlet-name>Faces Servlet</servlet-name>
       <url-pattern>*.faces</url-pattern>
       </servlet-mapping>
      </web-app>
      


      The problem is when I click on any of the a4j:commandLinks the AJAX response searches for a 'data' node id instead of a 'xxx:data' so no update occurs (the 'affected' attribute is ALWAYS generated without the parent UIComponent prefix unless the commandLink is NOT inside a dataList). I think this is an ajax4jsf bug cause if the commandLink is out of the dataList object the 'affected' property points correctly to 'xxxx:data'.

      I've try all possible 'solutions': a4j:ajaxListener with force render, dataTable instead of dataList, a4j:repeat instead of dataList, a4j:outputPanel, reRender='groups' instead of 'data', everything!. The only way I get the data component updated is setting its ajaxRendered property to true but this is out of the question, I can't do that cause I have several a4j:outputPanel on the same page and I want to update independently, not all at once each time a commandLink is executed.

      Please HELP!

      Thanks

        1 2 Previous Next