AutoComplete Component in Salesforce using JQuery

Hello everyone. Recently i came across one requirement where we need to have Auto Complete functionality in Visualforce Page so i used apex:inputText component with list attribute and that renders the List of Objects as dropdown as well as Auto Complete.  But due to some limitations with apex:inputText and i planned to use JQuery’s Autocomplete functionality and thats works great with Salesforce. So i though of sharing that implementation with you guys.

For AutoComplete functionality i have created one AutoComplete Component that we can use in any VisualForce Page and we can easily read data from AutoComplete component in our VisualForce page using JavaScript. In AutoComplete component i have created VisualForce Component and VisualForce Controller. In VisualForce Component i have used JQuery CSS & JS Files that i have upload in Static Resource.

  <apex:stylesheet value="{!URLFOR($Resource.AutoComplete,'/jquery-ui.css')}"/>
    <apex:includeScript value="{!URLFOR($Resource.AutoComplete,'/jquery-1.12.4.js')}"/>
    <apex:includeScript value="{!URLFOR($Resource.AutoComplete,'/jquery-ui.js')}"/>

Then i have created one input field and binded that input field with a String variable in my controller.

 <apex:pageBlockSection collapsible="false" title="Search Account" >
                <input  id="accountSearch" value="{!searchTerm}" />    
    </apex:pageBlockSection>

Then in body itself i have used Script tag to write my JQuery code to create AutoComplete functionality . In this i have used pre defined function of JQuery which is used to add AutoComplete functionality to a input field. For data that is to be visible in suggestion i have used Remote Action (Apex function that can be accessed from JavaScript Code) function in my Controller Apex Class. And for selection and focus i have added listeners that changes the value of the input field. And at the same time selection function calls another function which needs to available in our VisualForce parent page in which we have added this component.

 <script>
        $(function(){  
            $("#accountSearch").autocomplete({  
               minLength: 2,  
               source: function(request, response){  
                    var searchString = request.term;  
                    AutoCompleteComponentController.getSearchSuggestions(searchString, function(result, event){  
                         if(event.status){  
                              if(typeof result === 'undefined' || result.length <=0){  
                                   response(['No Record Found']);  
                              }else {  
                                   response(result);  
                              }  
                         }else {  
                              response([]);  
                         }  
                    },  
                    {escape: true}  
                    );  
               },  
               select: function(event, ui){  
                    if(ui.item.label != 'No Record Found'){  
                        $("#accountSearch").val(ui.item.label);
                        showAccountDetail(ui.item.value); 
                    }  
                    return false;  
               },  
               focus: function( event, ui ) {  
                    $("#accountSearch").val(ui.item.label);  
                    return false;  
               }  
           });  
  });  
  </script>

On selection of suggestion item i am setting the value of input field as the selected value and at the same time calls the showAccountDetail method which is available in my VisualForce parent page

select: function(event, ui){  
                    if(ui.item.label != 'No Record Found'){  
                        $("#accountSearch").val(ui.item.label);
                        showAccountDetail(ui.item.value); 
                    }  
                    return false;  
               },

 

On controller side i am having a Wrapper Class for storing the Label that is visible to user and value that contains the Id of that Account.

 public class AccountWrapper {  
      public String label { get; set; }  
      public String value { get; set; }  
      public AccountWrapper (String label, String value){  
           this.label = label;  
           this.value = value;  
      }  
  }

and also having a remoteAction method that executes SOSL Query on Account object and returns the List of AccountWrapper records.

 @RemoteAction  
  public static List<AccountWrapper> getSearchSuggestions(String searchString){  
       List<AccountWrapper> accountWrappers = new List<AccountWrapper>();  
       List<List<sObject>> searchObjects = [FIND :searchString + '*' IN ALL FIELDS RETURNING Account (Id, Name)];  
       if(!searchObjects.isEmpty()){  
            for(List<SObject> objects : searchObjects){  
                 for(SObject obj : objects){
                      if(obj.getSObjectType().getDescribe().getName().equals('Account')){  
                           Account acct = (Account)obj;  
                           accountWrappers.add(new AccountWrapper(acct.name, acct.Id));  
                      } 
                 }  
            }  
       }  
       return accountWrappers;  
  }

 

