1 2 Previous Next 17 Replies Latest reply: May 2, 2007 1:17 PM by Igor Shabalov RSS

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

Randy Saborio Newbie

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