2

I'm working on a search page that searches through all the fields in multiple objects and used those searched fields results in Visualforce page to show the search results and I'm stuck on how do you show search field results on VF, remember the search fields results come from different sobject1 or sobject2 etc..., I will try to demonstrate here what I mean by that.

PS: For the sake of simplicity I'm using standard object as an example but I'm using custom objects.

WrapperClass:

public class SearchWrapperClass {
    public List<Account> aAccounts {get;set;} 
    public List<Contact> cContacts {get;set;} 

    public SearchWrapper(List<Account> a, List<Contact> c) {
        this.aAccounts= a; 
        this.cContacts= c;
    }    
}

Apex Controller:

public List<SearchWrapperClass> mySearchWrapper {get;set;}

String searchquery ='FIND\'Edge*\'IN ALL FIELDS RETURNING Account(Id, Name),Contact(FirstName, LastName)'; 
List<List<SObject>> searchList = search.query(searchquery);

List<SearchWrapperClass> searchWrapperList = new List<SearchWrapper>();

Account[] searchAccounts = (Account[])searchList1[0];
Contact[] searchContacts = (Contact[])searchList1[1];

searchWrapperList.add(new SearchWrapper(searchAccounts,searchContacts));

mySearchWrapper = searchWrapperList;

Visualforce page:

Now, the problem is here I'm trying to show the search results so I should be able to show what is in the Account or Contact something like this I have attempted but does not work.

Error: Unknown property 'SearchWrapperClass.Name'

<apex:pageBlock title="Search Result" >  
    <apex:pageblockTable value="{!mySearchWrapper}" var="a">  
        <apex:column value="{!a.Name}"/>    
    </apex:pageblockTable>     
</apex:pageBlock>  

tried this and works but the problem with this approach is that I'm unable to query the Contact, how do I get the Contact search result in the pageBlockTable?:

<apex:pageBlock title="Search Result" >  
    <apex:pageblockTable value="{!mySearchWrapper[0].aAccounts}" var="a">  
        <apex:column value="{!a.Name}"/>    
    </apex:pageblockTable>     
</apex:pageBlock>  

Here is what I'm after to get or if you have a better solution please share. this is just a pseudo-code

<apex:pageblockTable value="{!mySearchWrapper}" var="a">  
    <apex:column value="{!a.aAccounts.Name}"/>    
    <apex:column value="{!a.aContacts.Name}"/>    
</apex:pageblockTable>      

Any thoughts?

1 Answer 1

5

You need separate tables for each list. Something along the lines of:

<apex:pageBlockTable value="{!mySearchWrapper.accounts}" var="account">
    <!-- columns -->
</apex:pageBlockTable>
<apex:pageBlockTable value="{!mySearchWrapper.contacts}" var="contact">
    <!-- columns -->
</apex:pageBlockTable>

If you really want to combine the records into one table, you need to make your property a single List<SObject>. Something like:

public class SearchWrapper
{
    public List<SObject> results { get; private set; }
    public SearchWrapper(List<Account> accounts, List<Contact> contacts)
    {
        results = new List<SObject>();
        results.addAll(accounts);
        results.addAll(contacts);
    }
}

Then your markup gets a bit more complex though. All of your columns would need conditional logic on which type of object is being rendered, and you must use the same number of columns. Better to keep separate tables IMO.


However, if you're really committed to the one table idea, you could make your property a single List<SObject> or List<RecordWrapper>. Something like:

public class RecordWrapper
{
    public SObject record { get; private set; }
    public List<SObjectField> fields { get; private set; }
    public RecordWrapper(Account record)
    {
        this.record = record;
        this.fields = new List<SObjectField> { Account.Name, Field2, etc. };
    }
    public RecordWrapper(Contact record)
    {
        this.record = record;
        this.fields = new List<SObjectField> { Contact.FirstName, Field2, etc. };
    }
}
public class SearchWrapper
{
    public List<RecordWrapper> results { get; private set; }
    public SearchWrapper(List<Account> accounts, List<Contact> contacts)
    {
        results = new List<SObject>();
        for (Account account : accounts) results.add(new RecordWrapper(account));
        for (Contact contact : contacts) results.add(new RecordWrapper(contact));
    }
}

Good luck figuring out the headers though. The general structure of the markup would be:

<apex:pageBlockTable value="{!mySearchWrapper.results}" var="result">
    <apex:column value="{!result.record[result.fields[0]]}" headerValue="???" />
    <apex:column value="{!result.record[result.fields[1]]}" headerValue="???" />
    <!-- etc. -->
</apex:pageBlockTable>
4
  • Adrian, I'm getting error on the VFP where I have the pageBlockTable Unknown property 'VisualforceArrayList.results' does not like how the value is defined in the pageBlockTable {!mySearchWrapper.results}
    – Nick
    Commented Jan 11, 2017 at 2:24
  • Did you declare MySearchWrapper as a SearchWrapper and define that class as laid out in the third example?
    – Adrian Larson
    Commented Jan 11, 2017 at 2:28
  • yes exactly I followed the steps as you have defined and I did declare the MySearchWrapper as a SearchWrapper.
    – Nick
    Commented Jan 11, 2017 at 2:31
  • Let's chat...
    – Adrian Larson
    Commented Jan 11, 2017 at 2:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .