AJAX Select box in CakePHP


When I created my first personal CakePHP web site, this was something that had me quite frustrated.  I struggled and struggled to figure out and understand how to do a simple “if I change this select box, how can I populate another one”.

I had previously done this a million times in other languages with a simple Javascript onchange() function that would do my AJAX and populate my other select box.

To solve this problem, I checked CakePHP’s web site and did not find anything useful.  Don’t forget this was almost a year ago, I find the web site has come a long way now.  Because I couldn’t find a could example, I did the next best thing, I dove write into the form helper and ajax helper.  Shortly after, I found enough information to start my trial and error process.

Excellent, now we are getting some where.  Now that we know this, let’s create our two select boxes and make our second one populate through AJAX.

In this example, I have a country select list.  After you choose a country, my second select box will be populated with cell phone carriers based on the country selected.

[code]echo $form->input(‘country_id’, array(‘options’ => $countries, ’empty’ => ‘– Select –‘), null, array(‘id’ => ‘country_id’, ‘label’ => ‘Country’));

$options = array(‘url’ => ‘update_select’,’update’ => ‘UserCarrierId’);
echo $ajax->observeField(‘UserCountryId’, $options);

echo $form->input(‘carrier_id’, array(‘options’ => $carriers, ’empty’ => ‘– Select –‘), null, array(‘id’ => ‘carriers’, ‘label’ => ‘Carrier’));

Let’s break down what is happening here.  The first thing we do is create a country select box.  The $countries variable is passed in to our view from our controller.  We simple did a $this->Country->find(‘list’) to populate it.

Next up, we create an empty select item with “– Select –” in it.  Because we need to reference this field later, we also give it an id of “country_id”.  It’s important to note that CakePHP automatically converts this to UserCountryId.  User comes from our form name that is specified during our form create.  And finally, we assign it a label of “Country”.

Now let’s discuss the “meat and potatoes” of this example.  We start by creating an options JavaScript array, in this array we provide a URL of “update_select” and a field to update, “UserCarrierId”.  We then echo out a function from our AJAX helper.  We are telling it to observe our country_id field and passing in the options above.  What this does is create Javascript code that says “when country_id changes call our update_select function in our users_controller and when it’s done, update our carrier_id field”.

The last thing we do in this example is create our carrier_id field.  By default $carriers is empty, however, we use a variable here because if our validation fails during submit, we can populate the $carriers variable in our controller and not force the user to re-select a country to populate it.

Below is the contents of “update_select.ctp”:

