Friday 26 April 2013


Search Records In Salesforce Using Auto Complete Feature

To retrieve a particular record is a basic need of any kind of the business requirement in Salesforce, Salesforce has provided us an out of box functionality known as global search or we can say standard search functionality, What theGlobal Search does? Global Search Searches all record having the same name in all objects but sometime client requires some custom search which I have Implemented the same feature, Just customize as per client requirement the example given below It searches record in few object like Account, Case, Contact  Opportunity only this is a limited search as per the client need as I have discussed above, For example client does not want to search the Custom object having the same name of the Contact object name and wants auto suggest feature as well then we can implement this feature, Some client prefers tab feature to get record of different -2 sObject into the single page. Some client requires some more advance feature like Google search having the same feature of Google search like auto suggest feature. So here I have tried to developed same functionality, The auto complete feature is the most important and the complex logic as we all know, to achieve this functionality I have just written a piece of code in jQuery,JavaScript Remoting using Remoting notation in Apex and obviously Visualforce page having few static resource. Here is Video Demo link and the running Demo which you can run at your end.

Implementation of this functionality in your org you do not need to put extra effort you just need to copy and paste all component given above in a sequence like class should be created first before creating Visualforce page, when you creating Visualforce page at that time you need static resource please Download from here. So the sequence isClass > Static Resource > Visualforce page now you are ready to test at your end!

Apex Controller

global class AutoCompleteController {
    /*Global variables*/
    public String searchedRecordId { get; set; }
    public static list<ResultSet> searchedRecord {get;set;}    
    @RemoteAction
    global static ResultSet[] getRecords(String searchText) {
        //sObject List
        searchedRecord = new list<ResultSet>();
        //SOSL Text should be more then one charecter
        if(searchText.length() >0){
            //SOSL opretion to retrive records of the Account, Lead, Contact, Opportunity, Lead Objects you can add more.
            List<List<SObject>> searchList = [FIND :searchText IN ALL FIELDS RETURNING Account (Id, Name,Description), Contact(Id, Name,Description), Opportunity(Id, Name,Description), Lead(Id, Name,Description)];
            //Adding diffrent object's records in sobject list
            for(List<SObject> o:searchList){
                for(SObject s:o){
                    searchedRecord.add(new autoCompleteController.ResultSet(s));
                } 
            }
        }
        return searchedRecord;
    }
    /*getGlobalDescribed*/
    private static list<Schema.SObjectType> gd{
        get{
            if(gd == null){
                gd = Schema.getGlobalDescribe().values();
            }
            return gd ;
        }set;
    }
    /*Record Wrapper*/
    global class ResultSet{
        public String Id {get;set;} 
        public String Name{get;set;}
        public String Description {get;set;}
        public String sObjectName {get;set;}
        public ResultSet(sObject s){
            this.Id = s.Id;
            this.Name = s.get('Name')+'';
            this.Description = s.get('Description')+'';
            this.sObjectName = getsObjectNameById(Id);            
        }       
        global ResultSet(String Id,String Name,String Description){
            this.Id = Id;
            this.Name = Name;
            this.Description = Description;
            this.sObjectName = getsObjectNameById(Id);            
        }
        /*To get object Name by Id*/
        private String getsObjectNameById(String sObjectId){            
            if(sObjectId != null && sObjectId.trim() != ''){
                for(Schema.SObjectType objectInstance : autoCompleteController.gd){
                    if(objectInstance.getDescribe().getKeyPrefix() == sObjectId.subString(0,3)){    
                        return objectInstance.getDescribe().getLabel();
                    }
                }
            }
            return null;
        }
    }
}

VF Page :
<apex:page sidebar="false" controller="autoCompleteController" showHeader="false" >   
    <apex:stylesheet value="{!UrlFor($Resource.jQuery181,'/jquery/jquery-ui.css')}"/>
    <apex:includeScript value="{!UrlFor($Resource.jQuery181,'/jquery/jquery-1.8.js')}"/>
    <apex:includeScript value="{!UrlFor($Resource.jQuery181,'/jquery/jquery-ui.js')}"/>
    <style type="text/css">
        .ui-autocomplete-loading { 
            background: white url("{!$Resource.ajaxLoad}") right center no-repeat; 
        }
        .autocomplete{
            border-color: #929292 #D5D5D5 #D5D5D5 #929292 !important;
            border-style: solid;border-width: 1px !important;
            height: 18px !important;
            padding: 3px 10px;width: 534px !important;
        }
        .searchBtn{
            background: #FDCE3E !important;
            border: 1px solid #E5A716 !important;
            color: #434343 !important;
            height: 26px !important;
            margin-left: 7px !important;
            padding: 0 23px !important;
            font-size: 15px !important; 
            font-weight: bold !important;
        }
    </style>  
    <apex:form id="frmId">
        <center>
            <img src="http://dl.dropbox.com/u/29695913/images.jpg" style="float:left;height:50px;width:120px;" />
            <img src="http://dl.dropbox.com/u/29695913/images.jpg" style="float:right;height:50px;width:120px;" /><br />
            <b style="vertical-align: middle;"> Search Record: </b> 
            <apex:inputText id="autocomplete_textbox" styleClass="autocomplete"/> 
            <apex:commandButton value="Search" styleClass="searchBtn" reRender="frmId"/>             
        </center>
        <hr/>
        <apex:inputhidden value="{!searchedRecordId}" id="searchId"/>
        <apex:detail inlineEdit="false" subject="{!searchedRecordId}" showChatter="true" title="true"/>     
        <script type="text/javascript">
            //To remove conflictions of jquery
            var j$ = jQuery.noConflict();            
            j$(document).ready(function() {
                //Auto complete textbox component
                var autoCompleteTextBoxId = "input[id$='autocomplete_textbox']";
                var queryTerm;
                //auto complete method
                j$(autoCompleteTextBoxId).autocomplete({
                    minLength: 2,
                    source: function(request, response) {
                                queryTerm = request.term;
                                var sObjects;
                                var searchText = j$(autoCompleteTextBoxId).val();
                                AutoCompleteController.getRecords(searchText,function(result, event){
                                    if(event.type == 'exception') {
                                          alert(event.message);
                                    } else {
                                         sObjects = result;
                                         response(sObjects);
                                    }
                                });
                           },
                    focus: function( event, ui ) {
                            j$(autoCompleteTextBoxId).val( ui.item.Name );
                            return false;
                            },
                    select: function( event, ui ) {
                                j$(autoCompleteTextBoxId).val( ui.item.Name );                                
                                j$("input[id$='searchId']").val(ui.item.Id);
                                return false;
                            },
                 })
                 .data( "autocomplete" )._renderItem = function( ul, item ) {
                    var entry = "<a>" + item.Name;
                    j$.each("".split(",") , function(key, value) {
                        entry = entry + " <b>" + item.sObjectName +"</b>";
                    });
                    entry = entry + "</a>";
                    entry = entry.replace(queryTerm, "<b>" + queryTerm + "</b>");
                    return j$( "<li></li>" )
                        .data( "item.autocomplete", item )
                        .append( entry )
                        .appendTo( ul );
                };
            });            
        </script>
    </apex:form>
</apex:page>

2 comments:

  1. Here ajaxLoad is missing please can u share that one if u share that really helps me

    ReplyDelete
  2. Create a new static Resource named as ajaxLoad and upload an image and download it from here https://dl.dropboxusercontent.com/u/29695913/ajaxLoad.gif

    ReplyDelete

    Links