+ Start a Discussion
vickySFDCvickySFDC 

how to display dynamic sosl query results on 3 objects values in single pageblocktable in VF page?

Hi All, 

 I have requirement like .

I have one text box if user enters some text like 'AB' then it will search on Account,Contact and leads  objects .then it  shoud display values contanis 'AB'   in contact, account and Lead in Single pageBlock table?

 

  Search text:  'dynamic text' here is 'AB' then list should display like this 

 it should display in pageblocktable:

 

 

Objname  Name     City

 

Contact      abi           abudhabi

 

Account     test AB    chennai ab

 

 

Lead         abraham   raviab

 

 

Thanks,

 

 

Vicky

Best Answer chosen by Admin (Salesforce Developers) 
JayNicJayNic

Well the tricky part is getting them in to a single list...

 

But given that a SOSL query returns a list<list<sObject>> then you can easily loop through that list of lists, and add it to a flat list to display somewhere else.

 

Given that you want to display the sObjectType in the column as well means you could create an inline class to store a result. The class would contain two properties of sObject Label, and sObject record.

 

Then it's a simple matter of creating a list of that custom class and displying that list on the page block table.

 

Here is how mine would look:

public with sharing class TEST_soslQueryPageBlock {

    public string searchText {get;set;}
    
    public list<list<sObject>> soslResults {
        get {
            if(searchText != null && searchText != '') {
                soslResults = [FIND :searchText IN ALL FIELDS RETURNING  lead(name, email), Contact(name, email), Account(name, phone)];
            }
            return soslResults;
        }
        set;
    }
    
    public class searchResultRow{
        public string sObjectTypeName {get;set;}
        public sObject record {get;set;}
        
        public searchResultRow(sObject pObject) {
            record = pObject;
            sObjectTypeName = pObject.getSObjectType().getDescribe().getLabel();
        }
    }   
    
    public list<searchResultRow> searchResults {
        get {
            searchResults = new list<searchResultRow>();
            if(soslResults != null) {
                //Loop through the list of list of sObjects from our sosl query
                for(list<sObject> objectList : soslResults) {
                    for(sObject obj : objectList) {
                        searchResults.add(
                            new searchResultRow(obj)
                        );
                    }
                }
            }
            return searchResults;
        }
        set;
    }

}

 And this would be a simple VF page to consume it:

<apex:page controller="TEST_soslQueryPageBlock" >
Test how to put results of a sosl search in a single page block

<br/>
<apex:form >
    
    <apex:actionFunction name="af_reRenderSearchBlock" reRender="searchBlock"/>

    <apex:pageBlock id="searchBlock" >
        <apex:pageBlockButtons location="top">
            <input type="button" class="btn" value="Search" onclick="af_reRenderSearchBlock()"/>
        </apex:pageBlockButtons>
        <apex:pageBlockSection collapsible="false" columns="1">
            <apex:pageBlockSectionItem helpText="Will search multiple objects">
                <apex:outputLabel for="searchParam">Search String</apex:outputLabel>
                <apex:inputText id="searchParam" value="{!searchText}"/>
            </apex:pageBlockSectionItem>
        </apex:pageBlockSection>
        <apex:pageBlockSection collapsible="false" columns="1" title="Results" rendered="{!searchResults.size > 0}">
            <apex:repeat value="{!searchResults}" var="row">
                {!row.sObjectTypeName} - {!row.record['Name']}, 
            </apex:repeat>
        </apex:pageBlockSection>
        
    </apex:pageBlock>

</apex:form>


</apex:page>

 

 

note that I am using a repeat - but you could use a pageBlockTable.

 

For instances where you want to render only specific fields in a column: you can use apex:outputField and use the "rendered" parameter with something like:

rendered="{!row.sObjectTypeName == 'Account'}"

 

All Answers

JayNicJayNic

Well the tricky part is getting them in to a single list...

 

But given that a SOSL query returns a list<list<sObject>> then you can easily loop through that list of lists, and add it to a flat list to display somewhere else.

 

Given that you want to display the sObjectType in the column as well means you could create an inline class to store a result. The class would contain two properties of sObject Label, and sObject record.

 

Then it's a simple matter of creating a list of that custom class and displying that list on the page block table.

 

Here is how mine would look:

public with sharing class TEST_soslQueryPageBlock {

    public string searchText {get;set;}
    
    public list<list<sObject>> soslResults {
        get {
            if(searchText != null && searchText != '') {
                soslResults = [FIND :searchText IN ALL FIELDS RETURNING  lead(name, email), Contact(name, email), Account(name, phone)];
            }
            return soslResults;
        }
        set;
    }
    
    public class searchResultRow{
        public string sObjectTypeName {get;set;}
        public sObject record {get;set;}
        
        public searchResultRow(sObject pObject) {
            record = pObject;
            sObjectTypeName = pObject.getSObjectType().getDescribe().getLabel();
        }
    }   
    
    public list<searchResultRow> searchResults {
        get {
            searchResults = new list<searchResultRow>();
            if(soslResults != null) {
                //Loop through the list of list of sObjects from our sosl query
                for(list<sObject> objectList : soslResults) {
                    for(sObject obj : objectList) {
                        searchResults.add(
                            new searchResultRow(obj)
                        );
                    }
                }
            }
            return searchResults;
        }
        set;
    }

}

 And this would be a simple VF page to consume it:

<apex:page controller="TEST_soslQueryPageBlock" >
Test how to put results of a sosl search in a single page block

<br/>
<apex:form >
    
    <apex:actionFunction name="af_reRenderSearchBlock" reRender="searchBlock"/>

    <apex:pageBlock id="searchBlock" >
        <apex:pageBlockButtons location="top">
            <input type="button" class="btn" value="Search" onclick="af_reRenderSearchBlock()"/>
        </apex:pageBlockButtons>
        <apex:pageBlockSection collapsible="false" columns="1">
            <apex:pageBlockSectionItem helpText="Will search multiple objects">
                <apex:outputLabel for="searchParam">Search String</apex:outputLabel>
                <apex:inputText id="searchParam" value="{!searchText}"/>
            </apex:pageBlockSectionItem>
        </apex:pageBlockSection>
        <apex:pageBlockSection collapsible="false" columns="1" title="Results" rendered="{!searchResults.size > 0}">
            <apex:repeat value="{!searchResults}" var="row">
                {!row.sObjectTypeName} - {!row.record['Name']}, 
            </apex:repeat>
        </apex:pageBlockSection>
        
    </apex:pageBlock>

</apex:form>


</apex:page>

 

 

note that I am using a repeat - but you could use a pageBlockTable.

 

For instances where you want to render only specific fields in a column: you can use apex:outputField and use the "rendered" parameter with something like:

rendered="{!row.sObjectTypeName == 'Account'}"

 

This was selected as the best answer
vickySFDCvickySFDC
Hi JayNic,

Good Its working fine my requirement.

Thanks.
JAVED AHMED 1JAVED AHMED 1
can we do  it the same funtionality with lwc???
can someone help me