Today, I struggled a bit to get a select field to be dynamically populated with values. The values are depending on what choice has been made earlier in the form in combination with CakePHP.
Before we get into things I must give credit where credit is due, this article helped me a lot, although since it was based on CakePHP 1.2 things were a bit outdated, so I had to adjust it here and there.
Time to get to the point. I’m assuming that you’re already familiar with AJAX and are just trying to integrate it nicely into your Cake app. I won’t be getting into AJAX itself, so if you’re not familiar with that, I suggest reading up on it first.
Let’s say you have a form with 2 drop down menus. For example, we would like to populate a dropdown with a list of chapters whenever a book is selected from the first dropdown. We want the chapters dropdown to get re-populated with options if the book were to change. In order to achieve this, we can use CakePHP’s built-in Ajax helper, which saves us loads of time. You can easily call the Ajax helper by putting this line in the top section of your controller:
var $helpers = array(‘Ajax’);
That will make the Ajax helper available to all the views belonging to this controller’s actions. Now, on top of that, we would like our views to be “expecting” AJAX calls and stand by for them. To do that, you can use CakePHP’s RequestHandler component, which can be included in your controller like this:
var $components = array(‘RequestHandler’);
Now, let’s say we would like to give users the ability to add a synopsis for a chapter of a book. Depending on what book they pick, a list of chapters for that book should be presented. Let’s assume the models are associated with the relation: Book hasMany Chapter. Now let’s take a look at what the view for such a page might look like.
echo $this->Form->input(‘Book.id’, array(‘label’ => ‘Book’, ’empty’ => ‘– Pick a book –‘));
echo $this->Form->input(‘Book.chapter_id’, array(‘label’ => ‘Chapter’, ’empty’ => ‘– Pick a chapter –‘));
echo $this->Form->end(‘Submit synopsis’);