Tags

, , ,

Update (03/14/2014): An intro post to CakePHP + jQuery auto-complete that’s more up to date.

Update (08/25/2010): There have been quite a few changes in CakePHP 1.3.3 and the Javascript/AJAX engines. (For one you are no longer “stuck” with prototype). Yet, everything in this post is still relevant and I still prefer to write jQuery by hand…

Please don’t tell me that you haven’t noticed that a lot of developers have abandoned the built-in AJAX stuff in CakePHP in favor of jQuery.

Not to say that the core helpers aren’t… helpful. The problem is that the jQuery framework is too addicting, because of easy coding, light weight, awesome plug-ins and “other great stuff”.

So, let’s explore a little how to get jQuery working in the CakePHP environment.

Yeah, this is part one only of (hopefully) a multi-post tutorial, but I figured that there aren’t too many introductory posts about it… well so let’s just start from the beginning.

First things first, you need to download the latest jQuery core (which it seems like I need to update mine). Update: Or… why not let google host the latest jQuery for you?
(At the time of writing: https://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js)

1. Let them handle HTTPS; it’s OK.
2. If you keep the build number simple like “1.4” rather than “1.4.2”, google will load the latest available 1.4.x version.

Anyways, generally speaking you kind of have to include the jQuery core, any plug-ins (if necessary) and then some page-specific (or view-specific) code.

Let us imagine a view_beer.ctp view:

<?php
    //let's load up the jQuery core
    $javascript->link('jquery/jquery.min', false);

    //and now... some file that will be specific to this view (page)
     $javascript->link('jquery/page_specific/beers_view_beer', false);
?>

This simply shows how to load up the required JS files in your view (not too bad). Don’t forget that for this to work properly you need to have $scripts_for_layout somewhere (usually in the head) in your layout file.

A side note… is the naming convention for the JS/jQuery files… which I will talk about in more detail in another post, but cake doesn’t have any specific conventions or requirements for that. As you see the way I do it, is call each file with controller + view name… and that seems to work just fine. You are, of course, free to chose your own convention… but it’s best to be consistent regardless of how you decide to proceed.

Now we should probably do something a little more “fun”.

For starters let’s see how easily we can post some data via AJAX using jQuery.

Alright, let’s say we have a link saying ‘add beer’ somewhere in the view…

<?php echo $html->link('add beer', '#', array('onclick'=>'return false;', 'id'=>'some-beer-name', 'class'=>'add-beer-link')); ?>

Let’s think about this one for a second. The “link”, as you see, really doesn’t do anything. Instead, it will be used later by our jQuery script to post some data via AJAX to the server.

What’s the point of ‘onclick’=>’return false;’? this simply keeps some decent browser from attempting to “jump” somewhere in the search of the non-existent “#” anchor.

To keep this example simple all we’ll do is post ‘some-beer-name’ using the link’s ID to the controller, and then store it into the CakePHP session. (As I mentioned, this is an intro post… so if you’ve done that a million times already no need to read any further ;))

So, now, we get to our beers_view_beer.js

 $(document).ready(function() {

    $('.add-beer-link').click( function () {
         $.post('/beers/add_beer', {id: $(this).attr('id')});
   });

});

Since there are countless tutorials out there explaining jQuery I won’t bug you with details of the code.

But what we are doing for our tiny app, is as follows:

  • We use jQuery selector, which equates to the class (i.e. ‘.add-beer-link’) of the link to basically say that whenever it is (or any link with such class) is clicked let’s post some data to the server.
  • The data will be posted to our: /beers/add_beer controller/action.
  • And what are we actually going to send?

As agreed, just an id of the link itself, which in our case happens to be ‘some-beer-name’…

I hope you can see how it all comes together from the rather simple jQuery syntax…

Now, let’s take a look at our add_beer() action, in the good ol’ CakePHP:

function add_beer() {
           Configure::write('debug', 0);
           $this->autoRender = false;

           if($this->RequestHandler->isAjax()) {
               $this->Session->write('BeersInOurSession', $this->params['form']['id']);
           }
       }

Let’s see what’s going on here…
Since all we are doing is saving some data to the session, this action does not need any view, hence:
$this->autoRender = false;

We use the RequestHandler component to check if the request to execute the action came from an AJAX request. It’s a very basic method to “protect” someone from going to the URL directly. In that case, well… nothing would happen, the user simply gets a blank page. There are better ways to secure this, but it would be beyond the scope of the article…

Alright, so we’ve disabled the output and view file rendering and checked for an AJAX request…

Remember this line of the jQuery code?

$.post(‘/beers/add_beer’, {id: $(this).attr(‘id’)});

It basically means that we’ve POSTed some data to our controller’s action and that data just happens to be “id”, which by reading the link’s actual id happens to be ‘some-beer-name’.

So how does that arrive to our controller? Well, since the form post was done via AJAX, to get the actual value of the sent data we use $this->params['form']['id'].

And if we were to do:

pr($this->Session->read(‘BeersInOurSession’));

We would see:

some-beer-name

Well, I hope this is a decent enough intro. In later (soon… ish… to be published posts I will try to give some real world usage examples of CakePHP + jQuery with a bit more interesting code).

P.S. Now there is a rumor going around that CakePHP and jQuery will become much closer friends… but yeah it’s just a rumor.

(part 2)