'How to ajax update an item in the footer of a PrimeFaces dataTable?

This is a visual of the table I have:

+---------+------------+-------------------+
| Header1 |  Header2   | Header3           |
+---------+------------+-------------------+
| Row A   |  Input A   | Calc'ed output A  |
| Row B   |  Input B   | Calc'ed output B  |
| etc..   |  etc..     |  etc..            |
+---------+------------+-------------------+
|    Total:          Total calc'ed output  |
+------------------------------------------+

And the stripped-down code:

<p:dataTable id="myTable" value="#{myBean.someList}"
    var="currentItem">

    <p:column headerText="Header1">
        <h:outputText value="#{currentItem.name}" />
    </p:column>

    <p:column headerText="Header2">
        <pe:inputNumber value="#{currentItem.inputVal}">
            <p:ajax event="change" listener="#{myBean.changeListener}"
                update="outputVal outputTotal" />
        </pe:inputNumber>
    </p:column>

    <p:column headerText="Header3">
        <h:outputText id="outputVal" value="#{currentItem.outputVal}" />
    </p:column>

    <f:facet name="footer">
        Total:
        <h:outputText id="outputTotal" value="#{myBean.total}" />
    </f:facet>

</p:dataTable>

The myBean.someList is an ArrayList<SomeOtherBean> with one String and two Integers, with just getters and setters. The myBean.changeListener calculates the second Integer from the first for the given row, and also the total for all rows.

So, when I type in one of the inputs then focus out, the listener is called and the calculation done, but on screen, the value in the third column changes, but the total stubbornly remains zero. I'm fairly sure this has something to do with PrimeFaces appending the row index to the generated id's of each input and output, but I can't figure out how to get to the output in the footer (whose generated id is mainForm:myTable:0:outputTotal).

Now, I could just update the parent table. However whenever the input to receive focus is part of the update target, the focus is lost, and I am under extremely strict accessibility rules that this table must be keyboard friendly (type a number, tab, type a number, tab, etc...)

I have tried:

  • update=":outputTotal" (gave exception Cannot find component with identifier...)
  • update="myTable:0:outputTota (same exception)
  • update="myTable:outputTotal" (no update, total stays zero)
  • wrap the text in a panelGroup and update that (no update)

(PrimeFaces 3.5.0 with MyFaces unknown version)



Solution 1:[1]

Update PrimeFaces

This issue was finally fixed in PrimeFaces 11, or PrimeFaces Elite 8.0.8 / 10.0.1. With PrimeFaces 11+ you can use partialUpdate="false" on the data table. Downside of this fix is that it will also update the headers (and filters), so it might update the filter input for you while you are typing. You could set a delay on the filter event to improve on this, but the effect won't be gone, only less noticeable.

See:

PrimeFaces.ab instead of p:remoteCommand

If you don't want to create p:remoteCommands to update components on a data table filter event (well, I don't), you could use:

<p:ajax event="filter"
        oncomplete="PrimeFaces.ab({source:'#{component.clientId}',process:'@none',update:'componentToUpdate'})"/>

True, this looks a bit messy, but you can create a custom EL function to reduce this to:

<p:ajax event="filter"
        oncomplete="#{my:ajaxUpdate('componentToUpdate')}"/>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1