Given
Have a form with 3 fields:
Zip(text field),
City(text field),
State(dropdown field).
Problem description
The user fills in the
Zip. Then, when starting to fill the
City, AutoComplete appear (from those that have filled
Zip). When/If one is selected the
Stateis filled automatically.
Solution
Nowadays there are many solutions for AJAX AutoComplete but i choosed the jQuery plugin from
devbridge.com. It seem to work very well and on the site are given details on how to use it.
So after incuding the library with
<script type="text/javascript" src="js/jquery.autocomplete.js"></script>
creating the form:
<form name="frm" action="someactionhere" method="post"><strong>Zip:</strong>?<input size="5" name="Zip" id="Zip" type="Text" value="#Zip#">
?<strong>City:</strong>?<input size="30" name="City" id="City" type="Text" value="#City#">
?<strong>State:</strong>?
<select name="State" id="State"><option value=""<cfif State eq "">selected</cfif>><cfloop query="getStates"><option value="#stateCode#"<cfif State eq stateCode>selected</cfif>>#stateName#
</cfloop></select></form>
and ading the JS:
<script language="JavaScript" type="text/javascript"><!--
var options, a;
jQuery(function(){
options =
{
serviceUrl:'index.cfm?action=buyers.getCity&loadContent=true&Zip='+$('##Zip').val()
, maxHeight:150
}
a = $('##City').autocomplete(options);
});
//--></script>
i started to test it in order to move farther.
And of course issues started. First problem was that the value from the Zip field was not passed to
index.cfm?action=buyers.getCity. Instead of the value just entered was passed the one that was in the field at the start, so it wasn't exactly what i needed. Maybe there exist an easier way, i don't know, but after quite long playing with it i came to the following solution. I created a new JS function
doAutoSuggest()and moved existing code into it and then made the call to it from
City's
onclick<form name="frm" action="someactionhere" method="post"><strong>Zip:</strong>?<input size="5" name="Zip" id="Zip" type="Text" value="#Zip#">
?<strong>City:</strong>?<input size="30" name="City" id="City" onclick="doAutoSuggest();" type="Text" value="#City#">
?<strong>State:</strong>?
<select name="State" id="State"><option value=""<cfif State eq "">selected</cfif>><cfloop query="getStates"><option value="#stateCode#"<cfif State eq stateCode>selected</cfif>>#stateName#
</cfloop></select></form><script language="JavaScript" type="text/javascript"><!--
function doAutoSuggest()
{
options =
{
serviceUrl:'index.cfm?action=buyers.getCity&loadContent=true&Zip='+$('##Zip').val()
, maxHeight:150
};
$('##City').autocomplete(options);
}
//--></script>
The script that retrieves cities data and pass it back on the AJAX call is:
<cfsetting showdebugoutput="No" enablecfoutputonly="Yes"><cfsilent><cfparam name="query" default=""><cfparam name="Zip" default=""><cfquery name="getCities" datasource="#application.dsn#">
Select distinct top 50 City + ', ' + st as ct, City + '|' + st as ct2
From zips
Where City like '#query#%'
<cfif Len(Zip)>
and zip = <cfqueryparam cfsqltype="CF_SQL_VARCHAR" value="#Zip#"></cfif>
Order by ct asc
</cfquery><cfset items = QuotedValueList(getCities.ct, ",")><cfset items2 = QuotedValueList(getCities.ct2, ",")></cfsilent><cfoutput>{ query:'#query#',suggestions:[#items#],data:[#items2#] }</cfoutput>
Note that the
Zipmay not be entered and so there may be
Citywith same name for different
State. Because of it, in the
suggestionsi return
city, statepairs and in
datai place same pairs but without the blank after the comma so that it to can be used for later easy processing.
What is left now is to make sure the
Cityand
Stateform fields are filled with the right values when something is selected in the AutoComplete dropdown.
Because the data come in a
city,stateformat we can split it and so
onSelectto place it in needed form fields. But because the
Stateis a dropdown element you can't just place the right value into it, you need to change the current selection. So, i created a JS function that taking as attribute the new value, will set it AND make the right selection.
function getOptionInde<img src="images/smiles/14.gif" border="0">opt)
{
document.frm.State.value=opt;
return document.getElementById('State').selectedIndex;
}
And so, the final code is as follow
<form name="frm" action="someactionhere" method="post"><strong>Zip:</strong>?<input size="5" name="Zip" id="Zip" type="Text" value="#Zip#">
?<strong>City:</strong>?<input size="30" name="City" id="City" onclick="doAutoSuggest();" type="Text" value="#City#">
?<strong>State:</strong>?
<select name="State" id="State"><option value=""<cfif State eq "">selected</cfif>><cfloop query="getStates"><option value="#stateCode#"<cfif State eq stateCode>selected</cfif>>#stateName#
</cfloop></select></form><script language="JavaScript" type="text/javascript"><!--
function doAutoSuggest()
{
options =
{
serviceUrl:'index.cfm?action=buyers.getCity&loadContent=true&Zip='+$('##Zip').val()
, maxHeight:150
, onSelect: function(value, data){ qwe=data.split("|");document.frm.City.value=qwe[0];document.frm.State.selectedIndex=getOptionInde<img src="images/smiles/14.gif" border="0">qwe[1]); }
};
$('##City').autocomplete(options);
}
function getOptionInde<img src="images/smiles/14.gif" border="0">opt)
{
document.frm.State.value=opt;
return document.getElementById('State').selectedIndex;
}
//--></script>
Enjoy!