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 :

Be the first to comment

Leave a Reply

Your email address will not be published.


*