+ Start a Discussion
patrospatros 

ComponentBody re-render is a step behind the rest of the component?

I have a Visualforce component that renders a data table and enables paging for it. The data itself and the fields to display are passed as variables to the component's body so the table layout can be customized (hoping to get re-use out of this).

 

Functionally, everything is working. However, the customized component body is always a "step behind" when paging through the data (ex. look at page 1 then click "next" - page increments, previous button is displayed, but data doesn't update).

 

You can see a live demo of this issue here. In this case, contact records are being retrieved (we have some custom objects to help abstract this for use with any object and any fields on the object).

 

Interestingly, if I take all the markup in the <c:WebTable> component on the Directory page and explicitly put it in the WebTable component (and overwrite the <componentBody> tags), it works fine.

 

All the code is provided below.

 

Thanks!

tom

 

 

WebTable Component (WebTable)

 

 

<apex:component controller="WebTableComponent">
<apex:attribute name="identifier" assignTo="{!identifier}" type="String" description="Unique key used to identify web table for configuration." />

<apex:outputPanel id="webTablePanel">
<apex:outputText value="Page {0}">
<apex:param value="{!currentPage}" />
</apex:outputText>
<apex:componentBody >
<apex:variable var="dataObjects" value="{!dataObjects}" />
<apex:variable var="fields" value="{!fields}" />
</apex:componentBody>
<apex:form >
<apex:commandLink immediate="true" rendered="{!hasPrevious}" action="{!movePrevious}" value="previous" rerender="webTablePanel" />
<apex:outputText value=" | " rendered="{!AND(hasPrevious,hasNext)}" />
<apex:commandLink immediate="true" rendered="{!hasNext}" action="{!moveNext}" value="next" rerender="webTablePanel" />
</apex:form>
</apex:outputPanel>

</apex:component>

 

 

WebTable Component Controller (WebTableComponent)

 

 

public with sharing class WebTableComponent {

public String identifier { get; set; }

public Web_View__c view {
get {
if(view == null) {
view = [select
Id,
Name,
Object_Type__c,
Filter__c,
Order__c,
(select Field_Name__c from Web_View_Fields__r order by Sequence__c asc)
from Web_View__c
where Name = :identifier
];
}
return view;
}
private set;
}

public List<Web_View_Field__c> fields {
get {
return view.Web_View_Fields__r;
}
}

public String query {
get {
String out = 'select Id, ' + fieldNames + ' from ' + view.Object_Type__c;
if(view.Filter__c != null && view.Filter__c.trim() != '') out += ' where ' + view.Filter__c + ' ';
if(view.Order__c != null && view.Order__c.trim() != '') out += ' order by ' + view.Order__c + ' ';
System.debug(out);
return out;
}
}

public ApexPages.StandardSetController setController {
get {
if(setController == null) {
setController = new ApexPages.StandardSetController(Database.getQueryLocator(query));
setController.setPageSize(5);
}
return setController;
}
private set;
}

public String fieldNames {
get {
String out = '';
for(Web_View_Field__c f : fields) {
out += f.Field_Name__c + ',';
}
return out.substring(0, out.length() - 1); // gets rid of the extra comma put in above
}
}

public List<sObject> dataObjects {
get {
return setController.getRecords();
}
}

public Integer currentPage {
get {
return setController.getPageNumber();
}
}

public Integer totalPages {
get {
return setController.getResultSize();
}
}

public Boolean hasPrevious {
get {
return setController.getHasPrevious();
}
}

public Boolean hasNext {
get {
return setController.getHasNext();
}
}

public PageReference moveNext() {
setController.next();
return null;
}

public PageReference movePrevious() {
setController.previous();
return null;
}

public WebTableComponent() {}

}

 

 

Visualforce Page (/Directory)

 

 

<apex:page standardStylesheets="false" showHeader="false" sidebar="false">
<apex:composition template="Container">
<apex:define name="body">
<h1>Directory</h1>
<c:WebTable identifier="My Table" id="MyTable">
<table class="table">
<tr>
<apex:repeat value="{!fields}" var="f">
<th>
<apex:outputText value="{!f.Field_Name__c}" />
</th>
</apex:repeat>
<th>Details</th>
</tr>
<apex:repeat value="{!dataObjects}" var="d">
<tr>
<apex:repeat value="{!fields}" var="f">
<td>
<c:WebTableCell dataObject="{!d}" field="{!f}">
<apex:outputlink rendered="{!field.Field_Name__c == 'Email'}" value="mailto:{!fieldValue}">{!fieldValue}</apex:outputlink>
<apex:outputText rendered="{!NOT(AND(field.Field_Name__c == 'Email'))}" value="{!fieldValue}" />
</c:WebTableCell>
</td>
</apex:repeat>
</tr>
</apex:repeat>
</table>
</c:WebTable>
</apex:define>
</apex:composition>
</apex:page>