As requested, this post covers using one jquery autocomplete to populate another jquery autocomplete on the same page. This example will use a jquery autocomplete to choose a state then, based on the state, another jquery autocomplete will be populated with zip codes for that state. Basically, the state chosen gets used as a filter in the query for the second autocomplete.
Form
The form for the examples is the same with fields for the autocompletes (state and zip_code) plus input fields for the values returned by the autocompletes.
<form action="YOUR-FILE-HERE" method="post"> <fieldset> <legend>jQuery UI Multi-Autocomplete Example</legend> <p>Start typing the name of a state or territory of the United States</p> <p><label for="state">State (abbreviation in separate field): </label> <input type="text" id="state" name="state" /> <input readonly="readonly" type="text" id="abbrev" name="abbrev" maxlength="2" size="2"/></p> <input type="hidden" id="state_id" name="state_id" /> <p><label for="zip_code">Zip (only Zips from state selected above): </label> <input type="text" id="zip_code" name="zip_code" maxlength="5" size="15" /></p> <p class="ui-widget"><label for="city">City:</label> <input readonly="readonly" type="text" id="city" name="city" /></p> <p><input type="submit" name="submit" value="Submit" /></p> </fieldset> </form>
jQuery
The jquery is also the same for each example. Notice that the zip_code field is initially disabled to prevent entry before the results have been filtered.
Also, note that the source and secondary URL extension will have to be modified depending on the language you are using.
$(function() {
//clear values on refresh
$('#abbrev').val("");
$('#city').val("");
$("#zip_code").attr('disabled', true);
$("#state").autocomplete({
source: "states.[cfm|aspx|php]",
minLength: 2,
select: function(event, ui) {
$('#state_id').val(ui.item.id);
$('#abbrev').val(ui.item.abbrev);
$("#zip_code").attr('disabled', false);
},
change: function(event, ui){
secondary_url = "zips.[cfm|aspx|php]?filter=" + ui.item.abbrev;
$("#zip_code").autocomplete("option", "source", secondary_url);
}
});
$("#zip_code").autocomplete({
source: "",
minLength: 2,
select: function(event,ui){
$('#city').val(ui.item.city);
}
});
});
Processing
Each programming language differs slightly in the processing. And, since there are hundreds of zip codes per state, the results are limited to 20. If the zip code desired is not returned in the top 20 after entering the minimum 2 characters, typing more characters will yield more precise results.
PHP
Refer to the example for using the jquery autocomplete with PHP. The code below only shows the zip select database processing.
PDO version
/* Connection vars here for example only. Consider a more secure method. */
$dbhost = 'YOUR_SERVER';
$dbuser = 'YOUR_USERNAME';
$dbpass = 'YOUR_PASSWORD';
$dbname = 'YOUR_DATABASE_NAME';
try {
$conn = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass);
}
catch(PDOException $e) {
echo $e->getMessage();
}
$return_arr = array();
if ($conn)
{
$ac_filter = $_GET['filter'];
$ac_term = $_GET['term']."%";
$query = "SELECT zip, city FROM zips WHERE abbrev = :filter AND zip like :term LIMIT 20";
$result = $conn->prepare($query);
$result->bindValue(":filter",$ac_filter);
$result->bindValue(":term",$ac_term);
$result->execute();
/* Retrieve and store in array the results of the query.*/
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
$row_array['label'] = $row['zip'] . " " . $row['city'];
$row_array['value'] = $row['zip'];
$row_array['city'] = $row['city'];
array_push($return_arr,$row_array);
}
}
/* Free connection resources. */
$conn = null;
/* Toss back results as json encoded array. */
echo json_encode($return_arr);
Non-PDO version
<?php
$dbhost = 'YOUR_SERVER';
$dbuser = 'YOUR_USERNAME';
$dbpass = 'YOUR_PASSWORD';
$dbname = 'YOUR_DATABASE_NAME';
$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ('Error connecting to mysql');
mysql_select_db($dbname);
$return_arr = array();
if ($conn)
{
$fetch = mysql_query("SELECT zip, city FROM zips WHERE abbrev = '" . mysql_real_escape_string($_GET['filter']) . "' AND zip like '" . mysql_real_escape_string($_GET['term']) . "%' LIMIT 20");
/* Retrieve and store in array the results of the query.*/
while ($row = mysql_fetch_array($fetch, MYSQL_ASSOC)) {
$row_array['label'] = $row['zip'] . " " . $row['city'];
$row_array['value'] = $row['zip'];
$row_array['city'] = $row['city'];
array_push($return_arr,$row_array);
}
}
/* Free connection resources. */
mysql_close($conn);
/* Toss back results as json encoded array. */
echo json_encode($return_arr);
?>
ASP.NET
Refer to the complete example of using the jquery autocomplete with ASP.NET for more information.
<%@ Page Language="VB" Debug="false" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<script runat="server">
Dim serializer As JavaScriptSerializer
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
serializer = New JavaScriptSerializer()
Response.Write(JSONData(Request.QueryString("Term")))
End Sub
Public Class Zip
Public zipcode As String
Public label As String
Public value As String
Public city As String
End Class
Private Function JSONData(ByVal term As String) As String
Dim zipArray As New ArrayList
Dim index As Integer = 0
Dim objConn As New SqlConnection("Server=YOUR-SERVER;Database=YOUR-DATABASE;User ID=YOUR-USERID;Password=YOUR-PASSWORD")
Dim myds As New DataSet("Zips")
objConn.Open()
Dim adapter As New SqlDataAdapter("SELECT TOP 20 zip, city FROM zips WHERE abbrev = @ac_filter AND zip like @ac_term + '%'", objConn)
adapter.SelectCommand.Parameters.Add("@ac_filter", SqlDbType.VarChar)
adapter.SelectCommand.Parameters("@ac_filter").Value = Request.QueryString("filter")
adapter.SelectCommand.Parameters.Add("@ac_term", SqlDbType.VarChar)
adapter.SelectCommand.Parameters("@ac_term").Value = term
adapter.Fill(myds, "Zips")
For Each dr As DataRow In myds.Tables(0).Rows
Dim zp As New Zip()
zp.label = dr("zip").ToString() & " " & dr("city").ToString()
zp.value = dr("zip").ToString()
zp.city = dr("city").ToString()
zipArray.Add(zp)
Next
objConn.Close()
Return serializer.Serialize(zipArray)
End Function
</script>
ColdFusion
Refer to the complete example of using the jquery autocomplete with ColdFusion for more information.
ColdFusion’s serializeJSON function has an odd bug that will not let you send numbers as strings. This turns the zip codes into numbers which we do not want. To workaround this, I added a space in front of the zip code then removed it from the JSON output with the Replace function. Not the best idea, but it works.
<cfset returnArray = ArrayNew(1) />
<cfquery name="qryStates" dataSource="autocomplete">
SELECT TOP 20 zip, city FROM zips WHERE abbrev = '<cfqueryparam value="#URL.filter#" cfsqltype="cf_sql_varchar">' AND zip like '<cfqueryparam value="#URL.term#" cfsqltype="cf_sql_varchar">%'
</cfquery>
<cfloop query="qryStates">
<cfset zipsStruct = StructNew() />
<cfset zipsStruct["label"] = ToString(zip) & " " & city />
<!---Had to add leading space to prevent serializeJSON from turning zip into number--->
<cfset zipsStruct["value"] = " " & zip />
<cfset zipsStruct["city"] = city />
<cfset ArrayAppend(returnArray,zipsStruct) />
</cfloop>
<cfoutput>
<!---replaced all spaces after quotes with just quotes in JSON to remove leading space applied to zip--->
#Replace(serializeJSON(returnArray),'" ','"',"all")#
</cfoutput>
Very important information below. Please read and understand before expecting the autocomplete to work properly.
Explanation on the ‘label’ and ‘value’ fields from the jQuery UI site:
“The local data can be a simple Array of Strings, or it contains Objects for each item in the array, with either a label or value property or both. The label property is displayed in the suggestion menu. The value will be inserted into the input element after the user selected something from the menu. If just one property is specified, it will be used for both, eg. if you provide only value-properties, the value will also be used as the label.”
Recommended:
If this post helped you out, please consider donating to help pay the hosting fees. 100% of the donations go to the web host.

