Best Approach to Dynamic Javascript in CakePHP Views

Posted on 05/29/2010 at 12:36 pm by Kevin Wentworth
Viewed 22,981 times | 5 comments

I always knew in the back of my mind that there was a better way of creating dynamic javascript than the method I was using.  CakePHP has a great function as part of the $View controller:  $View->addScript($jscript, false) will add a script block to your template header.  This is the command I use to send javascript created in a Cake view up to the header, which is where most javascript should live.  The best approach to adding dynamic javascript to your CakePHP views is to implement PHP's output buffering, combined with $View->addScript().

Buffer That Javascript and then use CakePHP's $this->addScript()

Here's the code I use to allow me to write "native" javascript, i.e. not having to worry about escaping quotes one way or the other (see below).

  1. <?php
  2.     ob_start();  //start output buffering (nestable, no need to worry about Cake's buffering
  3. ?>
  4. <script type="text/javascript" language="JavaScript">
  5.     function checkFormValidation(whichForm) {
  6.         var why = "<?php echo $data['Model']['text']; ?>";
  7.         var errorsFound = 0;
  8.         ...
  9.         document.waiver_and_consent.elements['SubmitButton'].disabled = true;
  10.         document.waiver_and_consent.elements['SubmitButton'].value = " Please wait... ";
  11.         return true;
  12.     }
  13. </script>
  14. <?php
  15.     $jscript = ob_get_contents(); //return output buffer to variable
  16.     ob_end_clean(); //must clean buffer or javascript above will print TWICE (one inline, one in header)
  17.     echo $this->addScript($jscript, false); //add script to header
  18. ?>

The Old Way... using a PHP string. Yuck!

I use to have huge javascript "strings" that would need to be properly quoted and escaped where necessary.  What a pain!  I can't believe I ever did it this way:

  1. <?php
  2. $jscript = '<script type="text/javascript">
  3.     function checkFormValidation(whichForm) {
  4.         var why = "'. $data['Model']['text'] .'";
  5.         var errorsFound = 0;
  6.         document.waiver_and_consent.elements[\'SubmitButton\'].disabled = true;
  7.         document.waiver_and_consent.elements[\'SubmitButton\'].value = " Please wait... ";
  8.         return true;
  9.     }
  11. ';
  12. echo $this->addScript($jscript, false); //add script to header
  13. ?>

Hope this saves someone from having to debug poorly escaped javascript in a PHP string on top of poorly written javascript.


-Kevin Wentworth

Bookmark and Share

Tags for Best Approach to Dynamic Javascript in CakePHP Views

Cakephp | Web Programming | Jquery | Usage | Example | Php

Comments for this Posting

Posted by Schiho

on 5/11/10

I was just waiting for that. There are a lot of old cakephp helpers written like your "yuck" code :). It was so annoying to find a bug!

thanks for the clarification.

Posted by Schiho

on 5/11/10

I would like to ask a question.

In your approach you have everything in one file. I would like to linked js file, so that my view does not get confusing. But how do i pass my linked "php" file the data variable?

would be nice to know


Posted by shreyas ubale

on 18/12/10

Or , you can use php heredoc syntax

Posted by miCRoSCoPiC^eaRthLinG

on 21/12/10

@shreyas: That's what I had tried using first - but heredoc does a miserable job as it tries to parse anything that begins with a $ and if you are using any of the regular JS frameworks where the functions are encased in a global $() namespace - you are royally screwed, my friend :D

But fear not, as in situations like these it's NOWDOC syntax that saved the day.

Anyway, the one presented in this article is a much better solution.


Posted by Fang

on 14/10/11

actually, i found out the following is exactly what this is ,

$this->Html->scriptStart(array('inline' => false));
echo $this->Js->alert('I am in the javascript');

it's not detailed documented, however, you can put any javascript (including comments, any html) between start and end, don't forget there's no echo for those two lines.

Sorry, comments are closed for this posting.

Please Email Kevin if you have any questions. Thanks!

Meet Site Avenger - Hosted Content Management System

Powered By: Site Avenger | Site Production: Saco Design