debuggable

 
Contact Us
 

Passing controller variables to your JavaScript

Posted on 27/8/08 by Felix Geisendörfer

Hey folks,

this is post #8 of my 30 day challenge. One week done, yeah!

If your application requires JavaScript in order to work than you have probably been looking for an efficient way to pass CakePHP controller variables to your scripts. I already mentioned this technique in my talk at CakeFest this year, but here is the full explanation.

Essentially we started by adding a new function to the AppController which we call 'setJson':

class AppController extends Controller{
  function setJson($one, $two = null) {
    if (!is_array($one)) {
      return $this->viewVars['jsonVars'][$one] = $two;
    }
    foreach ($one as $key => $val) {
      $this->viewVars['jsonVars'][$key] = $val;
    }
  }
}

After you added this to your AppController, you will also need this in the <head> section of your app/views/layouts/default.ctp file:

if (isset($jsonVars)) {
  echo $javascript->codeBlock('window.jsonVars = '.$javascript->object($jsonVars).';');
}

So lets say your application is all ajax / js and you want to render a couple of widgets fetched from the db, this is what you would do:

app/controllers/widgets_controller.php

class WidgetsController extends AppController{
  function index() {
    $widgets = $this->Widget->find('all');
    $this->setJson(compact('widgets'));
  }
}

app/views/webroot/js/my_include.js

$(function() {
  $.each(window.jsonVars['widgets'], function() {
    $.renderWidget(this);
  });
})

So essentially this provides you with a quick and dirty way to make your PHP arrays directly accessible in JavaScript. Often times you may want to avoid such techniques for accessibility reasons, but in other cases this is just exactly what makes sense.

Feel free to drop a comment if you like this approach or have your own solution to the problem.

HTH,
-- Felix Geisendörfer aka the_undefined

 
&nsbp;

You can skip to the end and add a comment.

Kim Fransman said on Aug 27, 2008:

Hi Felix.
Just yesterday i was thinking about this as I'm writing an app where JS will do all the heavy lifting. This is a really great way of getting the functionality i wanted, Thanks!

Ps. Looking forward for the release of jayDom.

Bryan Clark said on Aug 27, 2008:

What's the advantage of using this over $javascript->object(compact('widgets')), and then adding that to the viewVars or in the setJson method using $javascript->object()?

Marc Grabanski said on Aug 27, 2008:

You never mentioned that the JavaScript is actually jQuery code.

Jonathan Snook said on Aug 27, 2008:

@Marc: I think the fact that the final example uses jQuery is irrelevant. While it is (and people shouldn't expect this code to work "out of the box"), the important point is that the JS object will be available in whatever code you might have.

I like it!

Bruno Bergher said on Aug 27, 2008:

This is a very elegant solution, Felix, thanks.
And it's good to see you're keeping the post quality pretty high one week into your challenge. Congrats!

Duncan Brown said on Sep 12, 2008:

Thanks for this, I've been looking for a way of doing this for a while but just ignored it and moved on to something else, its such a simple solution I love it.

This post is too old. We do not allow comments here anymore in order to fight spam. If you have real feedback or questions for the post, please contact us.