2

I have requirement where i have to implement pagination in visual force page i want load all the records in a single page on clicking a button load records...

i.e initially it load 5 records during page load on clicking the button it loads more 5 records in the same page and the process continues till the last records.

I am using callouts also to get some data on the page so i cant call more than 10 records at a time.

can i have a work around for the above implementation.

Is there anyway in implementing pagination using jquery in salesforce.

2
  • 1
    Have you considered using a standard list controller with pagination? – Simon Lawrence May 12 '14 at 9:22
  • Please edit your question and clarify whether you want multiple pages or not. Here you say you need pagination. Below you say you want it all on one page. The word "pagination" implies multiple pages. – Jagular Jul 11 '14 at 20:52
3

I did this a while back and answered a similar question back in 2012 but using APEX. https://developer.salesforce.com/forums/ForumsMain?id=906F000000092EHIAY#ext-gen18

This will be able to handle multiple pagination queries.

Best advice I can give is make a service class that does the logic for you and you only have to setup once. You are currently doubling your code by having 2 methods because you want 2 paginated set of sobjects...

Here's an example of what I have done in the past when I needed pagination.

Here's the up to date generic version

/**
 * This is a basic pagination service class for the any Sobject.
 * Constructor requires 3 input values.
 * @Input String soqlString - Query related to what you want to pull back.
 * @Input Integer pageSize - Number of records to be returned at a time. 
 * @Input String SobjectName - Sobject API Name
 *
 * @auther Alex Acosta
 **/
public with sharing class CustomSetController {

private String soqlQuery        { get; set; }
private Integer recordCount     { get; set; }
private Boolean hasNext         { get; set; }
private Boolean hasPrevious     { get; set; }
private Integer offset          { get; set; }
private List<Sobject> records   { get; set; }
private Integer pageSize        { get; set; }
private Integer pageNumber      { get; set; }
private String sObjectName      { get; set; }

public CustomSetController(String soqlString, Integer pageSize, String sObjectName){
    this.soqlQuery = soqlString;
    this.sObjectName = sObjectName;
    recordCount = 0;
    if(null == pageSize || 0 == pageSize) 
        pageSize = 5;
    this.pageSize = pageSize;       
    offset = 0;
    pageNumber = 1;
    hasNext = false;
    hasPrevious = false;
    records = new List<Sobject>();
    try{
        getRecordCount();
    }catch(QueryException e){
        // no records found
        recordCount = 0;
    }
}

public Integer getRecordCount(){
    String soqlString = 'SELECT count() ' + this.soqlQuery.subString(this.soqlQuery.lastIndexOfIgnoreCase('from ' + sObjectName));
    if(soqlString.toLowerCase().contains('order by'))
        soqlString = soqlString.substring(0, soqlString.ToLowerCase().indexOf('order by'));
    try{
        recordCount = Database.countQuery(soqlString + ' LIMIT 50000');
    }catch(Exception e){
        recordCount = 0;
    }

    return recordCount;
}

public String getQueryString(){ return this.soqlQuery; }

public Integer getPageSize(){ return this.pageSize; }

public List<Sobject> getRecords(){
    if(recordCount == 0) return new List<Sobject>();

    String soqlString = this.soqlQuery + ' LIMIT ' + pageSize;
    if(offset > 0)
        soqlString = soqlString + ' OFFSET ' + offset;          
    records = Database.query(soqlString);

    return records;
}

public Boolean getHasNext(){
    if(offset + records.size() >= recordCount)  return false;
    return true;
}

public Boolean getHasPrevious(){
    if(offset == 0) return false;
    return true;
}

public List<Sobject> getNext(){
    offset = offset + pageSize;
    if(pageNumber < getTotalPages())
        pageNumber++;
    return getRecords();
}

public List<Sobject> getPrevious(){
    offset = offset - pageSize;
    if(pageNumber > 1)
        pageNumber--;
    return getRecords();
}

public Integer getCurrentPage(){
    return pageNumber;  
}

public Integer getTotalPages(){
    return (math.mod(recordCount, pageSize) > 0) ? Integer.valueOf(Math.floor(recordCount/pageSize)) + 1 : recordCount/pageSize;
}

public List<Sobject> getFirstPage(){
    pageNumber = 1;
    offset = 0;
    return getRecords();
}

public List<Sobject> getLastPage(){
    offset = (getTotalPages()-1) * pageSize;
    pageNumber = getTotalPages();
    return getRecords();
}
}

To control multiple pagination on a single page you would do something like this in your VF controller... Make a variable for each instance, and their own method. This way if anything ever needs to change from the root code, you only have to change it in one place.

public List<Task> notes  { get; set; }
public TaskSetController theNotesController  { get; set; }

public void resetNoteController(){
    theNotesController = new CustomSetController ('SELECT CreatedBy.Name, CreatedDate, Description, Id FROM Task WHERE WhoId = \'' + account.PersonContactId + '\' ORDER BY CreatedDate DESC', 10, 'Task');
    notes = theNotesController.getRecords();
}

public void getNextSetOfNotes(){
    if(getNotesHasNext())
        notes = theNotesController.getNext();
}

public Boolean getNotesHasNext(){
    return theNotesController.getHasNext();
}

public void getPreviousSetOfNotes(){
    if(getNotesHasPrevious())
        notes = theNotesController.getPrevious();
}

public Boolean getNotesHasPrevious(){
    return theNotesController.getHasPrevious();
}

public Integer getTaskRecordCount(){
    return theNotesController.getRecordCount();
}

