Custom Controller Pagination with dynamic search in Visualforce page.
Hi,
In this post i am going to give a small example on how to use dynamic search in visualforce with pagination using custom controller.
For this once the user enter his search criteria and click on search button the page is going to populate account details with Pagination of (Next,Previous,Last etc..). To achieve this i am using custom controller instead of Standared Set Controller.
Visualforce Page:
<apex:page controller="AccountMultipleSearchWithPagenationCLS" action="{!searchAcc}" >
<script type="text/javascript">
window.onload=function() {
// document.getElementById("{!$Component.thePb.thepbs.accName}").focus();
}
</script>
<apex:form >
<apex:pageBlock id="thePb" title="Account Details To Search">
<apex:pageblockSection id="thepbs">
<apex:inputField value="{!acc.Created_From_Date__c}" />
<apex:inputField value="{!acc.Created_To_Date__c}"/>
<apex:inputField value="{!acc.Name}" required="false" id="accName"/>
<apex:inputfield value="{!acc.accountNumber}"/>
</apex:pageblockSection>
<apex:pageblockButtons location="bottom">
<apex:commandButton value="Search" action="{!searchAcc}" />
</apex:pageblockButtons>
</apex:pageBlock>
<apex:pageBlock title="Account Details" id="noRec" rendered="{! IF( accountList != null && accountList.size ==0 , true, false)}" >
<apex:outputPanel >
<h1>No Records Found </h1>
</apex:outputPanel>
</apex:pageBlock>
<apex:pageBlock title="Account Details" id="details" rendered="{! IF( accountList != null && accountList.size >0, true, false)}" >
<apex:pageBlockTable value="{!accountList}" var="a">
<apex:column headerValue="Account Name">
<apex:outputLink target="_blank" value="/{!a.id}">{!a.Name}</apex:outputLink>
</apex:column>
<!-- If you want facet style you can add like this.
<apex:column >
<apex:facet name="header">Link Name</apex:facet>
<apex:outputLink target="_blank" value="/{!a.id}">{!a.Name}</apex:outputLink>
</apex:column>
-->
<apex:column value="{!a.accountNumber}" headerValue="Account Number"/>
<apex:column value="{!a.Industry}" headerValue="Industry"/>
<apex:column value="{!a.AnnualRevenue}" headerValue="Annual Revenue"/>
<apex:column value="{!a.Phone}" headerValue="Phone"/>
<apex:column value="{!a.website}" headerValue="Web"/>
</apex:pageBlockTable>
<apex:pageblockButtons >
<apex:commandButton value="First Page" rerender="details" action="{!FirstPage}" disabled="{!prev}"/>
<apex:commandButton value="Previous" rerender="details" action="{!previous}" disabled="{!prev}"/>
<apex:commandButton value="Next" rerender="details" action="{!next}" disabled="{!nxt}"/>
<apex:commandButton value="Last Page" rerender="details" action="{!LastPage}" disabled="{!nxt}"/>
</apex:pageblockButtons>
</apex:pageBlock>
</apex:form>
</apex:page>
Controller Class:
public with sharing class AccountMultipleSearchWithPagenationCLS {
public Account acc{get;set;}
public List<Account> accountList {get;set;}
// create a list of strings to hold the conditions
List<string> conditions = new List<string>();
private integer totalRecs = 0;
private integer OffsetSize = 0;
private integer LimitSize= 10;
public AccountMultipleSearchWithPagenationCLS(){
system.debug('==>AccountMultipleSearchWithPagenationCLS is calling==>');
acc = new Account();
//accountList = new List<Account>();
}
public void searchAcc(){
totalRecs = 0;
OffsetSize = 0;
if(accountList !=null && accountList.size()>0){
accountList=null;
}
searchAccounts ();
conditions.clear();
}
public Void searchAccounts(){
System.debug('Total Records is ==>'+totalRecs);
System.debug('OffsetSize is ==>'+OffsetSize);
if(accountList != null && !accountList.isEmpty()){
accountList.clear();
}
String strQuery ='SELECT Id,Name,AccountNumber,CreatedDate,Phone,Website,Industry,AnnualRevenue From Account';
if(acc.Created_From_Date__c !=null){
String fromDate = acc.Created_From_Date__c+'';
fromDate = fromDate.split(' ',0)[0]+'T00:00:00.000Z';
conditions.add('CreatedDate >='+fromDate);
}
if(acc.Created_To_Date__c !=null){
String toDate = acc.Created_To_Date__c+'';
toDate = toDate.split(' ',0)[0]+'T23:59:59.000Z';
conditions.add('createdDate <='+toDate);
}
if(acc.Name !=null && acc.Name !=''){
conditions.add('Name Like \'%' +acc.Name +'%\' ');
}
if(acc.AccountNumber !=null && acc.AccountNumber !=''){
conditions.add('AccountNumber Like\'%' +acc.AccountNumber +'%\' ');
}
if (conditions.size() > 0) {
strQuery += ' WHERE ' + conditions[0];
for (Integer i = 1; i < conditions.size(); i++)
strQuery += ' AND ' + conditions[i];
}
if(totalRecs !=null && totalRecs ==0){
List<Account> accTemp = Database.query(strQuery);
totalRecs = (accTemp !=null &&accTemp.size()>0)?accTemp.size():0;
}
system.debug('strQuery ==>'+strQuery );
// add sort and limits at the end
strQuery += ' ORDER BY Name ASC, CreatedDate DESC LIMIT :LimitSize OFFSET :OffsetSize';
accountList =Database.query(strQuery);
//conditions.clear();
//return accountList.size();
}
public void FirstPage()
{
OffsetSize = 0;
searchAccounts();
}
public void previous()
{
OffsetSize = (OffsetSize-LimitSize);
searchAccounts();
}
public void next()
{
OffsetSize = OffsetSize + LimitSize;
searchAccounts();
}
public void LastPage()
{
OffsetSize = totalrecs - math.mod(totalRecs,LimitSize);
searchAccounts();
}
public boolean getprev()
{
if(OffsetSize == 0){
return true;
}
else {
return false;
}
}
public boolean getnxt()
{
if((OffsetSize + LimitSize) > totalRecs){
return true;
}
else {
return false;
}
}
}
Example 2:
In this example i am not using any buttons simple using command links move forward or backward directions and also displaying the count of records, page numbers etc..
VF Page:
<apex:page controller="CustomPaginationVFController">
<apex:form >
<apex:pageBlock title="VF Sample Custom Pagination Example" id="mpb">
<!-- 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" />
<br/>
<!-- table of data -->
<apex:pageBlockTable title="Contacts" value="{!tRecords}" var="c">
<apex:column >
<apex:facet name="header">Action</apex:facet>
<apex:inputCheckbox value="{!c.IsSelected}" />
</apex:column>
<apex:column value="{!c.tContact.FirstName}"/>
<apex:column value="{!c.tContact.LastName}"/>
<apex:column value="{!c.tContact.Title}"/>
<apex:column value="{!c.tContact.Phone}"/>
<apex:column value="{!c.tContact.Email}"/>
</apex:pageBlockTable>
<br/>
<!-- 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:pageBlock>
</apex:form>
</apex:page>
Controller Class:
public with sharing class CustomPaginationVFController {
//default page size
private static final Integer PAGE_SIZE = 10;
//pagination information
public Integer page{get;set;}
public Integer totalRecords{get;set;}
public Integer totalPages{get;set;}
public Integer startIdx{get;set;}
public Integer endIdx{get;set;}
/*
* set controller
*/
public List<CCWRow> tRecords{get;set;}
/*
* constructor
*/
public CustomPaginationVFController ()
{
//init variable
this.tRecords = new List<CCWRow>();
//set initial page
this.page = 1;
//load records
getContacts();
}
/*
* advance to next page
*/
public void doNext(){
if(getHasNext()){
this.page++;
getContacts();
}
}
/*
* advance to previous page
*/
public void doPrevious(){
if(getHasPrevious()){
this.page--;
getContacts();
}
}
/*
* returns whether the previous page exists
*/
public Boolean getHasPrevious(){
if(this.page>1){
return true;
}
else{
return false;
}
}
/*
* returns whether the next page exists
*/
public Boolean getHasNext(){
if(this.page<this.totalPages){
return true;
}
else{
return false;
}
}
/*
* return current page of records
*/
public void getContacts(){
//calculate range of records for capture
this.startIdx = (this.page-1)*PAGE_SIZE;
this.endIdx = this.page*PAGE_SIZE;
this.totalRecords = 0;
//clear container for records displayed
this.tRecords.clear();
//cycle through
for(Contact c : [SELECT Id, FirstName, LastName, Title, Phone, MobilePhone, Email,
MailingStreet, MailingState, MailingPostalCode, MailingCountry, MailingCity
FROM Contact
ORDER BY LastName ASC
LIMIT 50000]){
//capture records within the target range
if(this.totalRecords>=this.startIdx && this.totalRecords<this.endIdx){
this.tRecords.add( new CCWRow(c, false) );
}
//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());
// System.Debug(LoggingLevel.WARN,'****** LIMIT script statements: '+Limits.getScriptStatements()+' / '+Limits.getLimitScriptStatements());
}
/*
* helper class that represents a row
*/
public with sharing class CCWRow{
public Contact tContact{get;set;}
public Boolean IsSelected{get;set;}
public CCWRow(Contact c, Boolean s){
this.tContact=c;
this.IsSelected=s;
}
}
}
Enjoy the coding......
20 comments:
Code issues in this. The navigation buttons are always disabled even when the totalRecs size is greater than the LimitSize too!
very nice article keep posting salesforce training
thanks for your collective information on Salesforce Tutorial Training
Can we Combine both functionalities ?
Dynamic search and editing of selected records ?
Thanks for sharing a good information about salesforce . .......This article is very useful to learners. Sales force online training
nice tutorials..thanks for sharing such a wonderful information..keep update with your blogs.
SalesForce online course
Interesting article! Thank you for sharing
https://onlineitguru.com/salesforce-online-training-placement.html
nice blog SalesForce Online Training
I can set up my new idea from this post. It gives in depth information. Thanks for this valuable information for all,..
War Wings Flip Master Happy Room 2
brilliant
Thank you so much. It saved me lot of time.
very helpful..thanks
Nice post.Keep sharing salesforce Online Training
Thanks for posting such a great article.you done a great job salesforce Online Training
It really is truly complicated to see out this type of fantastic articles with a few useful data and facts
Videodownloaderfb.com
good blog..
Server and Storage Solutions
This is one awesome blog article. Much thanks again salesforce training
This logic only works for 50k records What if WE have million records??
Please help..............
This logic only works for 50k records What if WE have million records??
Please help..............
You need personal informations from companies,family and friends that will better your life and you need easy access without them noticing just contact james or you’re financially unstable or you have a bad credit score, he will solve that without stress,he and his team can clear criminal records without leaving a trace and can also anonymously credit your empty credit cards with funds you need,all these are not done free obviously but I like working with James and his team cause they keep you updated on every step taken in order to achieve the goal and they also deliver on time,I tested and confirmed this I’m still happy on how my life is improving after my encounter with him ,you can send a mail to premiumhackservices@gmail.com
Post a Comment