rich:dataScroller index refers previous dataTable scroller index inside a4j:repeat - jsf

I am using rich:dataTable inside the a4j:repeat.
Every time the dataTable Scroller refer the index from the previous dataTable scroller index value. So the current dataTable having values but it displays empty table.
Because of,
previous dataTable list size is 200.
previous dataTable scroller index is 7
Current DataTable list size is 5.
<a4j:repeat value="#{Bean.outerTOList}" var="sampleValue">
<rich:dataTable id="dataTable"
var="innerTo"
rows="5"
value="#{sampleValue.sampleInnerTOList}" >
<f:facet name="header">
<rich:column>
<h:outputText value="Header"/>
</rich:column>
</f:facet>
<rich:column>
<h:outputText value="#{innerTo.name}"/>
</rich:column>
<f:facet name="footer">
<rich:datascroller id="dataTableScrollerId"
ajaxSingle="false" maxPages="3"
page="1">
</rich:datascroller>
</f:facet>
</rich:dataTable>
</a4j:repeat>

I think you have to change the <ui:repeat> to a (JSTL) <c:forEach> (see http://www.crazysquirrel.com/computing/java/jsp/jstl-forEach.jspx) because it has another lifecycle and your implementation using ui:repeat won't work in this scenario.
After doing so you probably also need some kind of "discriminator" for your IDs, because you cannot name all table components the same. You would have to use something like id="datatable0",... id="datatable1" and so on. You can use c:forEach's varStatus="status"property to do so. It has a property which you can use as the counter: #{status.index}

Related

How to reset the sorting on dynamic colums at PrimeFaces?

I have dynamic columns which are sorted as well as filtered. I managed to clear the filters, but according to Primefaces there is no function to clear the sorting for the client API.
My .xhtml:
<p:dataTable id="tableId" value="#{statisticCreateBean.tableData}"
var="data" widgetVar="dataTbl"
rendered="#{not empty statisticCreateBean.tableData}">
<p:columns id="columnId" value="#{statisticCreateBean.columnModel}"
var="column" sortBy="#{data[column.fieldName]}"
filterBy="#{data[column.fieldName]}">
<f:facet name="header">
#{column.displayName}
</f:facet>
<h:outputText value="#{data[column.fieldName]}" />
</p:columns>
</p:dataTable>
My Java-code:
Columns columns = (Columns)FacesContext.getCurrentInstance().getViewRoot().findComponent("statisticForm:tableId:columnId");
columns.setSortBy(null);
PrimeFaces.current().executeScript("PF('dataTbl').clearFilters();");
Is there a way to clear the sorting on dynamic columns?
To reset sorts and filters properly get the Datatable and call reset.
DataTable datatable= (DataTable )FacesContext.getCurrentInstance().getViewRoot().findComponent("statisticForm:tableId");
datatable.reset();

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?
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.

How to render a specific row in richfaces 4?

I have the following DataTable in richFaces 4.5.2:
<rich:dataTable id="t" var="v" rows="#{bean.size}"
value="#{bean.value}" rowKeyVar="row">
<rich:column>
<a4j:commandLink action="#{bean.doAction}" render="t:#{row}">
<h:outputText value="#{recipientGroup.id}" />
<f:facet name="footer">
<h:outputText value="#{msgs['dynamicRecipientGroupList.table.id']}"/>
</f:facet>
</rich:column>
</rich:dataTable>
I thought specifying the rowId explicitly force the richFaces to render the only specified row, but It renders the whole table instead. What did I do wrong?
New syntax is described here. (All data iteration components)
In your case it should be something like:
render="t:#rows(row)"

How to render the p:commandButton at last row of the p:datatable?

I need to render the <p:commandButton> at last entry of the <p:datatable> only .
consider if p:datatable having n no.of rows means i have render the p:commandButton at nth row only.
I think that you better use <f:facet name="footer">
<f:facet name="footer">
<p:commandButton/>
</f:facet>
But if you really insist on last row...
Try the rowIndexVar, something like this :
<p:dataTable value="#{myBean.myList}" rowIndexVar="rowIndex" var="item">
<p:column>
<p:commandButton rendered="#{(rowIndex+1) eq myBean.myList.size()}"/>
</p:column>
</p:dataTable>
I don't know if I got the functional requirement right, but from what I understand you want to add a single commandButton at the bottom of the table, for that you might use the following inside datatable tags:
<f:facet name="footer">
<p:commandButton/>
</f:facet>

Generate unique id for h:dataTable in the loop

I am using JSF 2.0. When I am trying to use a variable in the 'id' attribute of the h:dataTable its not taking that variable value.
I have h:dataTable inside ui:repeat with id values as index of ui:repeat as mentioned below.
<ui:repeat var="planMap" value="#{planAccountMap.entrySet().toArray()}" varStatus="planMapStatus">
<h:dataTable id="planTable#{planMapStatus.index}" value="#{planMap.value}" var="accountList">
Does any one know whether we can have dynamic id generated for h:dataTable in loop?
I have a Java script which is making use of table id, but as I am not able to have the unique id for each table in the loop, its breaking.
Any component inside of a repeatable component will always have a dynamic client id. You cannot do this.
Perhaps instead you can assign a unique style class to the dataTable component and use a jQuery selector to return an array of all the dataTable objects in the ui:repeat.
jQuery('.SomeClass');
I do some thing very similar to you. i have a UI:repeat inside a datatable column. tbh, if you check in fire bug, your datatable id would be unique as you put it inside a ui:repaet.
planMap:0:yourdatatableID
This problem can be solve by using datatable inside datatable. Second datatable is kept inside the column of the first datatable as below.
<h:dataTable id="outerTable" value="#{planAccountMap.entrySet().toArray()}" var="planMap" width="100%">
<h:column>
<h:dataTable id="planTable" value="#{planMap.value}" var="accountList"
headerClass="tablehead"
rowClasses="'',altrowcoloropt1"
first="0">
<h:column>
<f:facet name="header">
<h:outputText value="Date" />
</f:facet>
<h:outputText value="#{accountList.date}"/>
</h:column>
<h:column>
<f:facet name="header" >
<h:outputText value="Account Name" />
</f:facet>
<h:outputText value="#{accountList.accountName}"/>
</h:column>
</h:dataTable>
</h:column>
</h:dataTable>
By this you would get unique id as outerTable:0:planTable, outerTable:1:planTable.This even extend the unique id to each element in datatable as outerTable:1:planTable:1:columnid , outerTable:0:planTable:0:columnid

Resources