Salesforce Lightning: Global Search
Today we will have a look at creating a custom global search using Lightning and SOSL. We will use SOSL to query the results from database and show it on the lightning component using the lightning:datatable tag
SOSL is preferred over SOQL in use cases where we want to search for a particular keyword across different objects. The return type of SOSL will be a list of list of sobjects.
Below is the code used to implement the global search:
GlobalSearch.cmp
SOSL is preferred over SOQL in use cases where we want to search for a particular keyword across different objects. The return type of SOSL will be a list of list of sobjects.
List<List<sObject>> searchResult = [FIND :searchKey
IN ALL FIELDS RETURNING
Account (Id, Name, AccountNumber, Website),
Contact(Id, Name, Email, MobilePhone),
Opportunity(Id, Name, StageName, CloseDate),
Lead(Id, Name, Email, Company)];
Lightning datatable was introduced by Salesforce in Winter 18 release. With lightning datatable, now it has become very easy to implement a table in lightning, You just need to specify the columns and pass in your data to the component and the component will take care of creating the table. The table will also have the sort feature implemented by default.IN ALL FIELDS RETURNING
Account (Id, Name, AccountNumber, Website),
Contact(Id, Name, Email, MobilePhone),
Opportunity(Id, Name, StageName, CloseDate),
Lead(Id, Name, Email, Company)];
Below is the code used to implement the global search:
GlobalSearch.cmp
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" controller="GlobalSearchController">
<!-- handlers-->
<aura:handler name="init" value="{!this}" action="{!c.init}"/>
<!-- attributes -->
<aura:attribute name="showSearchResults" type="Boolean" default="false"/>
<aura:attribute name="searchKey" type="String"/>
<aura:attribute name="accountList" type="List" default="Account[]"/>
<aura:attribute name="accountColumns" type="List"/>
<aura:attribute name="contactList" type="List" default="Contact[]"/>
<aura:attribute name="contactColumns" type="List"/>
<aura:attribute name="oppList" type="List" default="Opportunity[]"/>
<aura:attribute name="oppColumns" type="List"/>
<aura:attribute name="leadList" type="List" default="Lead[]"/>
<aura:attribute name="leadColumns" type="List"/>
<lightning:layout multipleRows="true">
<lightning:layoutItem padding="around-small" size="9">
<lightning:input name="searchKey" placeholder="Enter search key" value="{!v.searchKey}"/>
</lightning:layoutItem>
<lightning:layoutItem padding="around-small" size="3">
<lightning:button variant="brand" label="Search" title="Search" onclick="{!c.search}" class="customButton"/>
</lightning:layoutItem>
</lightning:layout>
<aura:if isTrue="{!v.showSearchResults}">
<lightning:layout multipleRows="true">
<lightning:layoutItem padding="around-small" size="12">
Account
<lightning:datatable keyField="id"
data="{!v.accountList}"
columns="{!v.accountColumns}"
hideCheckboxColumn="true"/>
</lightning:layoutItem>
<lightning:layoutItem padding="around-small" size="12">
Contact
<lightning:datatable keyField="id"
data="{!v.contactList}"
columns="{!v.contactColumns}"
hideCheckboxColumn="true"/>
</lightning:layoutItem>
<lightning:layoutItem padding="around-small" size="12">
Opportunity
<lightning:datatable keyField="id"
data="{!v.oppList}"
columns="{!v.oppColumns}"
hideCheckboxColumn="true"/>
</lightning:layoutItem>
<lightning:layoutItem padding="around-small" size="12">
Lead
<lightning:datatable keyField="id"
data="{!v.leadList}"
columns="{!v.leadColumns}"
hideCheckboxColumn="true"/>
</lightning:layoutItem>
</lightning:layout>
</aura:if>
</aura:component>
GlobalSearchController.js<!-- handlers-->
<aura:handler name="init" value="{!this}" action="{!c.init}"/>
<!-- attributes -->
<aura:attribute name="showSearchResults" type="Boolean" default="false"/>
<aura:attribute name="searchKey" type="String"/>
<aura:attribute name="accountList" type="List" default="Account[]"/>
<aura:attribute name="accountColumns" type="List"/>
<aura:attribute name="contactList" type="List" default="Contact[]"/>
<aura:attribute name="contactColumns" type="List"/>
<aura:attribute name="oppList" type="List" default="Opportunity[]"/>
<aura:attribute name="oppColumns" type="List"/>
<aura:attribute name="leadList" type="List" default="Lead[]"/>
<aura:attribute name="leadColumns" type="List"/>
<lightning:layout multipleRows="true">
<lightning:layoutItem padding="around-small" size="9">
<lightning:input name="searchKey" placeholder="Enter search key" value="{!v.searchKey}"/>
</lightning:layoutItem>
<lightning:layoutItem padding="around-small" size="3">
<lightning:button variant="brand" label="Search" title="Search" onclick="{!c.search}" class="customButton"/>
</lightning:layoutItem>
</lightning:layout>
<aura:if isTrue="{!v.showSearchResults}">
<lightning:layout multipleRows="true">
<lightning:layoutItem padding="around-small" size="12">
Account
<lightning:datatable keyField="id"
data="{!v.accountList}"
columns="{!v.accountColumns}"
hideCheckboxColumn="true"/>
</lightning:layoutItem>
<lightning:layoutItem padding="around-small" size="12">
Contact
<lightning:datatable keyField="id"
data="{!v.contactList}"
columns="{!v.contactColumns}"
hideCheckboxColumn="true"/>
</lightning:layoutItem>
<lightning:layoutItem padding="around-small" size="12">
Opportunity
<lightning:datatable keyField="id"
data="{!v.oppList}"
columns="{!v.oppColumns}"
hideCheckboxColumn="true"/>
</lightning:layoutItem>
<lightning:layoutItem padding="around-small" size="12">
Lead
<lightning:datatable keyField="id"
data="{!v.leadList}"
columns="{!v.leadColumns}"
hideCheckboxColumn="true"/>
</lightning:layoutItem>
</lightning:layout>
</aura:if>
</aura:component>
({
init: function (component, event, helper){
component.set('v.accountColumns', [
{label: 'Name', fieldName: 'Name', type: 'text'},
{label: 'Account Number', fieldName: 'AccountNumber', type: 'text'},
{label: 'Website', fieldName: 'Website', type: 'url', typeAttributes: { target: '_self'}}
]);
component.set('v.contactColumns', [
{label: 'Name', fieldName: 'Name', type: 'text'},
{label: 'Email', fieldName: 'Email', type: 'email'},
{label: 'Mobile', fieldName: 'MobilePhone', type: 'phone'},
]);
component.set('v.oppColumns', [
{label: 'Name', fieldName: 'Name', type: 'text'},
{label: 'Stage Name', fieldName: 'StageName', type: 'text'},
{label: 'Close Date', fieldName: 'CloseDate', type: 'date'}
]);
component.set('v.leadColumns', [
{label: 'Name', fieldName: 'Name', type: 'text'},
{label: 'Company', fieldName: 'Company', type: 'text'},
{label: 'Email', fieldName: 'Email', type: 'email'}
]);
},
search : function(component, event, helper) {
helper.getSearchResultsFromApex(component, event, helper);
component.set("v.showSearchResults",true);
}
})
GlobalSearchHelper.js
init: function (component, event, helper){
component.set('v.accountColumns', [
{label: 'Name', fieldName: 'Name', type: 'text'},
{label: 'Account Number', fieldName: 'AccountNumber', type: 'text'},
{label: 'Website', fieldName: 'Website', type: 'url', typeAttributes: { target: '_self'}}
]);
component.set('v.contactColumns', [
{label: 'Name', fieldName: 'Name', type: 'text'},
{label: 'Email', fieldName: 'Email', type: 'email'},
{label: 'Mobile', fieldName: 'MobilePhone', type: 'phone'},
]);
component.set('v.oppColumns', [
{label: 'Name', fieldName: 'Name', type: 'text'},
{label: 'Stage Name', fieldName: 'StageName', type: 'text'},
{label: 'Close Date', fieldName: 'CloseDate', type: 'date'}
]);
component.set('v.leadColumns', [
{label: 'Name', fieldName: 'Name', type: 'text'},
{label: 'Company', fieldName: 'Company', type: 'text'},
{label: 'Email', fieldName: 'Email', type: 'email'}
]);
},
search : function(component, event, helper) {
helper.getSearchResultsFromApex(component, event, helper);
component.set("v.showSearchResults",true);
}
})
({
getSearchResultsFromApex : function(component, event, helper){
var action = component.get("c.getSearchResult");
action.setParams({ searchKey : component.get("v.searchKey") });
// Create a callback that is executed after
// the server-side action returns
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
var result = response.getReturnValue();
// SOSL will always return the list in the order they were queried
component.set("v.accountList",result[0]);
component.set("v.contactList",result[1]);
component.set("v.oppList",result[2]);
component.set("v.leadList",result[3]);
}
else if (state === "INCOMPLETE") {
// do something
}
else if (state === "ERROR") {
var errors = response.getError();
if (errors) {
if (errors[0] && errors[0].message) {
console.log("Error message: " +
errors[0].message);
}
} else {
console.log("Unknown error");
}
}
});
$A.enqueueAction(action);
}
})
GlobalSearch.cssgetSearchResultsFromApex : function(component, event, helper){
var action = component.get("c.getSearchResult");
action.setParams({ searchKey : component.get("v.searchKey") });
// Create a callback that is executed after
// the server-side action returns
action.setCallback(this, function(response) {
var state = response.getState();
if (state === "SUCCESS") {
var result = response.getReturnValue();
// SOSL will always return the list in the order they were queried
component.set("v.accountList",result[0]);
component.set("v.contactList",result[1]);
component.set("v.oppList",result[2]);
component.set("v.leadList",result[3]);
}
else if (state === "INCOMPLETE") {
// do something
}
else if (state === "ERROR") {
var errors = response.getError();
if (errors) {
if (errors[0] && errors[0].message) {
console.log("Error message: " +
errors[0].message);
}
} else {
console.log("Unknown error");
}
}
});
$A.enqueueAction(action);
}
})
.THIS .customButton{
margin-top: 19px;
}
GlobalSearchController.apxc
margin-top: 19px;
}
public class GlobalSearchController {
@AuraEnabled(cacheable=true)
public static List<List<sObject>> getSearchResult(String searchKey){
List<List<sObject>> searchResult = [FIND :searchKey
IN ALL FIELDS RETURNING
Account (Id, Name, AccountNumber, Website),
Contact(Id, Name, Email, MobilePhone),
Opportunity(Id, Name, StageName, CloseDate),
Lead(Id, Name, Email, Company)];
return searchResult;
}
}
@AuraEnabled(cacheable=true)
public static List<List<sObject>> getSearchResult(String searchKey){
List<List<sObject>> searchResult = [FIND :searchKey
IN ALL FIELDS RETURNING
Account (Id, Name, AccountNumber, Website),
Contact(Id, Name, Email, MobilePhone),
Opportunity(Id, Name, StageName, CloseDate),
Lead(Id, Name, Email, Company)];
return searchResult;
}
}
Comments
Post a Comment