0

I am using a Controller Extension to add Contacts to an sObject. My requirements are Wrapper, Pagination Limit 5000 and Dynamic Search.

My code is compiling fine. I have the Wrapper and the function of "inserting records into sObject" working, however, Pagination is simply not advancing through the pages.

I have also included images of my View State for both my code and CCW code.

I am referencing the following code:

Wrapper:
URL://developer.salesforce.com/page/Wrapper_Class

Pagination:
URL://cloudclickware.wordpress.com/2013/12/02/list-pagination-of-a-large-record-set-with-record-selection/

Thank you in advance for any direction you can provide!

ControllerExtension:

public class SelectTacosControllerExtension {

//default page size
private static final Integer PAGE_SIZE = 20;

//pagination information
public Integer page{get;set;}
public Integer totalRecords{get;set;}  // this number not showing
public Integer totalPages{get;set;}
public Integer startIdx{get;set;}   // this number not showing number 1
public Integer endIdx{get;set;}

//Controller for Outreach Visit sObject
private final Encounter__c visit;

public Id EncounterId { get; set; }

//Our collection of the class/wrapper objects cContact
public List<cBuba> contactList {get; set;}


// The extension constructor initializes the private member
// variable visit by using the getRecord method from the standard
// controller.
public SelectTacosControllerExtension(ApexPages.StandardController stdController) {
    this.visit = (Encounter__c)stdController.getRecord();

    //set initial page
    this.page = 1;

    //load records
    getTacos();

}

public void doNext(){

    if(getHasNext()){
        this.page++;
        getTacos();
    }
}

public void doPrevious(){

    if(getHasPrevious()){
        this.page--;
        getTacos();
    }              
}

public Boolean getHasPrevious(){
    if(this.page>1){
        return true;
    }
    else{
        return false;
    }
}

public Boolean getHasNext(){
    if(this.page<this.totalPages){
        return true;
    }
    else{
        return false;
    }
}


//This method uses a simple SOQL query to return a List of Contacts
public List<cBuba> getTacos() {

    //calculate range of records for capture
        this.startIdx = (this.page-1)*PAGE_SIZE;
        this.endIdx = this.page*PAGE_SIZE;

    if(contactList == null) {

        contactList = new List<cBuba>();

        this.totalRecords = 0;

        //clear container for records displayed
        this.contactList.clear();

        for(Contact c: [SELECT Id, Name, account.name, account.visn__c, Sta3n__c, Station_Name__c, ProviderClass__c, Title, AUD_Priority_Provider__c FROM contact ORDER BY name LIMIT 50000]) {

           //capture records within the target range
            if(this.totalRecords>=this.startIdx && this.totalRecords<this.endIdx){   

           // As each contact is processed we create a new cBuba object and add it to the contactList
              this.contactList.add(new cBuba(c));

            }   

            //count the total number of records
            this.totalRecords++;   
        }    

        //calculate total pages
        Decimal pages = Decimal.valueOf(this.totalRecords);
        pages = pages.divide(Decimal.valueOf(PAGE_SIZE), 2);
        this.totalPages = (Integer)pages.round(System.RoundingMode.CEILING);


   }

       //adjust start index e.g. 1, 11, 21, 31
       this.startIdx++;


       //adjust end index
       if(this.endIdx>this.totalRecords){
       this.endIdx = this.totalRecords;
       } 

       //display resource usage
        System.Debug(LoggingLevel.WARN,'****** LIMIT query rows: '+Limits.getQueryRows()+' / '+Limits.getLimitQueryRows());
        System.Debug(LoggingLevel.WARN,'****** LIMIT heap size: '+Limits.getHeapSize()+' / '+Limits.getLimitHeapSize());
        System.Debug(LoggingLevel.WARN,'****** LIMIT cpu time: '+Limits.getCpuTime()+' / '+Limits.getLimitCpuTime());

   return contactList;
   //return Null;

}

