Primefaces Datatable doesnt update selected rows

19,427

Solution 1

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. E.g.

<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:

Solution 2

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)

Solution 3

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 a p: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.

Share:
19,427

Related videos on Youtube

user489041
Author by

user489041

Updated on September 18, 2022

Comments

  • user489041
    user489041 over 1 year

    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?

  • user489041
    user489041 over 11 years
    Thanks for the response. I have tried you suggestion. Still no luck. I have updated my question to reflect it.
  • BalusC
    BalusC over 11 years
    Uh, "And this only called the setter when a row was clicked" this is exactly that they are supposed to do. Updating the model value once they are (un)selected. Is this not what you ultimately want? "When the user clicks on a row, I would like the selected rows property in the backing bean to be updated" What are you concretely asking here then?
  • user489041
    user489041 over 11 years
    I have tried this in the example above, but it still doesnt seem to work. I am going to try it with a single item instead of an array of selected rows.
  • user489041
    user489041 over 11 years
    Yea, that was a typo, sorry about that, I changed it to getter.
  • BalusC
    BalusC over 11 years
    The getter obviously won't be called here. It would only be called when the view really needs it. Why exactly do you want a specific getter to be called? This should be your least concern in JSF apps as getters (and setters) aren't supposed to perform business logic. What's the concrete functional requirement? Do you have placed some business logic in the getter? What is it supposed to do then?
  • user489041
    user489041 over 11 years
    I dont, I want the setter to be called, not the getter. But when I try the solution with the ajax tags, and click on a row, the getter is called, not the setter.
  • BalusC
    BalusC over 11 years
    Sorry, works fine for me with Mojarra 2.1.14 and PrimeFaces 3.4.1. Your problem is caused elsewhere not visible in the code or information provided so far.
  • user489041
    user489041 over 11 years
    Interesting thanks for your help, ill tinker with it. Ill update when I figure it out.
  • user489041
    user489041 over 11 years
    It appears that my issue was that the datatable was not in a form tag. This along with the ajax tags outlined in the response fixed the issue.
  • BalusC
    BalusC over 11 years
    You're welcome. Sorry, I should have mentioned it, but I assumed it to be obvious enough that you need a form when you want to submit something to the server by POST (as that's just a basic HTML requirement).