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>

Download Static resource – AutoCompleteWithModal
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
On which line you are getting error ? Can u please screenshot ? i have not used “this._container” any where.
Am getiing the following error message
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
Do you see any error in Javascript console ?
Hi.I have a scenario that when i enter the the pincode(Zipcode) need to populate State and Country i their respective fields
Error:-
Failed to load resource: the server responded with a status of 404 (Not Found)
https://ap1.salesforce.com/17181/logo180.png
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?
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
Yeah, you can.
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.
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.
Hey Saurabh,
Did you find any solutoin for this i am also facing the same issue.
Please share how to fix this.
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
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.