AJAX ZIP Code Spiffiness
I had to register at a kiosk before renting my snowboard at Park City last weekend. I noticed a nifty trick they implemented in the sign-up application: Normally you would expect to fill in your address fields in the following order:
- City
- State
- ZIP Code
That’s natural because that’s the way you write it on an envelope when you send an actual letter. But in this registration application they appeared in this order:
- ZIP Code
- City
- State
This confused me at first- I thought maybe I tabbed over too many times or they screwed up the form somehow. But as soon as I filled in the ZIP Code, the City and State were automatically filled out for me. How clever. Since I usually have to enter my zip code in forms like this anyways, and the city and state are trivially determined by ZIP Code, why the hell do they always ask me for that redundant information?
(Probably because they’re lazy, and furthermore most users have gotten so accustomed to typing this stuff in that it’s turned into muscle memory/reflex action.)
I don’t know if the kiosk app was web-based or not, but regardless I decided to try and implement something like it for use on the interweb and share the end result with anybody who wants to use it.
So I set about the following plan:
Step 1 Get a database of Zip Codes, Cities and States: Check – this one has lat/long coordinates too but I don’t really need them (Google Maps Hack anyone?). Thanks, dude for putting that up there. Everybody else I found wants to charge for that shit. The US Post Office should have a free CSV file but I couldn’t find one on their site.
Step 2 Decide how to store the ZIP Code data on the server. There are several options here.
- Keep it all in MySQL and query the database on every request.
- Keep it all in a flat CSV file and load and search it on every request.
- Keep it N separate, smaller CSV files and mod the requested zipcode by N to figure out which file to load (the bucket approach).
- Keep it all in a hard-coded hash map declaration in a ginormous php file. :)
I went with option 2 in the interest of doing the simplest thing that could possibly work. I might look into option 3 if my server gets pegged. Option 4 is a joke. Sort of.
Step 3 Figure out the AJAXiness regarding the data transmitted over http. I decided to have a single server-side script called zip.php. It takes one argument- the zipcode, and returns a chunk of javascript that looks for INPUT tags named city and state, then sets their values accordingly.
Step 4 Bells, but no whistles. (It’s getting late.) Add some spinners like this:
to indicate that Stuff is happening in The Background. Added the code to turn them on when zip.php starts loading, and then turn them off once zip.php finishes loading.
Step 5 Spend more time writing about it than I spent writing it.
Here’s a .zip of the source code if you’re interested: ajax-zipcode
Simply unpack it in some directory on your web server to install it. I’ve only tested it out on Safari and Firefox on my mac, so I’ve tried this out on the latest Mac: Safari and Firefox and PC: IE and Firefox. Please let me know if it blows up or craps out on your configuration.
Or of course you can check out the online demo if that’s the kind of thing that gets you hot and bothered.
I had a summer job as a teenager taking subscription orders over the phone. Naturally the computer did the zip-code lookup thing, and in our script, we asked for the zip code before city/state. About one person in ten would stop me to ask “don’t you want to know city and state?” so it probably would have been easier just to go by the conventional order. And in some cases, the zip code lookup would be wrong, or simply wouldn’t return the name of the small town people prefer to say they live in.
But when users are typing in the data, yeah, this makes more sense. Nice.
Adam Rice
23 Feb 06 at 9:45 am
As long as you were fielding the calls rather than making them, that’s cool ;-)
And even if this thing gets the city/state wrong, you can always go back and change what it automatically entered for you.
banksean
23 Feb 06 at 9:51 am
Okay, this is totally geeky.
At my job we deal with a lot of data quality aspects of mailing data. Multiple cities can return from single zip codes since some places have different cities within other cities… so zip code 90909 (Veronica Mars forever wohoo!) might be both Neptune, CA and Los Angeles, CA.
So you’d still need to check. Just in case.
David
1 Mar 06 at 1:35 pm
Love the script, just what I was looking for. But I can’t seem to get it to work on my local Linux box. The icons start spinning and the fields go dark, but that is it. Javascript console says
missing ; before statement
../zip.php?zip=72576 Line 3
Fatal error allowed memory size of 10485760 bytes exhausted (tried to allocate 4097 bytes)
Would sure love to know what I’m doing wrong.
Shane
21 Apr 07 at 3:34 pm
hm. looks like you’re out of ram in php-land. You’re seeing a javascript error because the javascript interperter is trying to run an error message sent by php.
Increase the RAM for php requests: http://www.tech-recipes.com/php_programming_tips777.html - it’s in your php.ini (think). OTOH if you’re actually going to use this in production I recommend going with one of the other approaches besides One Big Honkin’ CSV file, like putting it into a database.
banksean
22 Apr 07 at 8:04 am
Thanks for taking the time to write this article.
I wrote a zip code search utility as well to learn a bit about AJAX. I wired up google maps, since the zip db had long and lat. What’s really fun is the city search. How many US states have a city called Paris? go to http://channelping.com/zipcode/ to find out.
Regarding the various methods for getting at the zip data, a constant database, such as cdb or gdbm, is perfect for this type of application: it’s much faster than the sequential scan required with a plain csv file; the db sits on disk so the app isn’t using too much memory, and it doesn’t involve the adminstrative overhead typical of a full RDBMS.
gold
5 Jun 07 at 9:02 pm
the script used to work locally and on the web but now it seems i can’t get to work. When type in the zip code i don’t see any output on the city textbox and state textbox. The loading images are there but not output. I also don’t get an javascript script error.
has anyone the same issue here. Any advise or help is appreciated
fedi
6 Feb 08 at 9:30 pm
I know this post is old, but great job on the AJAX call. How hard is it to learn AJAX? I’m an experienced web developer, but have not fooled around with AJAX yet.
zipcode lookup
25 Mar 08 at 1:15 am
Very nice script, but what happens when you have multiple cities associated with a zip code? For example zip 80123 has like 5 cities associated with it. And zip 41465 has 27 cities associated with it. Thanks Again!
Cory
31 Mar 08 at 12:18 pm
@Cory: good point. You can still update the City after the form (incorrectly) auto-completes it. If you have the extra population stats, you could verify that the database associates the split zipcode with the City that has the most inhabitants in that zipcode. Not a fix really, just a sensible default kind of thing.
Of course if this problem affects a large number of your potential users it’s probably best to stick with a traditional address form. You just have to make a usability call in that case.
banksean
31 Mar 08 at 12:32 pm
I love this code. I am totally new to coding though. If i was running this off of a dbase (MySQL) with a list of the zip, states, etc, what would the code look like?
Mike
28 Feb 09 at 7:26 pm