Dynamic Select Box

Recently I came across a problem, where I wanted to show a select box for zones in an address (counties or states etc.). I have a list of zones in my database and to put them all in one box would have been unusable as the list is in excess of 2000 zones. My solution to this was only show the zones related to the country selected in another select box. When the user changes the country the zones are updated. In this tutorial I will explain how I achieved this using cakePHP (1.3) and the YUI Library (3.1.1).
If you want to try this, the following files have the sql to fill the two tables (this data is quite old, some some countries/states etc. may be out of date).

The first thing to do is setup basic controller and model files for “zones” and “countries”, this could be done with the bake console. For this example I will use this to set to state/county in a profile, so to make use of the data in the zones and countries tables you need to add two fields, “zone_id” and “country_id”. Make sure associations are setup between your profiles model and these two new models (zones and countries). If you were going to show the full list of zones the profile/add action would look lie this:

Now as I said this would give you over 2000 zone options, which is not exactly practical. To reduce the list to only show the zones for one country all you have to do is add a condition to the zone find statement, as I live in the UK I would do this:

Obviously this is great if you can guarantee that all your users are from one country. As this will almost never be the case the user needs to be able to select their country as well. This is an example of a basic form for our profile/add action.

To break this down, the first thing this bit of code does is look for an element with an id of “zones”, then there is a function that sends an io request to http://www.example.com/zones/update/{country_id} and finally adds an on change event listener to an element with an id of “CountryId” (countries select box).

There are a few things that need to be changed for this code to work. The profiles/add.ctp file needs another div added and I add a short message to inform users how to access other zones and make sure there is an empty selection. Simply replace the “zone_id” input code with this:

The action that the io request needs is “update”, this needs to be added to the zones controller. You can also use this same function/code if you need zone and country selection in multiple places in an app.