function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
JNicJNic 

One pageBlockTable with multiple sObjects?

Hey all,

 

trying to figure out if there is anywhere out there where someone has made a single pageBlockTable/dataTable (whatever) that combines multiple objects, and uses pagination.

 

Use case would be something like:

a single list of History type happenings that tracks: new files, new notes, maybe a change in field value here and there - all in one quick list rather that multiples...

 

Paginaiton would be great if I could use "standardSet Controler" ( http://www.salesforce.com/us/developer/docs/pages/Content/pages_custom_list_controller.htm )

Best Answer chosen by Admin (Salesforce Developers) 
sfdcfoxsfdcfox

A wrapper class is simply a class used to store the collection of variables you need to render your iterable components. For example, let us say that we wanted a table with contacts and accounts, with the option to check the records (maybe for a mass action):

 

 

public class myController {
  public List<aTableRow> tableRows { get; set; }
  public class aTableRow {
    public Contact theContact { get; set; }
    public Account theAccount { get; set; }
    public Boolean isSelected { get; set; }
    public aTableRow(Contact c,Account a,Boolean b) {
      theContact = c;
      theAccount = a;
      isSelected = b;
    }
  }

  public myController() {
    tableRows = new List<aTableRow>();
    for(Contact c:[select id,firstname,lastname,account.id,account.name from contact limit 10]) {
      tableRows.add(new aTableRow(c,c.account,false));
    }
  }
}

 

 

The page's code would appear something like the following:

 

 

<apex:page controller="myController">
  <apex:form>
    <apex:pageBlock>
      <apex:pageBlockTable value="{!tableRows}" var="row">
        <apex:column><apex:inputCheckbox value="{!row.isSelected}"/></apex:column>
        <apex:column headerValue="Contact First Name"><apex:inputField value="{!row.theContact.firstname}"/></apex:column>
        <apex:column headerValue="Contact Last Name"><apex:inputField value="{!row.theContact.lastname}"/></apex:column>
        <apex:column headerValue="Account Name"><apex:inputField value="{!row.theAccount.name}"/></apex:column>
      </apex:pageBlockTable>
    </apex:pageBlock>
  </apex:form>
</apex:page>

Of course, you'd want to add commandButton or commandLink features to manipulate the records, but this is the proof of concept. Pagination would be accomplished not through a StandardSetController (because it is not a plain SObject), but would be accomplished through the use of one of several methods:

 

 

1) Store all the values in a huge list, and then use the parameters to limit the offset (first) and count (rows), and have commandLink or commandButton actions that increment or decrement first and/or rows to create pagination. The drawback here is a large view state will hinder page performance, and perhaps run into heap allocation errors (a Bad Thing).

 

2) The commandLink or commandButton that implements pagination performs a new query, discarding offset rows of data before adding count items to the list, and discards the rest of the query. The drawback to this design is that users must save between page navigations, and huge queries might take a while to complete.

 

3) Combine 1 and 2 above, perhaps by keeping a "dirty" list in the view state that stores records that were modified/selected/whatever. Your query will still take a finite amount of time, but a smaller view state will help your page's performance considerably.

 

The major consideration for pagination performance is determining what will be the larger bottleneck, namely memory or database queries. It may not actually matter which method you choose if your page will never be that big (for example, under 1000 records).

All Answers

bob_buzzardbob_buzzard

I've used multiple sobjects in datatables utilizing wrapper classes.  The wrapper class combines the various sobjects (and other information) that I want to output, and then the datatable iterates a list of the wrapper class and navigates to the various contained item.

 

While I have introduced pagination into this, I've always rolled my own implementation of it as I need to page through wrapper classes.

JNicJNic

I have little to no experience using wrapper classes... Is there any solid demo / documentation / samples for doing what you propose?

sfdcfoxsfdcfox

A wrapper class is simply a class used to store the collection of variables you need to render your iterable components. For example, let us say that we wanted a table with contacts and accounts, with the option to check the records (maybe for a mass action):

 

 

public class myController {
  public List<aTableRow> tableRows { get; set; }
  public class aTableRow {
    public Contact theContact { get; set; }
    public Account theAccount { get; set; }
    public Boolean isSelected { get; set; }
    public aTableRow(Contact c,Account a,Boolean b) {
      theContact = c;
      theAccount = a;
      isSelected = b;
    }
  }

  public myController() {
    tableRows = new List<aTableRow>();
    for(Contact c:[select id,firstname,lastname,account.id,account.name from contact limit 10]) {
      tableRows.add(new aTableRow(c,c.account,false));
    }
  }
}

 

 

The page's code would appear something like the following:

 

 

<apex:page controller="myController">
  <apex:form>
    <apex:pageBlock>
      <apex:pageBlockTable value="{!tableRows}" var="row">
        <apex:column><apex:inputCheckbox value="{!row.isSelected}"/></apex:column>
        <apex:column headerValue="Contact First Name"><apex:inputField value="{!row.theContact.firstname}"/></apex:column>
        <apex:column headerValue="Contact Last Name"><apex:inputField value="{!row.theContact.lastname}"/></apex:column>
        <apex:column headerValue="Account Name"><apex:inputField value="{!row.theAccount.name}"/></apex:column>
      </apex:pageBlockTable>
    </apex:pageBlock>
  </apex:form>
</apex:page>

Of course, you'd want to add commandButton or commandLink features to manipulate the records, but this is the proof of concept. Pagination would be accomplished not through a StandardSetController (because it is not a plain SObject), but would be accomplished through the use of one of several methods:

 

 

1) Store all the values in a huge list, and then use the parameters to limit the offset (first) and count (rows), and have commandLink or commandButton actions that increment or decrement first and/or rows to create pagination. The drawback here is a large view state will hinder page performance, and perhaps run into heap allocation errors (a Bad Thing).

 

2) The commandLink or commandButton that implements pagination performs a new query, discarding offset rows of data before adding count items to the list, and discards the rest of the query. The drawback to this design is that users must save between page navigations, and huge queries might take a while to complete.

 

3) Combine 1 and 2 above, perhaps by keeping a "dirty" list in the view state that stores records that were modified/selected/whatever. Your query will still take a finite amount of time, but a smaller view state will help your page's performance considerably.

 

The major consideration for pagination performance is determining what will be the larger bottleneck, namely memory or database queries. It may not actually matter which method you choose if your page will never be that big (for example, under 1000 records).

This was selected as the best answer
PaqsPaqs

Put differently, is there a way to chain pageblock tables where one row of a pageblocktable would be another pageblock table (ex: sObject1 master items -> sObject2 details...?

PaqsPaqs

Nevermind, i found the answer to my question here 

jjvdevjjvdev
What is the best method to do what sfdcfox suggest but with PageReference search() results?
Thanks
Benjamin Moore 10Benjamin Moore 10
Thank you so much for this answer sfdcfox, do you know if I will be able to apply these same methods to pagination while viewing tags?