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