To use this complete component and to access data of selected Account i have created one VisualForce page and one Controller for that VisualForce page. In VisualForce page i am calling the VisualForce component of AutoComplete we just created

<c:AutoCompleteComponent />

And the i am having one actionFunction that will render the UI and also calls one method to get details about selected Account from Database.

<apex:actionFunction name="showInfoForAccount" action="{!showAccountDetail}" reRender="form">  
                     <apex:param assignTo="{!selectedAccountId}" name="selectedAccountId" value=""/>   
            </apex:actionFunction>

This actionFuntion get called from the showAccountDetail javascript method we have implemented in our VisualForce page

<script>
         function showAccountDetail( accountId){
            showInfoForAccount(accountId);
         }
    </script>

This javaScript is again called from the component on selection of a record from the AutoComplete field. So we can say when someone selects any record from AutoComplete Field it fires the select method in our component and from that select method we calling showAccountDetail method of our VisualForce page in which we have added the component. Then from showAccountDetail method we are calling showInfoForAccount actionFunction that is also in the same VisualForce Page and this actionFunction executes SOQL query on the selected accountId and returns the Object and that object is rendered on the UI.

In Controller i am using only one method that is called from actionFunction to get record details from database

public void showAccountDetail(){
      selectedAccount = [Select Id,Name,Website,AccountNumber,Phone ,Fax FROM Account WHERE Id = :selectedAccountId LIMIT 1];
      accountDetailVisible= true;
  }

 

 

Screen shots :

 

Video Walk through :

Static Resource : 

Download autocomplete jquery static resource from below url : http://blog.ertarandeep.com/AutoComplete_jquery.zip

9 Comments

  1. Hi Tarandeep, Thanks for the post. We recently used this feature in our app and our app did not pass the salesforce security review. I am attaching the comments below, would you know if there is way to fix this issue so that our app passes the review. Thanks in advance.
    ******
    Issue Description
    When new vulnerabilities are discovered in software, it is important to apply patches and update to a version of the software for which the vulnerability is fixed.
    Attackers can create attacks for disclosed vulnerabilities very quickly, so security patches should be deployed as soon as they are available.
    CWE: 937
    Finding 1 of 1
    File
    /Typeahead/jquery-1.10.2.min.js
    Notes
    jquery 1.10.2.min has known vulnerabilities: severity: medium; issue: 2432, summary: 3rd party CORS request may execute; https://github
    org/jquery/test/
    File
    /JQueryUI/jquery-ui/jquery-ui.js
    Notes
    jquery-ui-dialog 1.12.0-rc.2 has known vulnerabilities: severity: high; bug: 281, summary: XSS Vulnerability on closeText option; https
    jquery-ui-autocomplete 1.12.0-rc.2
    jquery-ui-tooltip 1.12.0-rc.2
    File
    /JQueryUI/jquery-ui/external/jquery/jquery.js
    Notes
    jquery 1.11.3 has known vulnerabilities: severity: medium; issue: 2432, summary: 3rd party CORS request may execute; https://github.com
    org/jquery/test/

  2. Hi Tarandeep,

    Thanks a lot for posting this tutorial and i was trying for this functionality since many days. Your explanation was really good. It’s a common requirement but there are no such good help from forums. Please keep post with new functionalities.

    Could you please share the static resources links you uploaded, i have followed the steps you explained but not working for me, I think it’s because of incorrect Jquery static resource.

    Thanks in advnance,
    Suman

  3. Hi,

    Its nice example, It will be great if you provide static resource files.

    Regards
    Harshad Dani (dani22harshad@gmail.com)

Leave a Reply

Your email address will not be published.


*