简体   繁体   中英

Primefaces Datatable doesnt update selected rows

I have a simple problem. I have a Primefaces Datatable. When the user clicks on a row, I would like the selected rows property in the backing bean to be updated. This can be achieved if the form that the Datatable is in is submitted, but I would like it to happen asynchronously. Ive read the various questions on here about this question, but still have not been able to find a solution.

Here is a small example to demonstrate the issue :

Test JSF Page:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:p="http://primefaces.org/ui">
<h:head>
    <title>Facelet Title</title>
</h:head>
<h:body>
    <p:dataTable var="v" value="#{test.values}" selectionMode="multiple"
                 selection="#{test.selectedValue}" rowKey="#{v.value}" >
        <p:column headerText="Test">
            <h:outputText value="#{v.value}" />
        </p:column>
    </p:dataTable>
</h:body>

Backing Bean:

import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.component.menuitem.MenuItem;
import org.primefaces.component.stack.Stack;

@ManagedBean
@ViewScoped
public class Test 
{

    private Value[] selectedValues;

    public List<Value> getValues()
    {
        List<Value> retVal = new ArrayList<Value>();
        retVal.add(new Value("a"));
        retVal.add(new Value("b"));
        return retVal;
    }

    public Value[] getSelectedValues() {
        return selectedValues;
    }

    public void setSelectedValues(Value[] selectedValues) {
        this.selectedValues = selectedValues;
    }
}

And a simple POJO that they use:

public class Value {

    private String value;
    public Value(String value)
    {
        this.value = value;
    }

    public String getValue()
    {
        return value;
    }

    public void setValue(String value)
    {
        this.value = value;
    }
}

As per the responses, I have update the Datatable like so:

    <p:dataTable id="dt" var="v" value="#{test.values}" selectionMode="multiple"
                 selection="#{test.selectedValues}" rowKey="#{v.value}" >
        <p:column headerText="Test">
            <h:outputText value="#{v.value}" />
        </p:column>
        <p:ajax event="rowSelect"/>
        <p:ajax event="rowUnselect" />
    </p:dataTable>

This however still fails to call the setter setSelectedValues(); I made them also say:

    <p:ajax event="rowSelect" update="@this" />
    <p:ajax event="rowUnselect" update="@this" />

And this only called the getter when a row was clicked. Any ideas?

You can use the rowSelect event for it in <p:ajax> .

<p:dataTable ...>
    ...
    <p:ajax event="rowSelect" />
</p:dataTable>

This makes however very little sense in this context. It'd have made more sense if you'd like to hook a listener or an update attribute on that as well. Eg

<p:dataTable ...>
    ...
    <p:ajax event="rowSelect" update="menu" />
</p:dataTable>

If you'd like to hook on unselecting of rows as well, add another one which hooks on rowUnselect :

<p:dataTable ...>
    ...
    <p:ajax event="rowSelect" />
    <p:ajax event="rowUnselect" />
</p:dataTable>

See also:

Just add <p:ajax event="rowSelect" /> inside your datatable

<p:dataTable selection="#{customerView.selectedEntity}" selectionMode="single">
    <p:ajax event="rowSelect" />
<!--more code-->
</p:dataTable>

This will call setSelectedEntity() in your backing bean, so you have it set when the actionListener fires

This is useful if you want to call an actionListener from outside the datatable form (which won't submit the value)

I believe your statement "Works when submitting the form" is the solution.

I had a similar problem where my page has multiple panels, the first panel is a list of people, once someone is selected the details are loaded in the following panels.

So my rowSelect listener was firing but my bean always had null for my selection. FYI, my rowSelect Listener updates ap:outputPanel which wraps my detail panels. My detail panels are only rendered when the selection is not null.

I just wrapped the datatable with an h:form and everything started to work, just by selecting a row.

Now I used Spring, Session Scoped Component for my bean to house the data list and selection and Spring singleton Component for my controller for the rowSelect operation. But it should still work for your example.

<p:column headerText="Test">
    <h:outputText value="#{v.value}" />
</p:column>

Remove the h:outputText tag, use as follows

<p:column headerText="Test">
    #{v.value}
</p:column>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM