views:

1457

answers:

2

I'm using CakePHP for a small web app and on one form page there's a dropdown to select a job number. I'd like to update two text fields based on the job number selected in the dropdown using jQuery (I'm also open to using the default ajax helper but I didn't have a lot of success with it).

Here's my jQuery snippet:

<script>
    $(document).ready(function() {
        $('#job_id').change(function() {
            $.post('/surveys/jobdetails', {id: $(this).attr('id')});
        })
        .change();
    });
</script>

jobdetails is a method in my controller that gets the current job based on the job id passed in. However, it doesn't get called when the dropdown changes value. I tried substituting an alert function in place of .post and that worked, so onchange is being called correctly.

Here's the <div> I'm trying to update:

echo "<div id='job_details'>";
echo $form->label('jobtitle', 'Job Title');
echo "<input type='text' name='jobtitle' id='jobtitle'>";
echo $form->label('department', 'Department');
echo "<input type='text' name='department' id='department'>";
echo "</div>";

I want to set the value of each text field to be the corresponding value for the job returned from the ajax call. There's a lot of really good jQuery and CakePHP documentation but I haven't found anything that quite covers what I'm trying to do. Can anyone see what I'm doing wrong? Is there a better way to use ajax to update a div with CakePHP?

+1  A: 

Right now, it appears that the AJAX request hits the "/surveys/jobdetails" URL, but does nothing with the results. You need to add a callback to your AJAX request, like so:

$(document).ready(function() {
    $('#job_id').change(function() {
        $.post('/surveys/jobdetails', {id: $(this).attr('id')},
        function(result) {
            $('#job_id').html(result);
        });
    })
    .change();
});

There is also a convenience function in jQuery called load() which simplifies it even further, getting the contents of a URL and applying it to the selected element:

$(document).ready(function() {
    $('#job_id').change(function() {
        $(this).load('/surveys/jobdetails', {id: $(this).attr('id')});
    })
    .change();
});
Luke Dennis
Thank you very much - I ended up using the html(result) function to update my div.
moexu
+2  A: 

Your CakePHP controller needs to look something like this:

function jobdetails() {
    // get the data however you want
    // $_POST['id'] will have the job_id
    print json_encode(array(
        'jobtitle' => $jobtitle,
        'department'=>$dept
    ));
    exit;
}

Then you need to add a callback to your $.post that will actually update the fields:

$(document).ready(function() {
    $('#job_id').change(function() {
        $.post('/surveys/jobdetails', {id: $(this).attr('id')}, function(json) {
            // now that we are in the callback,
            // the variable json is an object
            // with the values we passed above
            // so we can update the fields with the new values
            $('#jobtitle').val(json.jobtitle);
            $('#department').val(json.department);
        });
    })
    .change();
});

I also recommend you get a tool like Firebug so you can see the progress of your AJAX requests and make sure the server is returning what you think its returning. It makes testing and debugging anything related to AJAX way easier.

In my opinion this is more elegant than outputting the whole DIV to update, but if you want to go that route you would just use jQuery's .load to achieve what you want.

Paolo Bergantino
Thank you so much for your reply - I wasn't able to get the json encoding working but your input really helped. I also got Firebug up and running so thank you for that recommendation as well.
moexu
json_encode has only been included with PHP since version >= 5.2.0 so that's probably why. There are many packages out there that can emulate what it does, but I understand not bothering with it. Good luck. :)
Paolo Bergantino