Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
970 views
in Technique[技术] by (71.8m points)

jsf - 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)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can't really update the values of the table from within the table. However, you can use p:remoteCommand to achieve this. Also, I would probably use the cellEdit event on the whole table (instead of a single p:ajax on your pe:inputNumber). The overall result would be:

<p:remoteCommand name="refreshFooter" update=":formName:outputTotal"/>
...
<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}" process="@this"
                oncomplete="refreshFooter();" update="outputVal"/>
        </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>

Please note that you might need to add partialSubmit="true" to the p:ajax, this way you only submit the component's data. If you like the cellEdit event idea, you need to make the dataTable editable, and add the following in your p:dataTable, and get rid of the p:ajax inside your pe:inputNumber

<p:ajax event="cellEdit" partialSubmit="true" listener="#{myBean.onCellEdit}" 
    process="@this" oncomplete="refreshFooter();"/>

Good luck!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...