This post has a working example of dynamic search in a Visualforce page and the results shown with pagination.
There are 4 field search criteria including date fields too which makes it more interesting. The results upon clicking Search will display below the Search section with 4 buttons to paginate. The Next/Last Page buttons grey out when there are no further records in the results.
Apex Controller
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
} |
Visualforce Page
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
Here’s the complete github code
Hi, Thanks for sharing the code. It helps me a lot. I have a question here. Code that you implemented here does not maintain selected records when you move to next page. Meaning If i am on first page, I select 2 records then I move to next page again select 2 different records and then come back to previous page then it does not maintain selected records state here. Can you please tell me how to maintain selected records state when you move to next page?
LikeLike
I am getting error on Test class for Previous().
System.QueryException: SOQL offset must be a non-negative value
Anyone Facing this issue.Can you please help on this?
LikeLike
do you have test class for this
LikeLike
Wow! This can be one particular of the most useful blogs We’ve ever arrive across on this subject. Basically Magnificent. I am also a specialist in this topic so I can understand your effort.
LikeLike
Hi I am facing the issue in pagination …. when clicking on Last page its giving me Offset error that it can return only 2000 Rows .. Please help its Urgent
How to handle this.. Please
LikeLike
Enntlhienigg the world, one helpful article at a time.
LikeLike
Thank you!
LikeLike
Super inrvomatife writing; keep it up.
LikeLike
Thank you very much!
LikeLike
Yes now its working . Thank you so much 🙂
LikeLiked by 1 person
Glad to hear that !! You’re welcome.
LikeLike
Hi
Are there any prerequisites to make this code execute?? Its showing “unexpected token: ‘accountList’ at line 3 column 13”
Also “Could not resolve the entity from value binding ‘{!acc.Created_From_Date__c}’. can only be used with SObjects, or objects that are Visualforce field component resolvable” though i have created two custom fields by same name.
Please help me out
LikeLike
Are you trying to use {!acc.Created_From_Date__c} with outputText or inputText? No prerequisites for the code to execute.
LikeLike
Inputfield as u mentioned in the code
LikeLike
How about this?
can you tell me did u create the custom field by same name?? if so, in the screenshot its showing as From Date
LikeLike
Please change line 3 to the below line. The List was missing in it.
public List accountList {get;set;}
LikeLike
Ah! I see whats happening, the html code is being overwritten by wordpress. I’ll upload the full code and send you the link in few minutes
LikeLike
sure
LikeLiked by 1 person
Updated the code in the post. Please check and let me know if it works for you now.
LikeLike
Hi
Am here again.. actually i have written a test class for the same but its covering only 73%
also if i call previous method its throwing error. Please help me out
@isTest
public class ControllerTestClass
{
static testMethod void testMethod1()
{
Account testAccount = new Account();
testAccount.Name=’Test Account’ ;
testAccount.FromDate__c = Date.newInstance(2016, 12, 9);
insert testAccount;
Test.StartTest();
PageReference pageRef = Page.DateAccount; // Add your VF page Name here
pageRef.getParameters().put(‘id’, String.valueOf(testAccount.Id));
Test.setCurrentPage(pageRef);
AccountMultipleSearchWithPagenationCLS1 testAccPlan = new AccountMultipleSearchWithPagenationCLS1();
testAccPlan.searchAcc();
//testAccPlan.searchAccounts();
testAccPlan.FirstPage();
testAccPlan.next();
testAccPlan.LastPage();
testAccPlan.getprev();
testAccPlan.getnxt();
//testAccPlan.previous();
Test.StopTest();
}
}
LikeLike
@Ishwarya: In the test class, can you try to insert more than 10 Account records and then try. Because the page size is 10, the method “Previous” would work fine if the there are at least 11 Account records.
LikeLike
Sure. But tell me how can we give date value since even that part is not covered. The if loop of from date and to date
LikeLike
Hi i did tr to insert but of no use..its still 73 and is failing if i include previous
LikeLike
I just need to cover From Date, To date loops and condition.size…Please let me know on how can we do this
LikeLike
Hi
Now its 78% but the date loops and condition.size loop is not getting covered.
I need to make it 100.Please help me out
LikeLike
Hi, did you populate the 2 fields Created_To_Date__c and Created_From_Date__c in all the Accounts you created in the test class? If those are populated, the date loops should be covered.
LikeLike
In what way we need to populate..can you help me with the syntax…am unable to cover them
LikeLike
You can add this line
testAccPlan.acc = testAccount;
below the line AccountMultipleSearchWithPagenationCLS1 testAccPlan = new AccountMultipleSearchWithPagenationCLS1();
LikeLike
To populate the dates, use the below lines for the account
testAccount.Created_From_Date__c= Date.newInstance(2016, 12, 9);
testAccount.Created_To_Date__c= Date.newInstance(2016, 12, 10);
LikeLike
Hi
I have followed ur comments and written below. But though its covering dates when i give previous throwing error
@isTest
public class ControllerTestClass
{
static testMethod void testMethod1()
{
Account testAccount = new Account();
testAccount.Name=’Test Account’ ;
testAccount.FromDate__c= Date.newInstance(2016, 12, 9);
testAccount.ToDate__c= Date.newInstance(2016, 12, 10);
insert testAccount;
Account testAccount1 = new Account(Name = ‘ttt’);
testAccount1.ToDate__c = Date.newInstance(2016, 12, 18);
insert testAccount1;
Account testAccount2 = new Account(Name = ‘yyy’);
insert testAccount2;
Account testAccount3 = new Account(Name = ‘q’);
insert testAccount3;
Account testAccount4 = new Account(Name = ‘c’);
insert testAccount4;
Account testAccount5 = new Account(Name = ‘yt’);
insert testAccount5;
Account testAccount6 = new Account(Name = ‘ii’);
insert testAccount6;
Account testAccount7 = new Account(Name = ‘ui’);
insert testAccount7;
Account testAccount8 = new Account(Name = ‘yui’);
insert testAccount8;
Account testAccount9 = new Account(Name = ‘nj’);
insert testAccount9;
Account testAccount10 = new Account(Name = ‘lo’);
insert testAccount10;
Test.StartTest();
PageReference pageRef = Page.DateAccount;
pageRef.getParameters().put(‘id’, String.valueOf(testAccount.Id));
Test.setCurrentPage(pageRef);
AccountMultipleSearchWithPagenationCLS1 testAccPlan = new AccountMultipleSearchWithPagenationCLS1();
testAccPlan.acc = testAccount;
testAccPlan.searchAcc();
testAccPlan.searchAccounts();
testAccPlan.FirstPage();
testAccPlan.next();
testAccPlan.LastPage();
testAccPlan.getprev();
testAccPlan.getnxt();
testAccPlan.previous();
Test.StopTest();
}
LikeLike
I checked, comment the previous method. It is 86%. It is a good coverage. If you need 100%, I can give it to you tomorrow.
LikeLike
ya currently am getting 93 but again previous method is causing an issue
LikeLike
Hi
I have made it to 93 but still its not getting passed. Can you suggest any?
LikeLike
plz post VF page code………
LikeLike
Oops, updated the VF Page code now.
LikeLike