  public PageReference processSelected() {


  List<Outreach_Visit_Attendee__c> newAttendees = new List<Outreach_Visit_Attendee__c>();

  List<Contact> selectedParticipants = new List<Contact>();
  //We will cycle through our list of cBuba and will check to see if the selected property is set to true, if it is we add the Contact to the selectedContacts list
    for(cBuba cCon: getTacos()) {
        if(cCon.selected == true) {
            selectedParticipants.add(cCon.con);
        }
    }

  for(Contact con: selectedParticipants)
  {
  newAttendees.add(new Outreach_Visit_Attendee__c(Outreach_Visit__c = ApexPages.currentPage().getParameters().get('id'), Attendee_Name__c = con.id));
  }

  PageReference p;

  if(newAttendees.size() > 0) {

  try {
  Database.insert(newAttendees);
  p = new ApexPages.StandardController(new Encounter__c(id = EncounterId)).view();
  } catch (System.DMLException e) {
  ApexPages.addMessages(e);
  }

  }

  return p;
  }


// This is our wrapper/container class. A container class is a class, a data structure, or an abstract data type whose instances are collections of other objects. In this example a wrapper class contains both the standard salesforce object Contact and a Boolean value
public class cBuba {
    public Contact con {get; set;}
    public Boolean selected {get; set;}

    //This is the contructor method. When we create a new cContact object we pass a Contact that is set to the con property. We also set the selected value to false
    public cBuba(Contact c) {
        con = c;
        selected = false;
    }
}

}

VisualForce Page

<apex:page standardController="Encounter__c" extensions="SelectTacosControllerExtension" sidebar="false">

<script type="text/javascript">
    function selectAllCheckboxes(obj,receivedInputID){
        var inputCheckBox = document.getElementsByTagName("input");                  
        for(var i=0; i<inputCheckBox.length; i++){          
            if(inputCheckBox[i].id.indexOf(receivedInputID)!=-1){                                     
                inputCheckBox[i].checked = obj.checked;
            }
        }
    }
</script>     

<apex:form >
    <apex:pageBlock mode="edit" id="results">

        <!-- next, previous and page info -->
        <apex:commandLink action="{!doPrevious}" rendered="{!hasPrevious}" value="Previous" />
        <apex:outputLabel rendered="{!NOT(hasPrevious)}" value="Previous" />

        <apex:outputLabel value=" (page {!page} of {!totalPages}) | showing {!startIdx} to {!endIdx} of {!totalRecords} " />

        <apex:commandLink action="{!doNext}" rendered="{!hasNext}" value="Next" />
        <apex:outputLabel rendered="{!NOT(hasNext)}" value="Next" />


        <apex:pageBlockButtons >
            <apex:commandButton value="Select Provider" action="{!processSelected}" rerender="table"/>
            <apex:commandButton reRender="error,blocktable,buttons" action="{!Save}" value="Save"/>
            <apex:commandButton reRender="error,blocktable,buttons" action="{!Cancel}" value="Cancel"/>
            <apex:pageMessages id="errors"/>
        </apex:pageBlockButtons>

        <!-- In our table we are displaying the cContact records -->
        <apex:pageBlockTable value="{!tacos}" var="c" id="table">
            <apex:column >
                <apex:facet name="header">
                    <apex:inputCheckbox onclick="selectAllCheckboxes(this,'inputId')"/>
                </apex:facet>
                <!-- This is our selected Boolean property in our wrapper class -->
                <apex:inputCheckbox value="{!c.selected}" id="inputId"/>
            </apex:column>
            <!-- This is how we access the contact values within our cContact container/wrapper -->
            <apex:column value="{!c.con.account.VISN__c}" />
            <apex:column value="{!c.con.Sta3n__c}" />
            <apex:column value="{!c.con.Station_Name__c}" />
            <apex:column value="{!c.con.name}" />
            <apex:column value="{!c.con.ProviderClass__c}" />
            <apex:column value="{!c.con.title}" />

            <apex:inlineEditSupport event="onClick"/>

        </apex:pageBlockTable>
    </apex:pageBlock>
</apex:form>

View State Comparison

enter image description here

My VisualForce Page with reRender and id="myDataTable"

<script type="text/javascript">
    function selectAllCheckboxes(obj,receivedInputID){
        var inputCheckBox = document.getElementsByTagName("input");                  
        for(var i=0; i<inputCheckBox.length; i++){          
            if(inputCheckBox[i].id.indexOf(receivedInputID)!=-1){                                     
                inputCheckBox[i].checked = obj.checked;
            }
        }
    }
</script>     

