Domas
Domas

Reputation: 1133

CakePHP setting up dependent AJAX dropdown

I have done a lot of research, tried to apply a few different examples but it seems that nothing really works.

So I have the following 3 models: Customers, Projects and Events. Customers have many Projects and Projects have many Events.

While creating an Event, I would like a user to select a Customer from a dropdown list and then the user should be provided with a list of Projects that belong to the selected Customer. The closest I have got to is the following. I do not have experience with AJAX, so that really is a hard nut to brake.

Action in the Porject's controller:

    public function getbycustomer(){

    $customer_id = $this->request->data['Event']['customer_id'];

    $projects = $this->Project->find('list', array('conditions'=>array('Project.customer_id' => $customer_id), 'recursive' => -1));

    $this->set('projects', $projects);
    $this->layout = 'ajax'; 
}

View for this action is the following:

    <?php foreach ($projects as $key => $value): ?>
<option value="<?php echo $key; ?>"><?php echo $value; ?></option>
<?php endforeach; ?>

And here is the snippets from the view for adding an event:

    echo $this->Form->input('customer_id');
        echo $this->Form->input('project_id'); 

//form continues and at the end of a page there is the AJAX call

    $this->Js->get('#EventCustomerId')->event('change', 
    $this->Js->request(array(
        'controller'=>'projects',
        'action'=>'getbycustomer'
        ), array(
        'update'=>'#EventProjectId',
        'async' => true,
        'method' => 'post',
        'dataExpression'=>true,
        'data'=> $this->Js->serializeForm(array(
            'isForm' => true,
            'inline' => true
            ))
        ))
    );

Any help is much much appreciated as I do not even know the proper way for debugging it, so I could provide more valuable information.

Upvotes: 1

Views: 4605

Answers (2)

Sp0T
Sp0T

Reputation: 284

go to this. this helped me to do the dependent drop down list. it provies a details step by step process.

Upvotes: 3

DSG
DSG

Reputation: 436

I think you need to set autoRender to false otherwise it will try to render the template at app/View/Project/getbycustomer.ctp. Also, you probably want to return or print JSON. Ther are probably several ways to do this, but I have something similar that is working and the controller action is basically this:

public function getbycustomer() {
  $this->autoRender = $this->layout = false;
  $customer_id = $this->request->data['Event']['customer_id'];
  $projects = $this->Project->find('list', array('conditions'=>array('Project.customer_id' => $customer_id), 'recursive' => -1));
  $this->set('projects', $projects);
  echo json_encode(array('html' => $this->render('your_partial_template')->body())); // This template would be in app/View/Project/json/
}

Then in your Ajax call there should be a 'success' callback that handles the JSON returned:

success: function(data) {
  $('#EventProjectId').html(data.html); // assuming this an empty container
}

Also, unless your projects table is only two columns the result of your find is probably not what you're expecting. Change it to

$projects = $this->Project->find('list', array('conditions'=>array('Project.customer_id' => $customer_id), 'fields' => array('id', 'name_or_whatever', 'recursive' => -1));

Then in your partial template you can use the form helper:

<?php echo $this->Form->input('Projects.id', array('options' => $projects)); ?>

Upvotes: 0

Related Questions