RSS
Twitter
41 Comments
thank you Jen
it works now I just added the file zips.php as shown in your tutorial. but I changed my strategy!. I now use a simple autocomplete with a list of city / zip code like this. this solves my problem
Congratulations for your site and if you love the guitar play my "bigrock" playlist!
http://www.deezer.com/music/playlist/bigrock-52992764?provider=website
Marc
Merci Jen ,
I could run your script.
http://serna.alwaysdata.net//jensbit_autosuggest/jenform.php
but I prefer to use your other script "jQuery UI Autocomplete Widget with PHP and MySQL"
look here, it works but I have a small problem to fit perfectly.
http://localhost/autosuggest/jensbit_autosuggest/index.php
thank you for your help
@Marc
The zips.php is right inside the post. The states.php is the same one from the previous autocomplete post.
This is a continuation of that post.
hello Jen
merci pour ton super script
je n'arrive pas à adapter ton script ( i am a rooky ). j'ai un script qui fonctionne bien pour le résultat que je veux mais c'est une liste déroulante ( trop de villes) . j'aimerais remplacer par une auto complète.
regarde ici
http://serna.alwaysdata.net/liste_drop/form9.php
je peux te donner mes sources si tu en a besoin
( i'ts only rock roll but i like it !)
Hi Jen,
very good joob !
I can not adapt your script. I have a script that works well for the result I want but it's a combo (too many cities). I would replace it with a autocomplete
look here
http://serna.alwaysdata.net/liste_drop/form9.php
I can give you my sources if you need it
(I'ts only rock roll but i like it!)
hello jen,
I try to adapt your script but i have little ( big ?) difficult
I copied the source code but it does not work.
What is the code page for "zips.php" and "states.php"
thank you very much Jen
@Jen
Replacing the source for the .js files got rid of all of the errors. Unfortunately, it still isn't working correctly. I will re-check all of my code to see if I got something out of sync & let you know how it goes.
Thanks again
(( GO RAYS !! ))
@Terry
It is working now for you. You just need to make sure that the state_fips variables are all named correctly. We removed the underscore at one point, so be sure that the variable names are set to what the code is looking for.
Go Rays.
@Terry
Try replacing your javascript (jquery) includes to this:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
That will make sure you have the latest. Again, I got your code to run fine on my server. The only thing I can think of is the scripts. I use the script links above.
Here's an update… I corrected the zips.php
Here is the code:
<?php
$return_arr = array();
$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ('Error connecting to mysql');
mysql_select_db($dbname);
echo ("Connected");
/* If connection to database, run sql statement. */
if ($conn)
{
$fetch = mysql_query("SELECT * FROM smf_fips_counties WHERE state_fips = '" . $_GET['filter'] . "' AND county_name LIKE '" . $_GET['term'] . "%'") or die(mysql_error());
/* Retrieve and store in array the results of the query.*/
while ($row = mysql_fetch_array($fetch, MYSQL_ASSOC)) {
$row_array['label'] = $row['county_name'];
$row_array['value'] = $row['county_name'];
$row_array['state_fips'] = $row['state_fips'];
$row_array['county'] = $row['county_name'];
array_push($return_arr,$row_array);
}
}
/* Free connection resources. */
mysql_close($conn);
/* Toss back results as json encoded array. */
echo json_encode($return_arr);
?>
I added:
or die(mysql_error());
to the end of the query. It reported that I had one of the column names misspelled. I have since corrected it.