14

I have on a page two p:dataTable. The left one is mainly used for selection

<p:dataTable id="leftTable" var="item" value="#{bean.items}"
             selection="#{bean.item}" selectionMode="single">
  <p:ajax event="rowSelect" update=":rightTable" listener="#{bean.select}"/>  
  <p:column>
    <h:outputText value="#{item.value}" />  
  </p:column>
</p:dataTable>

This is fairly simple and works fine. The rightTable is a more complex one, this is a simplified example:

<p:dataTable id="rightTable" var="row" value="#{bean.rows}">
  <p:columns var="col" value="#{bean.cols}">  
    <h:outputText value="#{bean.map[row.id][col.id]}"/>
  </p:columns>
</p:dataTable>

Well, this also works fine. Now I implemented a composite component to replace the leftTable. This component also has selection and select attributes and in general is works, too. The same method like from p:dataTable is called and also the correct item is set.

But, and this is really a nasty thing: If I use my custom component, always the value in the first cell (column 0, row 0) is null. The values are taken from a Map<Long,Map<Long,String>> and I verified that the value for the specific row.id,col.id is set after the method is called.

I'm completely clueless stump with this issue and expect that it's really hard to answer this question and really appreciate if someone can even help me to debug this issue in more detail.

Upate 1: By request I checked the #{row.id},#{col.id}:

95,626 | 95,528
96,527 | 96,528
97,527 | 97,528

In the first cell the col.id is wrong. It should be 527 but is actual 626 (it's the value of the previous request). Why does this happen? How can I get the correct value?

Update 2: This is my component:

<composite:interface componentType="my.MenuDmClick">
  <composite:attribute name="actionListener" required="true"
        method-signature="void listener(javax.faces.event.AjaxBehaviorEvent)"/>
  <composite:attribute name="selection"/>
  <composite:attribute name="update/>
  <composite:attribute name="dm"/>
</composite:interface>
<composite:implementation>
  <ui:repeat var="item" value="#{cc.attrs.dm.wrappedData}">
  <li>
    <p:commandLink actionListener="#{cc.actionListener(item)}"
                   update="#{cc.attrs.update}">
      <h:outputText value="#{item.name}"/>
    </p:commandLink>
  </li>
  </ui:repeat>
</composite:implementation>

And this is the backing bean:

@FacesComponent(value="my.MenuDmClick")
public class MenuDmClick extends UINamingContainer
{
  public void actionListener(Object ejb)
  {
    FacesContext context = FacesContext.getCurrentInstance();
    ValueExpression mSelection = this.getValueExpression("selection");

    if(mSelection!=null){mSelection.setValue(context.getELContext(), ejb);}
    else{throw new PropertyNotFoundException("'selection' must be a ValueExpression!");}

    MethodExpression ajaxEventListener =
         (MethodExpression) getAttributes().get("actionListener");
    ajaxEventListener.invoke(context.getELContext(), new Object[] {});
  }
}
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
Thor
  • 6,607
  • 13
  • 62
  • 96
  • When you use selectable `dataTable` you should provide `rowKey` to some unique property of your model bean, for example it can be `rowKey="#{item.value}"`. Try with this and see what's happening. – partlov Mar 06 '13 at 08:20
  • With the selectable `dataTable` I have no problems. It happens wen I use my own composite:component. The used id's (long) are unique. – Thor Mar 06 '13 at 08:32
  • 1
    Add print of `#{row.id},#{col.id}` near `h:outputText` and see are the values as expected. – partlov Mar 06 '13 at 08:41
  • Great advise. I've done this (see updated question). The _col.id_ is wrong for the first row ... wyhever ... – Thor Mar 06 '13 at 09:31
  • This really seems like the problem might be in the managed bean, `bean`, that contains the values. – le3th4x0rbot Apr 12 '13 at 08:52
  • how do you call this composite component ? – engma Apr 30 '13 at 13:03

1 Answers1

0

After trying the usual stuff like

  • ui:repeat and c:forEach
  • immediate=true/false

I came across process=@this ... and it works like a charm!

<c:forEach var="item" items="#{cc.attrs.dm.wrappedData}">
  <li>
    <p:commandLink process="@this"
        actionListener="#{cc.actionListener(item)}" update="#{cc.attrs.update}">
      <h:outputText value="#{item.round.name}"/>
    </p:commandLink>
  </li>
</c:forEach>
Thor
  • 6,607
  • 13
  • 62
  • 96