1

I have a problem with primefaces datatables. I have one datatable with some entries and a column with a button inside. If the button is pressed a popup is opened with another datatable. The entries in the second datatable are depending on the row in which the button is pressed.

<!-- first datatable -->
<h:form id="list">
<p:dataTable id="list1" var="item" value="#{bean1.itemlist}"
   rowKey="#{item.id}" selection="#{bean1.selectedItem}"
   selectionMode="single">

    <p:column headerText="ID">
        <h:outputText value="#{item.id}" />
    </p:column>
    ...
    <p:column headerText="Edit Entries">
        <p:commandButton value="Edit Entries"
            actionListener="#{bean2.updateEntries(item)}" ajax="true"
            oncomplete="PF('edit_entries').show()" />

         </p:column>
</p:dataTable>

<!-- Second datatable in the popup -->
<p:dialog header="Edit Entries" widgetVar="edit_entries" modal="true"
    resizable="false">
        <p:dataTable id="list2" var="entry"
            value="#{bean2.entriesList}" rowKey="#{entry.id}"
            selection="#{bean2.selectedEntry}" selectionMode="single">
            <p:column headerText="Entry Number">
                <h:outputText value="#{entry.number}" />
            </p:column>
        </p:dataTable>
        <f:facet name="footer">
             <p:commandButton value="Save" oncomplete="PF('edit_entries').hide()" />
        </f:facet>
</p:dialog>
</form>

Bean2

public void updateEntries(Item selectedItem) {
    this.entriesList = this.entriesQuery.getAllEntriesByItemID(selectedItem.getId());//db query could take some time
    System.out.println("entrieslist size: " + this.entriesList.size()); //prints the correct size
}

The problem is that there are no entries listed in the popup datatable although there are some in the list after the db query.

Any ideas how to fix this bug? Thanks in advance!

UPDATE 1:

<!-- first datatable -->
<h:form id="list">
<p:dataTable id="list1" var="item" value="#{bean1.itemlist}"
   rowKey="#{item.id}" selection="#{bean1.selectedItem}"
   selectionMode="single">

    <p:column headerText="ID">
        <h:outputText value="#{item.id}" />
    </p:column>
    ...
    <p:column headerText="Edit Entries">
        <p:commandButton value="Edit Entries" update=":dialogUpdateEntries"
            actionListener="#{bean2.updateEntries(item)}" ajax="true"
            oncomplete="PF('edit_entries').show()" />

         </p:column>
</p:dataTable>
</h:form>

<!-- Second datatable in the popup -->
<p:dialog header="Edit Enries" id="dialogUpdateEntries" widgetVar="edit_entries" modal="true"
    resizable="false">
    <h:form id="formEntriesList">
        <p:dataTable id="list2" var="entry"
            value="#{bean2.entriesList}" rowKey="#{entry.id}"
            selection="#{bean2.selectedEntry}" selectionMode="single">
            <p:column headerText="Entry Number">
                <h:outputText value="#{entry.number}" />
            </p:column>
        </p:dataTable>
        <f:facet name="footer">
             <p:commandButton value="Save" oncomplete="PF('edit_entries').hide()" />
        </f:facet>
    </form>
</p:dialog>
mbauer
  • 308
  • 1
  • 5
  • 20
  • You're not supposed to change the question in such way that the answers become incompatible with it. – BalusC Jan 06 '15 at 20:30

2 Answers2

3

You're indeed not updating the data table in the dialog. JSF doesn't automatically update the view on change of the model, you have to explicitly tell the view to do so. You can use the ajax action component's update attribute for this. This takes a JSF client ID which can be found by rules as outlined in this related answer: How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar".

Given the markup as shown in the question, that'll be

<p:commandButton ... update=":list:list2" />

However, there's another potential problem. You're using <p:dialog modal="true"> inside a form instead of giving the dialog its own form. This way the dialog may not be available in the HTML DOM tree as JavaScript (the one responsible for dealing with ajax stuff) would expect to find it. Giving the dialog its own form should fix this matter. It'll also fix the potential future problems with invoking actions from inside the dialog as handled in this related question: <p:commandbutton> action doesn't work inside <p:dialog>.

<h:form id="viewForm">
    ...
    <p:commandButton ... update=":editDialog" />
    ...
</h:form>

<p:dialog id="editDialog" modal="true">
    <h:form id="editForm">
        ...
    </h:form>
</p:dialog>
Community
  • 1
  • 1
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • Then the problem is somewhere else not visible in the information provided so far. To start, it would be helpful if you tell (or show if you can't) the HTTP request payload and the HTTP response body contents. – BalusC Jan 06 '15 at 20:28
  • I've pressed the commandButton and that's what was transfered: http://pastebin.com/BrZirR2A I hope you can find something because the variable names are different – mbauer Jan 06 '15 at 20:45
  • The ajax update is working fine. It's only that `#{bean2.entriesList}` is apparently empty. – BalusC Jan 06 '15 at 20:47
  • so it's a problem with the timing? because the System.out in the updateEntries() shows the correct size of the list which was queried from the db. – mbauer Jan 06 '15 at 20:53
  • Nope. The timing is fine. It's apparently not the same list (anymore). Just put a debug watch point on the proprety or a debug breakpoint on the getter/setter to see if it gets changed by something else after the ajax action was invoked. – BalusC Jan 06 '15 at 20:54
  • ok when calling the updateEntried() then the list has some entries and when the getter is called the list is empty again :S – mbauer Jan 06 '15 at 21:21
  • 1
    Apparently the bean is reconstructed on every EL evaluation. Perhaps the managed bean scope is missing or wrong? This symptom namely matches a `@Named` without a valid scope. – BalusC Jan 06 '15 at 21:22
  • I used `@Named` and the bean was also listed in the `faces-config.xml`. Now I just replaced the `@Named` with `@Managed` and it worked. Thanks a lot! – mbauer Jan 06 '15 at 21:38
  • Bean registration in `faces-config.xml` should not be necessary in JSF 2.x. This is a leftover from JSF 1.x. You should be able to use `@Named`, you only have to make sure that you import the right scope, e.g. `@javax.faces.view.ViewScoped` and thus not `@javax.faces.bean.ViewScoped`. – BalusC Jan 06 '15 at 21:42
0

Try adding update="list2" to Edit Entries command button (even update="@widgetVar(edit_entries)" should work).

If, because of page layout and structure, you can't target the second datatable using above suggestions, then add styleClass="tList2" to second table, and update it with update="@(.tList2)" on edit button.

Predrag Maric
  • 21,996
  • 4
  • 45
  • 64