Making and processing AJAX calls from blocks

Permalink 4 users found helpful
Hi all, I recently wanted to make some ajax calls from a block, in this case to do the classic "populate a select box", but could have been anything really. Although it is extremely simple to do with c5, I couldn't find any nice'n easy tutorial, so had to figure it out myself in the end.
Note, this tutorial is written for people who have some clue about what they are doing.
Here are the basic steps you need.
In your block view.php (or custom template) you would have a code similar to this:
<select id="my_select"></select>
<input type="button" onclick="getValues()" value="get values!">
function getValues() {
      type: "POST",
      url: "<?= str_replace("&amp;","&",$this->action('myAction')) ?>",
      dataType: 'json',
      success: function(j){
         var options = '';      
         for (var i = 0; i < j.length; i++) {
            options += '<option value="' + j[i].value + '">' + j[i].name + '</option>';

Then in your block controller you would add the following (inside the controller class, of course:
function action_myAction {
   $values = array();
   $values[] = array('name'=>'some name 1','value'=>'some value 1');
   $values[] = array('name'=>'some name 2','value'=>'some value 2');
   $values[] = array('name'=>'some name 3','value'=>'some value 3');
   echo json_encode($values);

And that's all, you just created a select that will be populated with values returned by your block controller via ajax!
Note that jquery has several ways of doing this and for the sake of the example I probably chose the hardest one! But the most important things are:
- Submit your ajax to <?= str_replace("&amp;","&",$this->action('myAction')) ?>, of course myAction can be any action name.
- In your block controller, create a function called action_myAction (match the action name with the one in the ajax call), make it echo whatever you want and then exit.

View Replies:
ScottC replied on at Permalink Reply
Thank you for taking the time to make this post.
whereb replied on at Permalink Reply
I tried this code verbatum, and in as many logical variants as I could think of and none gives the expected result.

The best I can get is a ajax response of the block's controller method response embedded within the html of the entire containing page.

That is, the controller method is called and processed, but the entire page is returned along with the data that you want.

Is it something I'm doing wrong here? Or is there something not quite working?

matogertel replied on at Permalink Reply
I didn't try exactly the code above, I took my real world example and did some cleanup.
If you're saying that the action function is being called but you're getting the whole page along with the values, then most probably you forgot to call the "exit" function at the end of your action handler. This is neccessary so that c5 exits after the call and doesn't continue doing its own stuff (which in this case is printing the whole page)
whereb replied on at Permalink Reply
My controller action function finishes with exit(0);

I'll try cutting out the 0 argument and see if that makes a difference.

If you're using this and it works for you, then obviously it works and it's my problem. Hmmm...

I'll keep this thread posted on what the issue is for me.
whereb replied on at Permalink Reply
Not sure what it was that made the difference though. If I figure out what it was that I did wrong, I'll put it up here!

whereb replied on at Permalink Reply
So it looks like I made a small typo when I was rearranging my code around to fit with you example.

So, thanks. Funny why we need that str_replace call there, I wonder why the BlockView::action method doesn't just do that anyway. An oversight? or this a good reason for making us do this "by hand". I tried it without the str_replace wrapper and it doesn't work in Firefox.

Thanks for your time and help and - yeah GREAT POST!

cherrycake replied on at Permalink Reply
Thanks for the example. i'm just curious though as i'm sure i must be missing something..

what makes this any easier than simply doing this in view.php
$form->select('mySelect', $controller->getMySelectValues());
and then in your controller
function getMySelectValues() {
  return array(   'some name 1' => 'some value 1', 
      'some name 2' => 'some value 2', 
      'some name 3' => 'some value 3');
to me it looks like it would do the exact same thing. what i'm wondering i guess is, why would you need to use ajax to query an already instantiated controller that your view carries a reference to?

either way, thanks again for the tutorial.
matogertel replied on at Permalink Reply
Sure, the example doesn't do anything useful. I just wanted to put something really simple so that the concept doesn't get lost in a complex example.
It's based on assumption that you know how to do ajax in general but not too sure how to implement it in a c5 block.
virendrakaliyar replied on at Permalink Reply
Thanks you very much for the post. I really got benefit from this post. I had been using a very odd method for AJAX.

Thank You Very much!
JohntheFish replied on at Permalink Reply
sfeng replied on at Permalink Reply
Hi Matogertel,

I can not embed the php code: <?php echo $this->action('myAction')) ?>

into the javascript code. The php code will not be parsed.

Do you know the problem? Thank you very much.
JohntheFish replied on at Permalink Reply
You can put that code within script tags in a .php file.

For a small script, put all the JavaScript code in the script tags. For larger scripts, use the code
var js_action = '<?php echo $this->action("My_Action");?>';

In a short section of script the .php file, then access those variables from a separate .js file.
sfeng replied on at Permalink Reply

Thank you very much :)
CommotionCreative replied on at Permalink Reply
What would the code be if I wanted to do this with multiple select boxes and pass back a multidimensional array within that json object?
TheRealSean replied on at Permalink Reply
Thank you for this tutorial, it really helped me get my head round this.

Great post

arik replied on at Permalink Reply
Thanks for sharing. This is a lot easier than I thought.