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':
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:
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
function index() {
$widgets = $this->Widget->find('all');
$this->setJson(compact('widgets'));
}
}
app/views/webroot/js/my_include.js
$.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
You can skip to the end and add a comment.
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()?
You never mentioned that the JavaScript is actually jQuery code.
@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!
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!
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.
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.