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
Exactly, there is something amiss with the zips.php
I do not have mssql. I tried to adapt your query to mysql but have run into a brick wall there.
@Terry
Have you tried running the query against your database to ensure that it is correct?
And here is the states_abbrev.php
<?php
$return_arr = array();
$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ('Error connecting to mysql');
mysql_select_db($dbname);
/* If connection to database, run sql statement. */
if ($conn)
{
$fetch = mysql_query("SELECT * FROM smf_fips_states where state_name like '%" . $_GET['term'] . "%'");
/* Retrieve and store in array the results of the query.*/
while ($row = mysql_fetch_array($fetch, MYSQL_ASSOC)) {
$row_array['label'] = $row['state_name'];
$row_array['value'] = $row['state_abb'];
$row_array['stfips'] = $row['fips_code'];
array_push($return_arr,$row_array);
}
}
/* Free connection resources. */
mysql_close($conn);
/* Toss back results as json encoded array. */
echo json_encode($return_arr);
?>
Here is the zips.php (less connect info)
<?php
$return_arr = array();
$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ('Error connecting to mysql');
mysql_select_db($dbname);
/* If connection to database, run sql statement. */
if ($conn)
{
$fetch = mysql_query("SELECT * FROM smf_fips_counties WHERE state_code = '" . $_GET['filter'] . "' AND county_name LIKE '" . $_GET['term'] . "%'");
/* 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);
?>
Instead of mysql, everything was coded from your demo in mssql… I was able to correct connect to the database, however, there is something amiss in the query or something because I keep getting other errors. I tried to modify the query & such to match the states_abbrev.php file that you shared with us to learn from.
Thanks again.
@Terry
I can't see your states_abbrev.php or zips.php so it's difficult to fully solve. I know when I call your zips.php, it throw a mysql_connect error.
If anyone else that is reading this has any thought's or suggestions, I would greatly appreciate it
I am using Php 5.2.14, JSON 1.2.1, MySql 5.0.45
Thanks again for your most awesome website… I have it marked in my favorites
@Terry
I got it to run on my server. I think the error is in your states_abbrev.php and/or your zips.php.
@Terry
It was not the underscore in the javascript that I was trying to debug. It was using the underscore in the json string.
Oddly enough, the variable state_code is working correctly with the line:
$("#state_code").val(ui.item.stfips);
However, using the line:
secondary_url = "zips.php?filter=" + ui.item.stfips;
I get the ui.item is undefined error.
I think the problem is how to pass the variable to the "zips.php?filter="…
I made the changes that you suggested, (st_fips variable(s) to stfips), and I am still getting the same error message in firebug
I can email the actual .php files to you if it would be helpful in resolving this issue. I believe that I am very close but I just need a little assistance.
Thanks again for all of your help, it is truely appreciated.