<apex:form >

        <apex:pageBlock mode="edit" id="results">

            <!-- next, previous and page info -->
            <apex:commandLink action="{!doPrevious}" rendered="{!hasPrevious}" value="Previous" />
            <apex:outputLabel rendered="{!NOT(hasPrevious)}" value="Previous" />

            <apex:outputLabel value=" (page {!page} of {!totalPages}) | showing {!startIdx} to {!endIdx} of {!totalRecords} " />

            <apex:commandLink action="{!doNext}" reRender="myDataTable" value="Next" />
            <apex:outputLabel rendered="{!NOT(hasNext)}" value="Next" />


            <apex:pageBlockButtons >
                <apex:commandButton value="Select Provider" action="{!processSelected}" rerender="table"/>
                <apex:commandButton reRender="error,blocktable,buttons" action="{!Save}" value="Save"/>
                <apex:commandButton reRender="error,blocktable,buttons" action="{!Cancel}" value="Cancel"/>
                <apex:pageMessages id="errors"/>
            </apex:pageBlockButtons>

            <!-- In our table we are displaying the cContact records -->
            <apex:outputPanel id="myDataTable">
                <apex:pageBlockTable value="{!tacos}" var="c" id="table">
                    <apex:column >
                        <apex:facet name="header">
                            <apex:inputCheckbox onclick="selectAllCheckboxes(this,'inputId')"/>
                        </apex:facet>
                        <!-- This is our selected Boolean property in our wrapper class -->
                        <apex:inputCheckbox value="{!c.selected}" id="inputId"/>
                    </apex:column>
                    <!-- This is how we access the contact values within our cContact container/wrapper -->
                    <apex:column value="{!c.con.account.VISN__c}" />
                    <apex:column value="{!c.con.Sta3n__c}" />
                    <apex:column value="{!c.con.Station_Name__c}" />
                    <apex:column value="{!c.con.name}" />
                    <apex:column value="{!c.con.ProviderClass__c}" />
                    <apex:column value="{!c.con.title}" />

                    <apex:inlineEditSupport event="onClick"/>

                </apex:pageBlockTable>
            </apex:outputPanel>
        </apex:pageBlock>

</apex:form>

enter image description here

0
0

Wrap your pageblocktable inside a outputPanel and give some Id to it like mydatatable. Now in next command link put a reRender attribute and its value should be id of outputPanel. This will make sure that your table is refreshed every time you click on next.

5
  • @kiranMachewar thank you. here is the updated apex code, however, with no success. Q. Isn't this something I can handle in the Apex Class? I have leveraged the following code from (//cloudclickware.wordpress.com/2013/12/02/list-pagination-of-a-large-record-set-with-record-selection/) and seems they handle the refreshing in the Apex Class with the following line: //clear container for records displayed this.tRecords.clear();
    – tomc0920
    Nov 18 '15 at 2:50
  • I think there is a problem with this line if(contactList == null). Because of this whenever your clicking on next your control is not going to the code where you are making query to get further records. As a common practice if this solves please mark this as answer and upvote. If you still face issue please update. Nov 18 '15 at 4:09
  • thank you, that is the problem line, so will accept, however, without (contact == null) that then breaks my wrapper and limit of 50,000 capability : ( Any suggestions on code to solve for both? Thank you
    – tomc0920
    Nov 18 '15 at 12:47
  • I would say don't try to navigate over 50K records, since practically no user would be selecting/viewing those many records. Just stick to navigating less than 50K records. If record count is coming to be more than 50K (If 50K is coming so there is a major chance that all records are more than 50K) then just show a message say "There are more than 50K records. Please refine your search criteria to get restricted set of records.". I know this will include extra filters to be added to your list view but yes this is way to go. Nov 18 '15 at 18:05
  • 2 types of implementations that you can do 1. StanadardSetController & 2. Use of offset. In both approaches there are limitations where you need to restrict your data set. Go through developer.salesforce.com/page/… Nov 18 '15 at 18:06
0

With an empty "reRender" parameter the button is represented as an input element of a type submit: type="submit". This means by click on this button it will SUBMIT the entire form and the page will completely reloaded (synchronous in this case)..

3
  • thank you for your note. Not sure I understand. Does this mean the fix is simply in the VisualForce apex commandLink code?
    – tomc0920
    Nov 18 '15 at 1:51
  • @tomc0920 - Possibly, try simply adding rerender=myDataTable" to your command links
    – Eric
    Nov 18 '15 at 3:17
  • Guys, I should have added, that my page indexes are advancing, however, the data that should be wrapped in subsequent pages is not being displayed. See image above
    – tomc0920
    Nov 18 '15 at 3:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.