Pass Variables from PHP to Javascript

Permalink
I'm working on a block that uses AJAX and I'm trying to figure out the best way to pass information from my controller to Javascript without embedding it in my view.

My block view contains this code:

<script type="text/javascript">
<!--
var ajaxAction = "<?= str_replace('&amp;', '&', $this->action('myactionname')); ?>";
//-->
</script>

I then use the variable ajaxAction in an externally included Javascript file.

I would much rather pass it from the controller directly somehow without having to muddle my view with Javascript. Drupal has allows me to do this and I'm trying to figure out if C5 has a similar feature.

 
jordanlev replied on at Permalink Reply
jordanlev
That is the way I do it too. (Seehttp://www.concrete5.org/community/forums/customizing_c5/ajax-from-... ).

But now that I'm thinking about it, you could probably pass that directly into the head of the document from your controller via the on_page_view() method, like this:
public function on_page_view() {
    $bv = new BlockView();
    $bv->setBlockObject($this->getBlockObject());
    $action = $bv->action('myactionname');
    $action = str_replace('&amp;', '&', $action); //I'm not sure you need this. If you do, it might be better to use htmlentities() instead.
    $js = "var ajaxAction = '{$action}';";
    $this->addHeaderItem('<script type="text/javascript">' . $js . '</script>';
}



BTW, you don't need to put those <!-- and //--> things in your javascript anymore, that was like a Netscape 1 thing -- seehttp://javascript.crockford.com/script.html...
orourkedd replied on at Permalink Reply
Thanks, I'll take a look at this.

I include the <!-- //--> because the page won't validate if the javascript is not commented out.
orourkedd replied on at Permalink Reply 1 Attachment
Here's how I got this working:

1) I extended the Controller for pages and creatively named it 'PageController' and places in /libraries
2) When I create a controller it looks like this:

Loader::library("page_controller");
class MyPageController extends PageController {...

3) I transfer PHP data to JS by calling the functions 'setJS' or 'setJSAction':

$this->setJS('myvar', 'my value');
$this->setJSAction('myaction', 'actionMethodName');

4) The javascript is printed to the head and looks like this:
<script language="text/javascript"> <!--
var myvar = "my value";
var myaction = "/index.php/path/to/controller/action/actionMethodName";
//--></script>

It can also accept arrays - just not nested ones yet:
$this->setJS(array('myval' => '123', 'myval2' => '234'));

This is virtually untested but seems to be working for me right now!
I attached page_controller.txt - just change .txt to .php
jordanlev replied on at Permalink Reply
jordanlev
This is a really smart approach -- thanks for sharing! I've been doing a lot of extending single_page controllers recently, but didn't think to do something like this with block controllers. Definitely will be using this technique in the future.
JohntheFish replied on at Permalink Reply
JohntheFish
I just had a block "Ajax Lessons"http://www.concrete5.org/marketplace/addons/ajax-lessons/... approved. Its a working (and in some cases showing what does not work) set of abstract examples of ajax with javascript.

The trick you have just used is something I had not included, so I will be thinking about it for a future version.
jordanlev replied on at Permalink Reply
jordanlev
Great idea on that package, John -- I should do that for some of my sample code as well.

For what it's worth, I might recommend only using the portion of @vivefree's technique that involves sending the javascript to the header, not the extending of the BlockController class (so whatever functionality exists in the BlockController class should be moved into a private function of the actual block controller). The reason I think this would be better for a learning tool like you ajax block is because for a lot of people, the whole class extension / inheritance thing will be a very new and confusing concept, and since they're already trying to learn the ajax concept it might just get in the way.
JohntheFish replied on at Permalink Reply
JohntheFish
I thought you already had with designer content ;-), save that it does something really useful rather than just making an abstract lesson.