Sunday, January 20, 2019

Create a Lightning Component that Utilizes the Native Salesforce Global Search

I was recently working on a project where I needed to create Lightning Component that utilized the native global search to return items from several objects. I've done this in the past in a Visual Force page by redirecting the page to .../_ui/search/ui/UnifiedSearchResults?searchType=2&str=ACME+Corporation.

That works fine in Classic, but when I looked at the URL in Lightning I noticed that it's quite different.

../one/one.app#eyJjb21wb25lbnREZWYiOiJmb3JjZVNlYXJjaDpzZWFyY2hQYWdlI...

The first thing you may notice is that our search term is nowhere to be found. That's because it has been converted to a base64 encoded string value. In order to see how to pass our search terms, we need to decode this value and see what it consists of. You can do this online at sites like https://www.base64decode.org/.  Here's the decoded value.

{"componentDef":"forceSearch:searchPage","attributes":{"term":"ACME Corporation","scopeMap":{"resultsCmp":"forceSearch:resultsTopResults","label":"Top Results","type":"TOP_RESULTS","cacheable":"Y","id":"TOP_RESULTS","labelPlural":"Top Results"},"context":{"disableSpellCorrection":false,"disableIntentQuery":false,"permsAndPrefs":{"OrgPermissions.UnionAppNavSmartScope":false,"SearchUi.feedbackComponentEnabled":false,"SearchUi.searchUIPilotFeatureEnabled":false,"SearchExperience.LeftNavEnhancementEnabled":true,"Search.crossObjectsAutoSuggestEnabled":true,"Search.maskSearchInfoInLogs":false,"SearchUi.orgHasAccessToSearchTermHistory":false,"SearchResultsLVM.lvmEnabledForSearchResultsOn":true,"SearchUi.searchUIInteractionLoggingEnabled":false,"MySearch.userCanHaveMySearchBestResult":false,"SearchResultsLVM.lvmEnabledForTopResults":false,"MySearch.userCanHaveMySearch":false}},"groupId":"DEFAULT"},"state":{}}

Did you notice the bold 'term' attribute? That's where we want to put our search terms. Now that we know what the encoded string consists of and where to put our search terms all that's left to do is write some code. Let's take a look at how we can take this decoded JSON and use it in a Lightning Component.

In the first line of the code, we will declare our search term variable and assign the value 'ACME Corporation'.

var searchterm='ACME Corporation';

Next, we need to take the decoded JSON and add our search term.

var stringToEncode = '{"componentDef":"forceSearch:search","attributes":{"term":"'+searchterm+'"...

Now that we have the JSON ready, we need to Base64 encode it for use in the URL. For this example I created a variable that references the base64min.js library. In a real-world project, you may want to create a static resource for this.

var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234...
var searchcriteria = Base64.encode(stringToEncode);


And last but not least we redirect to the newly created search URL.

window.location.href='/one/one.app?source=alohaHeader#'+searchcriteria;

That's pretty much it! Here's the complete code snippet.

3 comments:

  1. Hey Tom, this has been super helpful, thanks for laying this all out.

    I am having one small problem though and I was curious to know whether it could be solved.

    Any time the text string "rn" is in the search, the r does not come through. For example "Learning Center" would populate through as "Leaning Center", "International" would become "Intenational".

    Any idea what the issue might be?

    ReplyDelete
  2. for anyone reading this in the future, there is an issue in the code that is literally replacing "rn" with "n" instead replacing \r\n with \n

    Replace this >e.replace(/rn/g,"n") with this >e.replace(/\r\n/g,"\n")

    ReplyDelete
  3. hey i tried it but my component that is rendering is getting freeze.. plz help ..

    ReplyDelete

Create a Lightning Component that Utilizes the Native Salesforce Global Search

I was recently working on a project where I needed to create Lightning Component that utilized the native global search to return items from...