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
Yelper DevYelper Dev 

Records Not Displaying In PageBlockTable

Hi, I need help with code. The requirement is to display all the records of Contact that has Account. When I search, there is no results being displayed. Anything wrong with my custom controller? Just a reminder I've created a Wrapper Class for this dynamic Search.

Custom Controller:
public with sharing class AccountSearchSampleController{
    //Pagination variables
    public Integer pageCount = 0;
    public Integer currentPage = 1;
    public Integer pageLimit = 10;
    public Integer totalSize = 0;
    
    public String resultDateTime{get;set;}
    
    //Search Criteria fields variables
    public String AccountName {get;set;}	
    public String Country {get;set;}
    public String ContactName {get;set;}
    public String AccountType {get;set;}
    
    //Custom Setting variable class
    public Account_Filter__c searchSetting {get;set;}
    
    //Wrapper class
    public Map<Integer, List<ContactWithAccountWrapper>> accountSearchResultMap;

    //Constructor
    public AccountSearchSampleController(){
        //Initialize accountSearchResultMap to empty map
        this.accountSearchResultMap = new Map<Integer, List<ContactWithAccountWrapper>>();

        //Returns the custom setting data set record for the specified data set name.
        searchSetting = Account_Filter__c.getInstance();
        pageLimit = Integer.valueOf(searchSetting.Page_Limit__c);
    }     
    //For dynamic picklist of Account Type field
    public List<SelectOption> getAccountTypeOptionsList(){
        List<SelectOption> accountTypeOptionsList = new List<SelectOption>{new SelectOption('', '--None--')};
            Schema.DescribeFieldResult accountTypeDescription = Account.Type.getDescribe();
        List<Schema.PicklistEntry> accountTypePicklistValuesList = accountTypeDescription.getPicklistValues();
        for(Schema.PicklistEntry accountTypePicklistValue : accountTypePicklistValuesList){
            accountTypeOptionsList.add(new SelectOption(accountTypePicklistValue.getLabel(), accountTypePicklistValue.getValue()));
        }
        return accountTypeOptionsList;
    }

    //Displays error message method
    public Boolean checkFilterValidation(){
        Boolean valid = FALSE;
        
        if(this.Country	 != NULL){
            this.Country = this.Country.replace('*', '');
        }
        if(this.ContactName	 != NULL){
            this.ContactName = this.ContactName.replace('*', ''); 
        }
        Set<String> filterSet = new Set<String>{this.AccountName, this.Country, this.ContactName, this.AccountType};
            for(String filter : filterSet){
                if(!String.isBlank(filter)){
                    valid = TRUE;
                }
            }
        
        //Displays an error message if all fields does not have a value to search.
        if(!valid){
            ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.Severity.ERROR, Label.LBL_Account_Search_No_Value);
            ApexPages.addMessage(errorMessage);
            return valid;
        }
        //Displays an error message if Account Name field does not have a value and should at least be 2 minimum characters to search.
        if(!String.isBlank(AccountName) && AccountName.length() < 2){
            ApexPages.Message errorMessage = new ApexPages.Message(ApexPages.Severity.ERROR, Label.LBL_Account_Search_Minimum_Character_Input);
            ApexPages.addMessage(errorMessage);
            valid = FALSE;
        }
        return valid;
    }


    //Start of Logic query - Trigger to search based on the criteria
    public void searchAccounts(){
        if(checkFilterValidation()){
            this.currentPage = 1;
            //Initialize accountSearchResultMap
            fetchRecords();
        } 
    } 
    
    //To pull the records if "Find Account" button is click
    public void fetchRecords(){
        this.accountSearchResultMap = new Map<Integer, List<ContactWithAccountWrapper>>();
        Set<Id> accountIdSet = new Set<Id>();
        Map<Id, Account> accountMap = new Map<Id, Account>();
        List<Account> accountContactList = new List<Account>();
        
        //Pass the method to string variable
        String queryString = getQueryString();
        
        //The string variable will retrieve up to 50,000 records.
        accountContactList = Database.query(queryString);
        this.resultDateTime = System.now().format('MMM, DD YYY \'@\' HH:mm:ss z');
        remapForPagination(accountContactList);
    }
    
    //Query Conditions
    public String getQueryString(){
        String tempCondition = '';
        String contactCondition = '';
        List<String> conditionList = new List<String>{'isDeleted = FALSE'};
            //Parent to Child Query - To validate if the record has been deleted or not.
            String contactSubQuery = 'SELECT Id, Name, CreatedDate 	FROM Contacts WHERE isDeleted = FALSE';
        
        //Start of Query for Account Name field
        if(!String.isBlank(this.AccountName)){
            //Returns a copy of the string that no longer contains any leading or trailing white space characters.
            this.AccountName = this.AccountName.trim();
            tempCondition = stringConditionHandler(this.AccountName, TRUE);
            conditionList.add('Name LIKE \'' + tempCondition + '\'');
            
        }  
        //Start of Query for Country field
        if(!String.isBlank(this.Country)){
            //Returns a copy of the string that no longer contains any leading or trailing white space characters.
            this.Country = this.Country.replace('*', '').trim();
            tempCondition = stringConditionHandler(this.Country, FALSE);
            conditionList.add('(BillingCountry = \'' + tempCondition + '\' + OR ShippingCountry = \'' + tempCondition + '\')');
        }    
        
        //Start of Query for Contact Name field
        if(!String.isBlank(this.ContactName)){
            //Returns a copy of the string that no longer contains any leading or trailing white space characters.
            this.ContactName = this.ContactName.replace('*', '').trim();
            tempCondition = stringConditionHandler(this.ContactName, FALSE);
            contactCondition = 'AND (Name = \'' + tempCondition + '\' + OR FirstName = \'' + tempCondition + '\' OR LastName = \'' + tempCondition + '\')';
            conditionList.add('Id IN (SELECT AccountId FROM Contact WHERE ' + contactCondition + ')');
            contactSubQuery += contactCondition;
        }
        
        //Start of Query for Account Type
        if(!String.isBlank(this.AccountType)){
            tempCondition = stringConditionHandler(this.AccountType, FALSE);
            conditionList.add('(Type = \'' + tempCondition + '\' ');
        }  
        
        String queryString = 'SELECT Id, Name, CreatedDate, BillingCountry, ShippingCountry, Type, ( ' + contactSubQuery + ' ) FROM Account WHERE Name LIKE \'%'+AccountName+'%\' ORDER BY Name';
        System.debug(queryString);
        return queryString;
    }
    
    //For replacing wildcard character 
    public String stringConditionHandler(String value, Boolean withWildCard){
        String processedValue = value;
        if(withWildCard){
            processedValue = value.replace('%', '\\%').replace('_', '\\').replace('*', '%');
        }else{
            processedValue = value.replace('*', '');
        }
        return String.escapeSingleQuotes(processedValue).trim();
    }
    
    //For pagination using Map
    public void remapForPagination(List<Account> accountContactList){
        Integer recordsPerPageCounter = 0;
        Integer pageCounter = 1;
        Integer totalRecords = 0;
        
        for(Account acct : accountContactList){
            if(acct.Contacts.size() > 0){
                for(Contact cont : acct.Contacts){
                    totalRecords++;
                    System.debug(totalRecords);
                    if(recordsPerPageCounter < this.PageLimit){
                        recordsPerPageCounter++;
                        System.debug(recordsPerPageCounter);
                    }else{
                        recordsPerPageCounter = 1;
                        pageCounter++;
                        System.debug(recordsPerPageCounter + pageCounter);
                    }
                    
                    if(this.accountSearchResultMap.containsKey(pageCounter)){
                        this.accountSearchResultMap.put(pageCounter, new List<ContactWithAccountWrapper>());
                        System.debug(accountSearchResultMap);
                    }
                    this.accountSearchResultMap.get(pageCounter).add(new ContactWithAccountWrapper(cont, acct));
                }
            }else{
                totalRecords++;
                if(recordsPerPageCounter < this.pageLimit){
                    recordsPerPageCounter++;
                } else{
                    recordsPerPageCounter = 1;
                    pageCounter++;
                }
                if(!this.accountSearchResultMap.containsKey(pageCounter)){
                    this.accountSearchResultMap.put(pageCounter, new List<ContactWithAccountWrapper>());
                }
                this.accountSearchResultMap.get(pageCounter).add(new ContactWithAccountWrapper(new Contact(), acct));
            }
        }
        this.totalSize = totalRecords;
    }
    
    //Wrapper to assign and get the results to be displayed in visualforce page
    public List<ContactWithAccountWrapper> getSearchResultList(){
        return this.accountSearchResultMap.get(currentPage);
    }

    //Pagination
        public Integer getTotalSize(){
        return this.totalSize;
    }
    
    public Boolean getFirst(){
        return
    }
    public Boolean getHasNext(){
        return this.accountSearchResultMap.containsKey(currentPage + 1);
    }
   
    public void getNext(){
        this.currentPage++;
    }

    public void getLast(){
        return this.accountSearchResultMap.size();
    }
    
    public Boolean getHasPrevious(){
        return this.accountSearchResultMap.containsKey(currentPage - 1);
    }
    
    public void getPrevious(){
        this.currentPage--;
    }

    public void getFirst(){
    this.currentPage =1;
    }
    
    //Wrapper class for Account and Contact Object
    public class ContactWithAccountWrapper{
        public Account acct {get; set;}
        public Contact cont {get; set;}
        public Integer yearAccountCreated {get; set;}
        public ContactWithAccountWrapper(Contact contact, Account account){
            this.cont = contact;
            this.acct = account;
            yearAccountCreated = account.CreatedDate.year();
        }
    }
    
}
Visualforce page:
<apex:page controller="AccountSearchSampleController" tabStyle="Account_Search_Sample__tab">
    <!--Custom CSS File for Account Search Page-->
    <apex:stylesheet value="{! $Resource.AccountSearchPageCSS}"/>
    <!--Start of Searching For Matching Records-->
    <apex:actionstatus id="matching_records">
        <apex:facet name="start">
            <apex:outputPanel styleClass="waitingSearchDiv">
                <apex:outputPanel styleClass="waitingHolder">
                    <apex:image url="/img/loading.gif" />
                    <apex:outputPanel >{! $Label.LBL_Search_Matching_Accounts}</apex:outputPanel>
                </apex:outputPanel>
            </apex:outputPanel>
        </apex:facet>
    </apex:actionstatus>
    <!--End of Searching For Matching Records --> 
    <!--Start of Loading Records-->
    <apex:actionstatus id="loading_records">
        <apex:facet name="start">
            <apex:outputPanel styleClass="waitingSearchDiv">
                <apex:outputPanel styleClass="waitingHolder">
                    <apex:image url="/img/loading.gif" />
                    <apex:outputPanel >{! $Label.LBL_Loading_Records}</apex:outputPanel>
                </apex:outputPanel>
            </apex:outputPanel>
        </apex:facet>
    </apex:actionstatus>
    <!--End of Loading Records-->        
    <apex:form >
        <!--Logo of Account Search Page-->
        <apex:image url="{! $Resource.AccountSearchLogo}"/> 
        <!--Error Message-->
        <apex:pageMessages id="showErrorMessage" />
        <apex:pageBlock title="{! $Label.LBL_Search_Criteria}" helpUrl="{! $Label.LBL_How_to_Search}" helpTitle="{! $Label.LBL_How_to_Search}">
            <apex:pageBlockSection columns="4">
                <apex:pageBlockSection columns="1">
                    <apex:outputText value="{!$ObjectType.Account.Fields.Name.Label}" styleclass="labelBold"/>
                    <apex:inputText value="{! AccountName}" required="FALSE"/>
                </apex:pageBlockSection>
                <apex:pageBlockSection columns="1" rendered="{! searchSetting.Country__c }">
                    <apex:outputText value="{!$Label.LBL_Country}" styleclass="labelBold"/>
                    <apex:inputText value="{! Country}"/>
                </apex:pageBlockSection>
                <apex:pageBlockSection columns="1"  rendered="{! searchSetting.Contact_Name__c }">
                    <apex:outputText value="{!$Label.LBL_Contact_Name}" styleclass="labelBold"/>
                    <apex:inputText value="{! ContactName}" rendered="{! searchSetting.Contact_Name__c }"/>    
                </apex:pageBlockSection>
                <apex:pageBlockSection columns="1" rendered="{! searchSetting.Account_Type__c}">
                    <apex:outputText value="{!$ObjectType.Account.Fields.Type.Label}" styleclass="labelBold" />
                    <apex:selectList value="{! AccountType}" rendered="{! searchSetting.Account_Type__c}" size="1">
                        <apex:selectOptions value="{! accountTypeOptionsList}"/>
                    </apex:selectList> 
                </apex:pageBlockSection>  
            </apex:pageBlockSection>  
            <apex:pageBlockButtons location="bottom" styleClass="findAcctButton">
                    <apex:commandButton value="Find Acccounts" status="matching_records" rerender="showErrorMessage"  action="{! searchAccounts}" /> 
            </apex:pageBlockButtons>
        </apex:pageBlock>
        <!--Start of Search Results Block--> 
        
        <apex:pageBlock title="{! $Label.LBL_Search_Results}" id="search-result">
            <!--Start of Displaying Results-->
            <apex:outputText rendered="{! !(SearchResultList.empty || SearchResultList == NULL) }" value="{ ! SearchResultList.size}/{! totalSize} {! $Label.LBL_Search_Results}" /> 
            <!--Enod of Displaying Results-->
            <apex:outputPanel layout="block" >
                <apex:pageBlockTable value="{! searchResultList}" var="searchResult" rendered="{! !(SearchResultList.empty || SearchResultList == NULL) } ">
                    <apex:column headerValue="{!$ObjectType.Account.Fields.Name.Label}"/>
                    <apex:outputLink value="/{! searchResult.acct.Id}" target="_blank">
                        {! searchResult.acct.Name}
                    </apex:outputLink>
                    <apex:column value="{! searchResult.acct.BillingCountry}" headerValue="{!$ObjectType.Account.Fields.BillingCountry.Label}"/>  
                    <apex:column value="{! searchResult.acct.ShippingCountry}" headerValue="{!$ObjectType.Account.Fields.ShippingCountry.Label}"/>  
                    <apex:column headerValue="{!$Label.LBL_Contact_Name}"/>
                    <apex:outputLink value="/{! searchResult.cont.Id}" target="_blank">
                        {! searchResult.cont.Name}
                    </apex:outputLink>
                    <apex:column value="{! searchResult.acct.Type}" headerValue="{!$ObjectType.Account.Fields.Type.Label}"/>  
                    <apex:column value="{! searchResult.yearAccountCreated}" headerValue="{! $Label.LBL_Year_Created}"/>
                </apex:pageBlockTable>
                <apex:outputPanel layout="block" rendered="{! SearchResultList.empty || SearchResultList == NULL }">
                {! $Label.LBL_Matching_Records}
                </apex:outputPanel>
            </apex:outputPanel>
                        <apex:outputPanel >
                <apex:commandButton value="{! $Label.LBL_Double_Previous_Button}" action="{! getFirst}" rendered="{! hasPrevious}" rerender="search-result" status="loading_records" disabled="{!prev}"/>
                <apex:commandButton value="{! $Label.LBL_Previous_Button}" action="{! getFirst}" rendered="{! hasPrevious}" rerender="search-result" status="loading_records" disabled="{!prev}"/>
                <apex:commandButton value="{! $Label.LBL_Next_Button}" action="{! getNext}" rendered="{! hasNext}" rerender="search-result" status="loading_records" disabled="{!next}"/>
                <apex:commandButton value="{! $Label.LBL_Double_Next_Button}" action="{! getLast}" rendered="{! hasNext}" rerender="search-result" status="loading_records" disabled="{!next}"/>
            </apex:outputPanel>
        </apex:pageBlock>
        <!--End of Search Results Block--> 
    </apex:form>
</apex:page>