Weird behavior of JSF p:dataTable (first entry wrong in p:columns)
Asked Answered
C

1

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[] {});
  }
}
Caelum answered 6/3, 2013 at 7:46 Comment(6)
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.Scandalize
With the selectable dataTable I have no problems. It happens wen I use my own composite:component. The used id's (long) are unique.Caelum
Add print of #{row.id},#{col.id} near h:outputText and see are the values as expected.Scandalize
Great advise. I've done this (see updated question). The col.id is wrong for the first row ... wyhever ...Caelum
This really seems like the problem might be in the managed bean, bean, that contains the values.Chastity
how do you call this composite component ?Moneylender
C
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>
Caelum answered 7/6, 2013 at 6:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.