AutoComplete Component in Visualforce using JQueryUI

In this tutorial, I am going to explain very Simple AJAX and JSON based Auto Complete component with the help of JQuery UI. First I am assuming that you already have Static Resource of named “AutoCompleteWithModal”. This Static resource has all images, CSS and JQuery library needed to implement this component.

In one of my old post, I have already explained that how to generate JSON in Visualforce page. So Considering same article I have create Visualforce page named “Account_JSON” which returns list of Accounts on basis of text entered in input field.

Live Demo :

try searching “gen” or “edg” and spacebar, It will load account after one space.

Visualforce Account_JSON :

<apex:page Controller="AccountJSONCreator" contentType="application/x-JavaScript; charset=utf-8" showHeader="false" standardStylesheets="false" sidebar="false">
{!JSON}
</apex:page>

Controller AccountJSONCreator :

public with sharing class AccountJSONCreator {

    public String getJSON()
    {
        String AccountName = Apexpages.currentPage().getParameters().get('AccName');
        List<AccountWrapper> wrp = new List<AccountWrapper>();
        for (Account a : [Select a.Id, a.Website, a.Name, a.BillingCountry, a.BillingCity
                            From
                                Account a
                            WHERE Name Like : '%'+AccountName+'%' ]) {
               AccountWrapper w = new AccountWrapper (a.Name, nullToBlank (a.BillingCountry), nullToBlank (a.BillingCity));
               wrp.add(w);
            }
        return JSON.serialize(wrp);
    }

    public String nullToBlank(String val)
    {
        return val == null ?'':val;
    }

    public class AccountWrapper
    {
        String AccName,BillingCountry,BillingCity;

        public AccountWrapper(String aName, String bCountry, String bCity)
        {
            AccName = aName;
            BillingCountry = bCountry;
            BillingCity = bCity;
        }
    }

    static testMethod void AccountJSONCreatorTest() {
        AccountJSONCreator obj = new AccountJSONCreator();
        obj.getJSON();
    }
}

Now let’s create a Component which will make AJAX request to above visualforce page “Account_JSON” and Parse JSON page using JQuery.

Component Autocomplete_Component :

<apex:component>
 <apex:attribute name="ComponentLabel" description="Label of Component"
                    type="String" required="true"/>

<apex:stylesheet value="{!URLFOR($Resource.AutoCompleteWithModal, '/JQueryUI/css/ui-lightness/jquery-ui-1.8.17.custom.css')}"/>
<apex:includeScript value="{!URLFOR($Resource.AutoCompleteWithModal, '/JQueryUI/js/jquery-1.7.1.min.js')}"/>
<apex:includeScript value="{!URLFOR($Resource.AutoCompleteWithModal, '/JQueryUI/js/jquery-ui-1.8.17.custom.min.js')}"/>
<apex:stylesheet value="{!URLFOR($Resource.AutoCompleteWithModal, '/JQueryModal/css/basic.css')}"/>

<style type="text/css">
    .ui-autocomplete-loading { background: white url('{!URLFOR($Resource.AutoCompleteWithModal, 'AjaxLoad.gif')}') right center no-repeat; }
</style>

{!ComponentLabel} <apex:inputText id="theTextInput"/>

<script type="text/javascript">
//$ac - AutoComplete

$ac = jQuery.noConflict();

function getLoadingImage()
{
    var loadImagURL = "{!URLFOR($Resource.AutoCompleteWithModal, 'BigLoad.gif')}";
    var retStr = ['<img src="', loadImagURL ,'" title="loading..." alt="loading..." class="middleAlign" />'];
    return retStr.join("");
}

var sourcePage = 'https://c.ap1.visual.force.com/apex/Account_JSON?core.apexpages.devmode.url=0';

 $ac(function() {
        var txtVal =  $ac('[id="{!$Component.theTextInput}"]');
        //This method returns the last character of String
        function extractLast(term) {
            return term.substr(term.length - 1);
        }

        $ac('[id="{!$Component.theTextInput}"]').autocomplete({
            source: function( request, response ) {

                //Abort Ajax
                var $this = $ac(this);
                var $element = $ac(this.element);
                var jqXHR = $element.data('jqXHR');
                if(jqXHR)
                    jqXHR.abort();

                $ac('[id="{!$Component.theTextInput}"]').addClass('ui-autocomplete-loading');
                //prompt('',sourcePage+'&key='+txtVal.val());
                $element.data('jqXHR',$ac.ajax({
                    url: sourcePage+'&AccName='+txtVal.val(),
                    dataType: "json",
                    data: {
                    },
                    success: function( data ) {
                        response( $ac.map( data , function( item ) {
                            return {
                                label: '<a>'+
                                item.AccName+"<br />"+
                                '<span style="font-size:0.8em;font-style:italic">'
                                +item.BillingCity+', '+item.BillingCountry+
                                "</span></a>",
                                value: item.AccName
                            }
                        }));
                    },
                    complete: function() {

                        //This method is called either request completed or not
                        $this.removeData('jqXHR');

                        //remove the class responsible for loading image
                        $ac('[id="{!$Component.theTextInput}"]').removeClass('ui-autocomplete-loading');
                    }
                })
                );

            },
            search: function() {
                /*
                // If last character is space
                    var term = extractLast(this.value);
                    if(term == " ")
                    {
                        return true;
                    }
                */

                //If String contains at least 1 space
                if (this.value.indexOf(" ") >= 0)
                {
                    $ac('[id="{!$Component.theTextInput}"]').autocomplete('option', 'delay', 500);
                    return true;
                }
                return false;
            },
            focus: function() {
                // prevent value inserted on focus
                return false;
            },
            select: function(event, ui) {
                var selectedObj = ui.item;
                //alert(selectedObj.compId);
                //getCompanyDetail(selectedObj.compId);
                return true;
            }
        }).data("autocomplete")._renderItem = autoCompleteRender;

    });

function autoCompleteRender(ul, item) {
    return $ac("<li></li>").data("item.autocomplete", item).append(item.label).appendTo(ul);
}

</script>
</apex:component>

Now Visualforce page, which will host above Component.

Viusalforce Page : AutoCompleteDemo

<apex:page >
    <apex:form >
        <c:autocomplete_component ComponentLabel="Enter Account Name : "/>
    </apex:form>
</apex:page>
JQuery UI and JSON based AJAX AutoComplete Component in Salesforce

JQuery UI and JSON based AJAX AutoComplete Component in Salesforce

Download Static resource – AutoCompleteWithModal

Related posts

  • Ravi

    hi. I tried this code in my developer org it is not working. When i checked this in the Mozilla firefox debugger. it shows me an error message
    TypeError: this._container is undefined

    Could you please help me with this?

    Thanks
    Ravi sankar

    • JitendraZaa

      On which line you are getting error ? Can u please screenshot ? i have not used “this._container” any where.

      • Ravi

        Am getiing the following error message