[code]echo “<option value=\”\”>– Select –</option>\n”;
foreach($carriers as $k => $v) {
 echo “<option value=\”$k\”>$v</option>\n”;

This code receives the same $carriers variable, but this time it is populated with the carriers only for our country that we previously selected.

That’s it for today’s article and hopefully you can avoid the headaches I had to go through to create this for the first time. If you’re looking to explore how to do this with another server-side language be sure to checkout my Node.js tutorial as I’ve compiled a list of examples that perform this very similar functionality.

About the author

  • ajmacaro

    well, this is pretty nice. but really, can you provide
    a complete and working example on this?

    in what should “update_select.ctp” located?

  • Jamie

    Hey ajmacaro, no problem. It should be setup as follows:

    in app/controllers/users_controller.php you should have two functions add() and update_select().

    you should then create two views in app/views/users, add.ctp and update_select.ctp. Add.ctp should contain the first snippet to create the two select boxes and then update_select.ctp should contain the second snippet, that loops through the carriers and writes out the select box options.

    hopefully that’s more clear.

  • ajmacaro

    yes, thank you very much. i hope more post about this ajax stuff in cakephp. 🙂

  • http://www.google.com/search?hl=lv&q=XRumer&meta=&aq=f&oq= XRumerMonstroZ

    Gimme any url for downloading XRumer 5.0 Palladium FREE!
    Thank you…
    Very-very much.
    I’m so need this program for promote my online projects! This software is the best thing for online promo and mass posting, you know…

    And, dont send me XRumer 2.9 and XRumer 3.0 – that versions are too old!

    P.S. Google cant help me((((

  • Jamie

    I got it to populate the fields uing the select but how do I get to insert the selected data in the database? Can anyone help?

  • Pat

    I’ve got the Ajax call pulling up the “update_select” view content, with some static placeholder data. However, it’s not showing the iterated array data for the options. I’ve either messed up the calls in my update_select() function, or the Ajax call isn’t invoking the function at all.

    Would it be possible for you to post an example of your update_select() function; which pulls the constrained list of articles and sends it to the update_select view? Any help with this would be greatly appreciated. Thanks in advance!

    • Jamie

      My update_select function does a find() to retrieve a list of items and then in my view I simply output them as follows:
      echo “– Select –\n”;
      foreach($items as $k => $v) {
      echo “$v\n”;

      I’m not sure if this is the best approach for the view as I wrote this quite a while ago.

      I suppose the “better” approach would be to return JSON and have Javascript code that parses the JSON and creates option elements, but my example above seemed to work in the various browsers I tested.

  • Scholtzz

    Hi Jamie

    How do I retrieve the selected value of the select box in my controller?


    • Jamie

      It should be in the $this->data array. If it’s not it would be in the standard $_POST array.

  • vanganhxinh

    thank you very much for this tutorial. 🙂 You saved my time a lot.

    By the way, it would be better when all the variables could be explained in more details.

  • http://www.babilasaronni.it Babila Saronni

    Thanks a lot.

    I have improve performance of my CakePHP Intranet, instead of loading from MySQL DB all the 8000 cities, my user select only one hundred zones runtime, and then, by the handler request, software loads only the interesting cities.
    It was very important because all my system work under a SaaS logic.
    A good service.

    Babila Saronni

  • Issam

    thank you very much for this tutorial
    By the way, it would be better if you can repost it again, but this time, destiny to cakephp’s beginer like me ^_^

    i realy need to understand how it works
    Thank you
    NB : sorry for my english speaking, i’am not a good english writer ^_^

  • Paul

    I am trying to get your example to work on my form. All of my select boxes are completely full of every option available in the database. The states and cities are not updating.

    Below is the code I am using in my add.ctp.


    echo $this->Form->input(‘last_name’);
    echo $this->Form->input(‘username’);
    echo $this->Form->input(‘password’);
    echo $this->Form->input(’email’);

    echo $this->Form->input(‘country_id’, array(‘options’ => $countries, ’empty’ =>
    ‘– Select –‘), null, array(‘id’ => ‘country_id’, ‘label’ => ‘Country’));
    $options = array(‘url’ => ‘update_select’,’update’ => ‘UserStateId’);
    echo $ajax->observeField(‘UserCountryId’, $options);

    echo $this->Form->input(‘state_id’, array(‘options’ => $states, ’empty’ =>
    ‘– Select –‘), null, array(‘id’ => ‘states’, ‘label’ => ‘State’));
    $options = array(‘url’ => ‘update_select’,’update’ => ‘UserCityId’);
    echo $ajax->observeField(‘UserStateId’, $options);

    echo $this->Form->input(‘city_id’, array(‘options’ => $cities, ’empty’ =>
    ‘– Select –‘), null, array(‘id’ => ‘cities’, ‘label’ => ‘City’));

    Form->end(__(‘Submit’, true));?>

    This is my user_controller.php update_select function.

    function update_select(){
    $states = $this->User->State->find(‘list’);
    $cities = $this->User->City->find(‘list’);

    And this is my update_select.ctp.

    $v) {
    echo “$v\n”;

    echo “– Select –\n”;
    foreach($cities as $k => $v) {
    echo “$v\n”;

    Am I doing something wrong? I mean, obviously I am, none of my fields are updating. I have added the ajax and javascript helpers to my controller as well. I am quite new to CakePHP so any help would be awesome. Thanks in advance.

  • Pingback: Streisand, Aniston, Pfeiffer get Hollywood honors (AP) | 3fg.cc

  • Pingback: sulwhasoo

  • Pingback: removal of skin tags

  • Pingback: warlock pvp guide

  • Pingback: gardening recipe

  • Pingback: online computer repair

  • Pingback: Goozle Zone

  • Pingback: Ania Antonette Quisumbing

  • Pingback: guayabera shirts

  • Pingback: top songs download website

  • Pingback: ultimate power profits

  • Pingback: zig zagz

  • Pingback: Motorbike Accident Claim Solicitors

  • Pingback: Personal Injury Solicitors in Manchester

  • Pingback: promo umbrellas

  • Pingback: ZigZag

  • Pingback: calaguas tour

  • Pingback: new york asian escorts

  • Nachee

    Thanks for your article. Well explained

  • Pingback: Studios

  • Pingback: Info

  • Pingback: Success

  • Pingback: Climate

  • Pingback: Collecting

  • Pingback: Blog

By Jamie

My Books