public Integer getTaskTotalPages(){
    return 0 == theNotesController.getTotalPages() ? 1 : theNotesController.getTotalPages();
}

public Integer getTaskCurrentPage(){
    return theNotesController.getCurrentPage();
}

public void getFirstPageOfNotes(){
    notes = theNotesController.getFirstPage();
}

public void getLastPageOfNotes(){
    notes = theNotesController.getLastPage();
}

Visualforce Page would look as such per Instance of the Pagination Class

<apex:panelGroup >
    <label></label>
    <apex:dataTable value="{!notes}" var="n" rowClasses="odd,even" id="notesTable" styleClass="tableClass" width="100%" border="1px" cellpadding="10px">
        <apex:column width="70%">
            <apex:facet name="header">Notes</apex:facet>
            <apex:outputText value="{!n.Description}"/>
        </apex:column>
        <apex:column >
            <apex:facet name="header">Created By</apex:facet>
            <apex:outputText value="{!n.CreatedBy.Name} on {!n.CreatedDate}"/>
        </apex:column>
    </apex:dataTable>

    <apex:panelGroup style="width:100%;text-align:center;display:block;margin:5px 0 0 0;">
        <apex:outputText value="Page: {!taskCurrentPage} of {!taskTotalPages}" style="float:left !important;" />

        <apex:outputText value="◄◄" rendered="{!IF(taskCurrentPage != 1, false, true)}" style="margin: 0 10px 0 0;color:#A8A8A8" />
        <apex:commandLink action="{!getFirstPageOfNotes}" value="◄◄" rendered="{!IF(taskCurrentPage == 1, false, true)}" rerender="notesSection" style="margin: 0 10px 0 0;text-decoration:none;" />
        <apex:outputText value="◄ Previous" rendered="{!NOT(notesHasPrevious)}" style="margin: 0 5px 0 0;color:#A8A8A8" />
        <apex:commandLink action="{!getPreviousSetOfNotes}" value="◄ Previous" rendered="{!notesHasPrevious}" rerender="notesSection" style="margin: 0 5px 0 0;text-decoration:none;" />

        <apex:commandLink action="{!getNextSetOfNotes}" value="Next ►" rendered="{!notesHasNext}" rerender="notesSection" style="margin: 0 0 0 5px;text-decoration:none;" />
        <apex:outputText value="Next ►" rendered="{!NOT(notesHasNext)}" style="margin: 0 0 0 5px;color:#A8A8A8" />
        <apex:outputText value="►►" rendered="{!IF(taskCurrentPage >= taskTotalPages, true, false)}" style="margin: 0 0 0 10px;color:#A8A8A8" />
        <apex:commandLink action="{!getLastPageOfNotes}" value="►►" rendered="{!IF(taskCurrentPage < taskTotalPages, true, false)}" rerender="notesSection" style="margin: 0 0 0 10px;text-decoration:none;" />

        <apex:outputText value="Total Records: {!taskRecordCount}" style="float:right !important;" />
    </apex:panelGroup>
</apex:panelGroup>
0
0

You can implement a custom pagination your self. Hope this will help you. Below is the idea behind the implementation.

  1. Have a method to generate the dynamic query.
  2. Have a class variable to keep track of offset of your query
  3. Have a final variable to keep track of the limit of your query (5 in your case)
  4. In all Next, Prev, First and Last buttons' actions update the value of your offset and run the dynamic query, reset the wrapper class list which will be used to generate the UI.
2
  • i dont want to use pagination, I want to display all the records in the same page. with a single button "Load..." i want increase the display of records initially 5 record and clicking the button its has to display 10 records along with the initial five records – user6833 May 12 '14 at 10:23
  • In that case you no need of having offset, just have the limit variable and increase it by 5 and execute the query in the Load button action – highfive May 12 '14 at 17:03
0

Have you looked at this plugin before? It's really easy to use and will give you very cool functionalities to your table

http://datatables.net/

// Controller

public with sharing class TestDataTables {

public List<Account> accList { get {
    if(accList == null || accList.size() == 0){
        accList = [SELECT Id, Name FROM Account LIMIT 1000];
    }
    return accList;
} set;}

}

// VF Page

<apex:dataTable value="{!accList}" var="acc" id="testTable" >
    <apex:column >
        <apex:facet name="header"><apex:outputLabel value="ID" /></apex:facet>
        <apex:outputText value="{!acc.Id}"/>
    </apex:column>
    <apex:column >
        <apex:facet name="header"><apex:outputLabel value="Name" /></apex:facet> 
        <apex:outputText value="{!acc.Name}"/>
    </apex:column>
</apex:dataTable>
<button type="button" id="load">Load</button>
<script type="text/javascript" charset="utf8">


    var oTable;
    var currentNumberDisplayed = 5;

    $(document).ready(function() {
        $('#load').click( function () {
            var oSettings = oTable.fnSettings();
            currentNumberDisplayed += 5;
            oSettings._iDisplayLength = currentNumberDisplayed;
            oTable.fnDraw();
        });

        oTable = $('[id$=testTable]').dataTable({               
            "iDisplayLength": 5
        });
    });

</script>

3
  • can you explain how to use that jquery plugin into salesforce. – Sathya May 12 '14 at 12:36
  • All you need is the list of records that you are going to render on the VF page and make use of apex:dataTable. Also keep in mind that you can't render more than 1000 records when using apex:dataTable. You would need to add some logic for that scenario – user8274 May 12 '14 at 12:48
  • I worked the on the above examples and it not functioning proprely – user6833 May 27 '14 at 5:04

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.