Rich listShuttle won't let me select items
funcruiser7 Jun 11, 2008 8:06 AMHello JBoss developers!
I have a serious problem with the listShuttle component. I'm using it exactly like shown in the demo, but I can't select items in both lists to move them to the other list.
I am using RF 3.2.0 SR1 - and can't update to RF 3.2.1 because I'm in the middle of a project right now.
Here is my code.
the XHTML-file:
<!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:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich" xmlns:c="http://java.sun.com/jstl/core" no-conversation-view-id="/main.xhtml" login-view-id="/login.xhtml"> <head> <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8" /> <title> SEAK - Verwaltung </title> <link rel="STYLESHEET" type="text/css" href="${facesContext.externalContext.requestContextPath}/css/common.css" /> </head> <body> <style> .pic{ margin-bottom:-4px; margin-right:2px; } a{ text-decoration:none; color:#{a4jSkin.headerTextColor}; } </style> <rich:panel id="adminPW55MPEdPriv" width="700" height="300" > <f:facet name="header"> <h:outputText value="Rechte-Zuordnungen bearbeiten" /> </f:facet> <div> <h:form> <rich:toolBar id="toolBar" itemSeparator="line" height="28px"> <c:forEach items="#{toolBar.items}" var="item"> <h:panelGroup> <h:graphicImage value="#{item.iconURI}" styleClass="pic"/> <h:outputLink value="#"> <h:outputText value="#{item.label}"></h:outputText> </h:outputLink> </h:panelGroup> </c:forEach> </rich:toolBar> <rich:spacer height="20"></rich:spacer> <rich:listShuttle sourceValue="#{toolBar.freeItems}" targetValue="#{toolBar.items}" var="items" listHeight="300" listWidth="300" sourceCaptionLabel="Available Items" targetCaptionLabel="Currently Active Items" converter="listShuttleconverter"> <rich:column width="18"> <h:graphicImage value="#{items.iconURI}"></h:graphicImage> </rich:column> <rich:column> <h:outputText value="#{items.label}"></h:outputText> </rich:column> <a4j:support event="onlistchanged" reRender="toolBar"/> </rich:listShuttle> </h:form> </div> <h:form> <h:panelGrid id="adminPW56MPEdPriv" columns="1"> <h:outputText value="Ausgewaehlte Gruppe: #{adminBean.tmpRole4Alloc.ident}" /> </h:panelGrid> <rich:listShuttle sourceValue="#{adminBean.allPrivs}" targetValue="#{adminBean.allRolePrivs}" var="items" sourceSelection="#{adminBean.allPrivsSourceSelection}" targetSelection="#{adminBean.allPrivsTargetSelection}" sourceCaptionLabel="Vorhandene Rechte" targetCaptionLabel="Zugewiesene Rechte" switchByClick="true" converter="listShuttleconverterSEAK" showButtonLabels="false" orderControlsVisible="false" fastOrderControlsVisible="false" fastMoveControlsVisible="false" sourceListWidth="350" targetListWidth="350" > <rich:column> <h:outputText value="#{items.description}" /> </rich:column> </rich:listShuttle> <rich:spacer height="30px" /> <rich:spacer width="250px" /> <h:commandButton value="Speichern" action="#{adminBean.modifyRolePriv}" /> <rich:spacer width="30px" /> <h:commandButton value="Abbrechen" action="#{adminBean.invokeAdminPage}" /> </h:form> </rich:panel> <rich:spacer height="20px" /> <rich:panel id="adminStatus"> <h:outputText value="Status: #{adminBean.status}" styleClass="infoMessage" /> </rich:panel> <rich:spacer height="20px" /> <rich:spacer width="200px" /> <h:form> <h:commandButton image="/pages/images/RoterKreisLinksPfeil_klein.png" action="#{adminBean.returnToAdminPage}" /> </h:form> </body> </html>
the faces-config.xml:
<?xml version="1.0"?> <!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN" "http://java.sun.com/dtd/web-facesconfig_1_0.dtd"> <faces-config> <converter> <converter-id>listShuttleconverterSEAK</converter-id> <converter-class>com.as.seak.utils.Converter</converter-class> </converter> <converter> <converter-id>listShuttleconverter</converter-id> <converter-class>com.as.seak.beans.listShuttle.Converter</converter-class> </converter> <managed-bean> <managed-bean-name>toolBar</managed-bean-name> <managed-bean-class>com.as.seak.beans.listShuttle.ToolBar</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>adminBean</managed-bean-name> <managed-bean-class>com.as.seak.beans.AdminBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>adminHandler</managed-bean-name> <managed-bean-class>com.as.seak.handler.AdminHandler</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>loginHandler</managed-bean-name> <managed-bean-class>com.as.seak.handler.LoginHandler</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>messageBean</managed-bean-name> <managed-bean-class>com.as.seak.beans.MessageBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>pollBean</managed-bean-name> <managed-bean-class>com.as.seak.beans.PollBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>privBean</managed-bean-name> <managed-bean-class>com.as.seak.beans.PrivBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>userBean</managed-bean-name> <managed-bean-class>com.as.seak.beans.UserBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <navigation-rule> <description>rules on the priv assignment page</description> <from-view-id>/templates/administrationRolePrivs.xhtml</from-view-id> <navigation-case> <from-outcome>administrationDetails</from-outcome> <to-view-id>/templates/administrationDetails.xhtml</to-view-id> </navigation-case> <navigation-case> <from-outcome>adminPage</from-outcome> <to-view-id>/templates/administrationDetails.xhtml</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <description>rules on the administration page</description> <from-view-id>/templates/administrationDetails.xhtml</from-view-id> <navigation-case> <from-outcome>mainPage</from-outcome> <to-view-id>/templates/main.xhtml</to-view-id> </navigation-case> <navigation-case> <from-outcome>stay</from-outcome> <to-view-id>/templates/administrationDetails.xhtml</to-view-id> </navigation-case> <navigation-case> <from-outcome>administrationRolePrivs</from-outcome> <to-view-id>/templates/administrationRolePrivs.xhtml</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <description>rules on the login change pwd page</description> <from-view-id>/templates/changePasswordLogin.xhtml</from-view-id> <navigation-case> <from-outcome>mainPage</from-outcome> <to-view-id>/templates/main.xhtml</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <description>rules on the login page</description> <from-view-id>/templates/login.xhtml</from-view-id> <navigation-case> <from-outcome>mainPage</from-outcome> <to-view-id>/templates/main.xhtml</to-view-id> </navigation-case> <navigation-case> <from-outcome>stay</from-outcome> <to-view-id>/templates/login.xhtml</to-view-id> </navigation-case> <navigation-case> <from-outcome>changePasswordLogin</from-outcome> <to-view-id>/templates/changePasswordLogin.xhtml</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <description>rules on the main page</description> <from-view-id>/templates/main.xhtml</from-view-id> <navigation-case> <from-outcome>mainPage</from-outcome> <to-view-id>/templates/main.xhtml</to-view-id> </navigation-case> <navigation-case> <from-outcome>stay</from-outcome> <to-view-id>/templates/main.xhtml</to-view-id> </navigation-case> <navigation-case> <from-outcome>adminPage</from-outcome> <to-view-id>/templates/administrationDetails.xhtml</to-view-id> </navigation-case> <navigation-case> <from-outcome>loginPage</from-outcome> <to-view-id>/templates/login.xhtml</to-view-id> </navigation-case> </navigation-rule> <lifecycle> <phase-listener>org.richfaces.treemodeladaptor.PostbackPhaseListener</phase-listener> </lifecycle> </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"> <description>Richfaces Components demo</description> <display-name>richfaces-demo</display-name> <context-param> <param-name>javax.faces.DEFAULT_SUFFIX</param-name> <param-value>.xhtml</param-value> </context-param> <context-param> <param-name>facelets.REFRESH_PERIOD</param-name> <param-value>2</param-value> </context-param> <context-param> <param-name>facelets.DEVELOPMENT</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>server</param-value> </context-param> <context-param> <param-name>com.sun.faces.validateXml</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>com.sun.faces.verifyObjects</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>org.ajax4jsf.SKIN</param-name> <param-value>DEFAULT</param-value> </context-param> <context-param> <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name> <param-value>com.sun.facelets.FaceletViewHandler</param-value> </context-param> <context-param> <param-name>org.ajax4jsf.COMPRESS_SCRIPT</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>org.ajax4jsf.COMPRESS_STYLE</param-name> <param-value>false</param-value> </context-param> <context-param> <param-name>org.ajax4jsf.xmlparser.ORDER</param-name> <param-value>NEKO</param-value> </context-param> <context-param> <param-name>org.richfaces.CONTROL_SKINNING</param-name> <param-value>enable</param-value> </context-param> <context-param> <param-name>org.richfaces.LoadStyleStrategy</param-name> <param-value>ALL</param-value> </context-param> <context-param> <param-name>javax.faces.CONFIG_FILES</param-name> <param-value>/WEB-INF/faces-config.xml</param-value> </context-param> <context-param> <param-name>org.richfaces.LoadScriptStrategy</param-name> <param-value>DEFAULT</param-value> </context-param> <listener> <listener-class>com.as.seak.utils.ServletContextListener</listener-class> </listener> <!-- Hibernate --> <filter> <filter-name>HibernateFilter</filter-name> <filter-class>com.as.seak.utils.HibernateSessionRequestFilter</filter-class> </filter> <filter-mapping> <filter-name>HibernateFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <display-name>Ajax4jsf Filter</display-name> <filter-name>ajax4jsf</filter-name> <filter-class>org.ajax4jsf.Filter</filter-class> <init-param> <param-name>createTempFiles</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>maxRequestSize</param-name> <param-value>100000</param-value> </init-param> </filter> <filter-mapping> <filter-name>ajax4jsf</filter-name> <servlet-name>Faces Servlet</servlet-name> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping> <login-config> <auth-method>BASIC</auth-method> </login-config> </web-app>
com.as.seak.bean.listShuttle.Converter.java:
package com.as.seak.beans.listShuttle; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; public class Converter implements javax.faces.convert.Converter{ public Object getAsObject(FacesContext context, UIComponent component, String value) { int index = value.indexOf(':'); return new ToolBarItem(value.substring(0, index), value.substring(index + 1)); } public String getAsString(FacesContext context, UIComponent component, Object value) { ToolBarItem optionItem = (ToolBarItem) value; return optionItem.getLabel() + ":" + optionItem.getIcon(); } }
the com.as.seak.utils.Converter.java:
package com.as.seak.utils; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import com.as.seak.model.PrivilegDAO; public class Converter implements javax.faces.convert.Converter { public Object getAsObject(FacesContext context, UIComponent component, String value) { int index = value.indexOf(':'); return new PrivilegDAO(value.substring(0, index), value.substring(index + 1)); } public String getAsString(FacesContext context, UIComponent component, Object value) { PrivilegDAO optionItem = (PrivilegDAO) value; return optionItem.getId() + ":" + optionItem.getDescription(); } }
com.as.seak.bean.AdminBean:
public class AdminBean { private List<PrivilegDAO> allPrivs = new ArrayList<PrivilegDAO>(); private List<PrivilegDAO> allRolePrivs = new ArrayList<PrivilegDAO>(); private Set<PrivilegDAO> allPrivsSourceSelection = new HashSet<PrivilegDAO>(); private Set<PrivilegDAO> allPrivsTargetSelection = new HashSet<PrivilegDAO>(); // ... public List<PrivilegDAO> getAllPrivs() { if (allPrivs.size() == 0) { List<Privileg> privs = new ArrayList<Privileg>(); privs = (List<Privileg>) Util.getPrivilegEntries(); for (Iterator iterator = privs.iterator(); iterator.hasNext();) { Privileg privileg = (Privileg) iterator.next(); PrivilegDAO p = new PrivilegDAO(); p.setId(privileg.getId()); p.setDescription(privileg.getDescription()); allPrivs.add(p); } } return allPrivs; } public void setAllPrivs(List<PrivilegDAO> allPrivs) { this.allPrivs = allPrivs; } public List<PrivilegDAO> getAllRolePrivs() { if (allRolePrivs.size() == 0) { allRolePrivs = (List<PrivilegDAO>) Util.getPrivilegDAOEntries(); } return allRolePrivs; } public void setAllRolePrivs(List<PrivilegDAO> allRolePrivs) { this.allRolePrivs = allRolePrivs; } public Set<PrivilegDAO> getAllPrivsSourceSelection() { return allPrivsSourceSelection; } public void setAllPrivsSourceSelection(HashSet<PrivilegDAO> allPrivsSourceSelection) { this.allPrivsSourceSelection = allPrivsSourceSelection; } public Set<PrivilegDAO> getAllPrivsTargetSelection() { return allPrivsTargetSelection; } public void setAllPrivsTargetSelection(HashSet<PrivilegDAO> allPrivsTargetSelection) { this.allPrivsTargetSelection = allPrivsTargetSelection; } }
PrivilegDAO.java:
package com.as.seak.model; public class PrivilegDAO extends Privileg { public boolean equals(Object object) { if (this == object) return true; if (null == object) return false; if (getClass() != object.getClass()) return false; if (object instanceof PrivilegDAO || object instanceof Privileg) { final Privileg other = (Privileg) object; if (null == this.getId()) { if (other.getId() != null) return false; } else if (!this.getId().equals(other.getId())) return false; if (null == this.getDescription()) { if (other.getDescription() != null) return false; } else if (!this.getDescription().equals(other.getDescription())) return false; } return true; } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((this.getId() == null) ? 0 : this.getId().hashCode()); result = prime * result + ((this.getDescription() == null) ? 0 : this.getDescription().hashCode()); return result; } // constructor public PrivilegDAO() { } public PrivilegDAO(String id, String description) { super(); setId(id); setDescription(description); } }
Privileg.java:
package com.as.seak.model; // Generated 11.06.2008 12:30:21 by Hibernate Tools 3.2.0.beta6a /** * Privileg generated by hbm2java */ public class Privileg implements java.io.Serializable { // Fields private String id; private String description; // Constructors /** default constructor */ public Privileg() { } /** minimal constructor */ public Privileg(String id) { this.id = id; } /** full constructor */ public Privileg(String id, String description) { this.id = id; this.description = description; } // Property accessors public String getId() { return this.id; } public void setId(String id) { this.id = id; } public String getDescription() { return this.description; } public void setDescription(String description) { this.description = description; } }
In the XHTML the upper listShuttle is the example from the RichFaces dem, the lower listShuttle is mine.
Both listShuttles are displayed and filled correctly, but in neither case any rows are selectible. I can click into a cell but the row won't be selected.
What can/ must I do to get this work? I'd appreciate quick help!
Kind regards, Peter