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

Posted

in

,

by


Related Posts

Comments

19 responses to “AutoComplete Component in Visualforce using JQueryUI”

  1. Ravi Avatar
    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

    1. JitendraZaa Avatar
      JitendraZaa

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

      1. Ravi Avatar
        Ravi

        Am getiing the following error message

        1. Kalyan Avatar
          Kalyan

          Hi Jitendra thanks for sharing this but when I use the same code it does not give me any values instead just a circle comes and goes off with out any values. Can you please help me

          1. Jitendra Zaa Avatar

            Do you see any error in Javascript console ?

  2. Muneendar Avatar
    Muneendar

    Hi.I have a scenario that when i enter the the pincode(Zipcode) need to populate State and Country i their respective fields

  3. Muhammad Affu Avatar
    Muhammad Affu

    Error:-
    Failed to load resource: the server responded with a status of 404 (Not Found)

    https://ap1.salesforce.com/17181/logo180.png

  4. Anshul Avatar
    Anshul

    Hi Jitendra,

    everything works like a charm for me but I need to capture the account Id somehow, so that I can use it in my controller. and I do not want to show that Account in when we search for an account?

    is there any quickfix?

  5. Ashish Thakur Avatar
    Ashish Thakur

    Hi Jitendra,

    Can I use this for multiple fields of same object on a VF page?

    E.g:

    Field 1 (AutoComplete)
    Field 2 (AutoComplete)
    Field 3 (AutoComplete)
    Field 4 (AutoComplete)

    Thanks,
    Ashish

    1. Jitendra Zaa Avatar

      Yeah, you can.

  6. […] service cloud can be done using callouts consuming Azure Search Rest Api, a good example can be this , just change the json generation part so that instead of making queries on Salesforce accounts you […]

  7. […] Zaa has a fantastic blog post on creating an autocomplete lookup field component for Visualforce pages.  The only issue with […]

  8. Rajesh Avatar
    Rajesh

    Hi Jitendra, thanks a lot for sharing this Information. Need you help in understanding the {!JSON} part in VF page. I replaced the JSON with the code that you have provided in other forum page but i am not getting the desired result.
    I am receiving “Undefined” as the result.

  9. saurabh Avatar
    saurabh

    Hi Jitendra.

    I am getting the following error. the ajax effect for loading is working fine.

    AutoCompleteDemo?core.apexpages.request.devconsole=1:1 Invalid ‘X-Frame-Options’ header encountered when loading ‘https://testsaurabh-dev-ed.my.salesforce.com/apexpages/devmode/devConsoleViewStateMetadataReceiver.apexp?sfdcIFrameOrigin=https%3A%2F%2Ftestsaurabh-dev-ed–c.ap5.visual.force.com’: ‘ALLOW-FROM https://testsaurabh-dev-ed–c.ap5.visual.force.com‘ is not a recognized directive. The header will be ignored.

    1. Abhishek Anand Avatar
      Abhishek Anand

      Hey Saurabh,

      Did you find any solutoin for this i am also facing the same issue.
      Please share how to fix this.

  10. Abhishek Anand Avatar
    Abhishek Anand

    Hi Jitendra,

    I am facing the similar problem as Saurabh in the above comment which is :-

    “AutoCompleteDemo?core.apexpages.devmode.url=1&core.apexpages.request.devconsole=1:1 Invalid ‘X-Frame-Options’ header encountered when loading ‘https://sfdfunky-dev-ed.my.salesforce.com/apexpages/devmode/devConsoleViewStateMetadataReceiver.apexp?sfdcIFrameOrigin=https%3A%2F%2Fsfdfunky-dev-ed–c.eu14.visual.force.com’: ‘ALLOW-FROM https://sfdfunky-dev-ed–c.eu14.visual.force.com‘ is not a recognized directive. The header will be ignored.”

    once i bypass the above error by disabling CORS in chrome(not a practical solution for the client org but for testing), i am also facing another issue which is mentioned below:-

    HTTP-Based Public Key Pinning is deprecated. Chrome 69 and later will ignore HPKP response headers. (Host: c.ap1.visual.force.com)

    and this error seems to be a chrome ( firefox, opera also that support HPKP) specific error from chrome version 69 . This seems to be a security update that has been initiated by google and soon other browsers would see this coming. Is there a way to handle this issue for salesforce and would there be an impact of this on the existing lightning component, please shed some light.

    Meanwhile i am also trying to find a solution for this, your support would be very helpfull

  11. Rob Avatar
    Rob

    Hi, Thank you for posting this article. It was a huge help! I tried to expand this logic into a force.com site and I am receiving this error:
    Access to XMLHttpRequest at ‘URL’ from origin ‘URL’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Any thoughts? I tried adding the origin URL into the CORS settings in SF.

  12. […] Zaa has a fantastic blog post on creating an autocomplete lookup field component for Visualforce pages.  The only issue I have […]

  13. […] Zaa has a fantastic blog post on creating an autocomplete lookup field component for Visualforce pages.  The only issue I […]

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Discover more from Jitendra Zaa

Subscribe now to keep reading and get access to the full archive.

Continue Reading