Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

update datatable footer primefaces (facet or columnGroup)

I want to make a footer in dataTable and I need to update when the values inside the DT changes.

The problem is that ajax update simply don't occurs.

I've tried two ways:

<p:dataTable 
    id="dataTableAvaliacao" var="aluno"
    value="#{alunoAvaliacaoMB.alunos}">
    <p:column>
        <p:inputText id="inputNota"
            value="#{aluno.getNota(avaliacao.property).vlNotaString}">

            <p:ajax event="change"
                update=":form:dataTableAvaliacao:mediaAluno, :form:dataTableAvaliacao:mediaAvaliacao" />
        </p:inputText>
    </p:column>             

    <p:columnGroup type="footer" id="mediaAvaliacao">

        <p:row>
            <p:column
                 footerText="Nota média da avaliação" />
        </p:row>

        <p:row>
            <ui:repeat value="#{alunoAvaliacaoMB.colunasAvaliacoes}"
                var="avaliacao">
                <p:column id="colunaMedia" 
                    footerText="#{alunoAvaliacaoMB.getMediaAvaliacao(avaliacao.property)}"/>

            </ui:repeat>
        </p:row>                        
    </p:columnGroup>
<p:dataTable>   

The update doesn't occurs...

second way (based on this answer on SO: How to ajax update an item in the footer of a PrimeFaces dataTable?):

<p:remoteCommand name="refreshFooter" update=":form:dataTableAvaliacao:outputMediaAvaliacao"/>
<p:dataTable 
    id="dataTableAvaliacao" var="aluno"
    value="#{alunoAvaliacaoMB.alunos}">

    <p:column>
        <p:inputText id="inputNota"
            value="#{aluno.getNota(avaliacao.property).vlNotaString}">

            <p:ajax event="change"
                update=":form:dataTableAvaliacao:mediaAluno" oncomplete="refreshFooter();" />

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

<f:facet name="footer">
    <h:outputText colspan="1" value="Nota média da avaliação:"/>

    <ui:repeat value="#{alunoAvaliacaoMB.colunasAvaliacoes}"
        var="avaliacao">

        <h:outputText id="outputMediaAvaliacao"
            value="#{alunoAvaliacaoMB.getMediaAvaliacao(avaliacao.property)}" 
    </ui:repeat>
</f:facet>

I've also tried

<p:remoteCommand name="refreshFooter" update=":form:outputMediaAvaliacao"/>

If I put

<p:ajax event="change"
                update=":form:dataTableAvaliacao:mediaAluno, :form:dataTableAvaliacao" />

in the first way, it works, but I don't wanna update all dataTable every time.

What I'm doing wrong? is it a bug?

like image 884
Johnny Willer Avatar asked Aug 13 '15 14:08

Johnny Willer


1 Answers

Referring on 2nd way from your question that you based on this answer...

actually it is possible to update p:dataTable footer (even from within table itself)...but with one modification of your code.

Reason why your implementation does not work is that you did not take into account that <h:outputText id="outputMediaAvaliacao"../> is wrapped with ui:repeat.

In that case, p:remoteCommand is not able to find h:outputText component ID defined in update attribute because that ID does not exist in DOM:

ui:repeat is actually copying h:outputText as many times as list from value attribute is long and appending all parent IDs to newly created native HTML components

<span id="form:dataTableAvaliacao:avaliacao:0:outputMediaAvaliacao">...</span>
<span id="form:dataTableAvaliacao:avaliacao:1:outputMediaAvaliacao">...</span>
<span id="form:dataTableAvaliacao:avaliacao:2:outputMediaAvaliacao">...</span>
...

(you can see the same using DOM inspector of your favorite browser)

SOLUTION

After you learn and understand all facts stated above (like I did :) ), solution is quite simple:

wrap ui:repeat with some parent element and assign ID to parent element. For example like this

<f:facet name="footer">
    <h:outputText value="Nota média da avaliação:"/>

    <h:panelGroup id="footerPanel">
        <ui:repeat value="#{alunoAvaliacaoMB.colunasAvaliacoes}"
                   var="avaliacao" id="avaliacao">
             <h:outputText id="outputMediaAvaliacao" value="#{alunoAvaliacaoMB.getMediaAvaliacao(avaliacao.property)}" />
        </ui:repeat>
     </h:panelGroup>
</f:facet>

and modify p:ajax of p:inputText to update newly created element after text is changed

<p:ajax event="change" update=":form:dataTableAvaliacao:footerPanel" />

On this way all children elements of h:panelGroup will be updated (meaning only footer will be updated and not entire table).

And now, after you solved updating, you can focus on designing of all UI elements under h:panelGroup to make them fit your requirements.

like image 103
Dusan Kovacevic Avatar answered Nov 15 '22 08:11

Dusan Kovacevic