rich:extendedDataTable - Selection mess
charriu Sep 14, 2012 9:54 AMHello,
The problem: There is a very large (>3000 elems) list of objects and the user should select one or many of this objects to create a set of this objects.
First attempt: Initially I wanted to use the rich:pickList, on the left side my elems and on the right side the selected ones. Works great, but nobody wants to scroll through 3000 items, so I added a filter function. It consits of an h:inputText and an a4j:commandLink. The large list was filtered in the backend bean and overwrite and re-render the f:selectedItems value of the rich:pickList. Works well, but the right side forgot all selected items :-(
Second attempt: I use two rich:extendedDataTables to make my own "pick list". And than the trouble starts again, selection doesn't work. Here is the code for the table:
<rich:extendedDataTable id="sourceAttr" value="#{manageJourneyEditorBean.sourceAttr}" var="srcAttr" selectionMode="multiple" selection="#{manageJourneyEditorBean.selectionSourceAttr}" rows="10" > <f:ajax event="selectionchange" listener="#{manageJourneyEditorBean.sourceSelection()}" /> <rich:column width="60px"> <f:facet name="header">Code</f:facet> <h:outputText value="#{srcAttr.abbreviation}" /> </rich:column> <rich:column width="auto"> <f:facet name="header">Name</f:facet> <h:outputText value="#{srcAttr.name}" /> </rich:column> <!-- pagination on bottom --> <f:facet name="footer"> <rich:dataScroller id="dataScrollerSrc" for="sourceAttr" maxPages="5" /> </f:facet> </rich:extendedDataTable>
I tried either the a4j:support, but no other result. I get into my method sourceSelection and the selectionSourceAttr (List<Integer>) contains the positions of the selected elements. Okay, I manged to make a list of Attributes of this named selectedSourAttr (List<Attribute>) and it works. Now I got the selected elements and want to move them to the other table, there for I have a4j:commandLinks:
<h:panelGrid columns="1" id="shuttleButtons" styleClass="shuttleButtons"> <a4j:commandButton value=">>" actionListener="#{manageJourneyEditorBean.all2Target()}" render=":sourceAttr, : targetAttrT" /> <a4j:commandButton value=">" actionListener="#{manageJourneyEditorBean.selection2Target()}" render=":sourceAttr, : targetAttrT" /> <a4j:commandButton value="<" actionListener="#{manageJourneyEditorBean.selection2Source()}" render=":sourceAttr, : targetAttrT" /> <a4j:commandButton value="<<" actionListener="#{manageJourneyEditorBean.all2Source()}" render=":sourceAttr, : targetAttrT" /> </h:panelGrid>
When I click one of this links, I get an exception and I have no idea where this came from:
Warnung: String index out of range: 0 java.lang.StringIndexOutOfBoundsException: String index out of range: 0 at java.lang.String.charAt(String.java:695) at org.richfaces.context.ComponentIdResolver.isAbsolute(ComponentIdResolver.java:256) at org.richfaces.context.ComponentIdResolver.buildInversedFilteredTreeRecursively(ComponentIdResolver.java:264) at org.richfaces.context.ComponentIdResolver.resolve(ComponentIdResolver.java:522) at org.richfaces.renderkit.util.CoreRendererUtils.findComponentsFor(CoreRendererUtils.java:140) at org.richfaces.context.RenderComponentCallback.doVisit(RenderComponentCallback.java:86) at org.richfaces.context.ExecuteComponentCallback.doVisit(ExecuteComponentCallback.java:47) at org.richfaces.context.ComponentCallback.visit(ComponentCallback.java:94) at org.richfaces.context.BaseExtendedVisitContext.invokeVisitCallback(BaseExtendedVisitContext.java:321) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1612) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) at javax.faces.component.UIForm.visitTree(UIForm.java:371) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1623) at org.richfaces.context.ExtendedPartialViewContextImpl.visitActivatorComponent(ExtendedPartialViewContextImpl.java:440) at org.richfaces.context.ExtendedPartialViewContextImpl.visitActivatorAtExecute(ExtendedPartialViewContextImpl.java:310) at org.richfaces.context.ExtendedPartialViewContextImpl.getExecuteIds(ExtendedPartialViewContextImpl.java:98) at org.richfaces.context.ExtendedPartialViewContextImpl.isExecuteAll(ExtendedPartialViewContextImpl.java:148) at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:929) at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:643) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:450) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131) at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:524) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1067) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:377) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:192) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1001) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129) at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:250) at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:149) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:111) at org.eclipse.jetty.server.Server.handle(Server.java:360) at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:454) at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:900) at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:954) at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:851) at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235) at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:77) at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:622) at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:46) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:603) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:538) at java.lang.Thread.run(Thread.java:722)
Here is the java code:
public class ManageJourneyEditorBean { private List<Attribute> sourceAttr; private List<Attribute> targetAttr; private List<Integer> selectionSourceAttr; private List<Attribute> selectedSourceAttr; private List<Integer> selectionTargetAttr; private List<Attribute> selectedTargetAttr; public void sourceSelection() { selectedSourceAttr.clear(); for (Integer posElem : selectionSourceAttr) { selectedSourceAttr.add(sourceAttr.get(posElem)); } } public void targetSelection() { selectedTargetAttr.clear(); for (Integer posElem : selectionTargetAttr) { selectedTargetAttr.add(targetAttr.get(posElem)); } } public void all2Target() { targetAttr.addAll(sourceAttr); sourceAttr.clear(); } public void selection2Target() { List<Attribute> toRemoveFromSource = new ArrayList<Attribute>(); for (Integer item : selectionSourceAttr) { Attribute a = sourceAttr.get(item); targetAttr.add(a); } sourceAttr.removeAll(toRemoveFromSource); selectionSourceAttr.clear(); } public void all2Source() { sourceAttr.addAll(targetAttr); targetAttr.clear(); } public void selection2Source() { sourceAttr.addAll(selectedTargetAttr); targetAttr.removeAll(selectedTargetAttr); selectedTargetAttr.clear(); } /* * All the setters and getters */
Thank your for listening,
Felix