7

i have this simple page:

<h:form id="form">

    <p:dataTable value="#{testBean.unitTypeModel}" var="elem" lazy="true" rows="10">
        <p:column headerText="class">#{elem.class.simpleName}</p:column>
        <p:column headerText="code">#{elem.code}</p:column>
        <p:column headerText="description">#{elem.description}</p:column>
        <p:column headerText="action">
            <p:commandButton action="test2" icon="ui-icon ui-icon-wrench" value="edit">
                <f:setPropertyActionListener target="#{testBean.selection}" value="#{elem}"/>
            </p:commandButton>
        </p:column>
    </p:dataTable>

    <p:commandButton action="test2" icon="ui-icon ui-icon-wrench"/>

</h:form>

and the CommandButton inside DataTable is not working, just refreshes page. but the one outside is working.

if i change value and lazy this way:

<h:form id="form">

    <p:dataTable value="#{testBean.unitTypeModel.load(0, 10, null, null, null)}" var="elem" lazy="false" rows="10">
        <p:column headerText="class">#{elem.class.simpleName}</p:column>
        <p:column headerText="code">#{elem.code}</p:column>
        <p:column headerText="description">#{elem.description}</p:column>
        <p:column headerText="action">
            <p:commandButton action="test2" icon="ui-icon ui-icon-wrench" value="edit">
                <f:setPropertyActionListener target="#{testBean.selection}" value="#{elem}"/>
            </p:commandButton>
        </p:column>
    </p:dataTable>

    <p:commandButton action="test2" icon="ui-icon ui-icon-wrench"/>

</h:form>

the CommanButton inside DataTable works like a charm.

someone knows why?

is it a bug?

i'm on

  • Glassfish 3.1.2
  • JSF 2.1.11 (Mojarra)
  • PrimeFaces 3.4-SNAPSHOT
Michele Mariotti
  • 7,372
  • 5
  • 41
  • 73

2 Answers2

7

found out that the lazy datamodel must be the same instance on postback request, even a new instance with the very same values will not work. so it must be provided from at least a @ViewScoped bean.

Michele Mariotti
  • 7,372
  • 5
  • 41
  • 73
  • 1
    This is not entirely true: it is helpful if the same instance of `LazyDataModel` is found in the session by the use of `@ViewScoped`, but you can also use `@RequestScoped`. The point is that the method `isRowAvailable()` must return true when it is evaluated in `APPLY_REQUEST_VALUES` and the field `pageSize` must hold a value greater than zero. I achieved this by extending `LazyDataModel` while overloading two methods: `isRowAvailable()`, here I call `load(...)` and apply the result to `setWrappedData()` and the second method `setRowIndex(int rowIndex)` where I set the `pageSize` to my default – Uwe Voigt Jan 16 '18 at 10:14
4

Four years have passed since this question was posted, but the problem still remains en PrimeFaces 6.0.

I'm going to post a workaround to those who don't want to (or can't) use ViewScoped beans.

The premise is: "you can not place any "ajaxified" item inside a lazy datatable bound to RequestScoped stuff". Never. Keep en mind that anything that throws an ajax call will never work.

So the first step is to take the ajax call outside the datatable. We'll do this using a RemoteComand. You can place this RemoteCommand anywhere outside the DataTable (inside a form, of course)

<p:remoteCommand name="remoteCall" action="#{bean.doStuff()}">
</p:remoteCommand>

Now, all we have to do is to call this RemoteCommand from inside the DataTable. I'm using a link to perform the javascript call, but you could use a button or whatever you like:

<p:column>
    <p:link value="#{item.id}" href="#" onclick="remoteCall([{name:'id', value:#{item.id}}])">
    </p:link>
</p:column>

This link provides a way to call the javascript function "remoteCall" which will perform the ajax call to "bean.doStuff()".

Note that the onClick event contains not only the javascript call to "remoteCall" but it also contains a parameter array with only one param, named "id" with a value "#{item.id}". This will allow the RemoteCommand to send a param named "id" to the backing bean.

Inside the "doStuff" method you'll have to retrieve the "id" parameter value:

public void doStuff () {

    String id = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id");

}
Sergio
  • 179
  • 1
  • 7