the web, technology and miscellaneous rants
Simple Zend Framework and Ajax Tutorial
I love the Zend Framework. I’ve been using it since version 1.5 (currently at 1.10 as of this writing). It has so many features and can do so many things–sometimes it’s just not immediately clear how to implement those great features.
One feature that took me awhile to figure out was AJAX context switching. The documentation contains various pieces of information about implementing AJAX, but it just wasn’t clear how to put those pieces together. To help make this more clear, I’m going to go through a simple example of how to add very basic AJAX to the Zend Framework QuickStart project. I’m going to be using jQuery because I prefer that to Dojo and the rest of the JavaScript frameworks.
This tutorial assumes you already have a development server set up, Zend Framework installed, and the Zend Framework QuickStart project up and running.
Modify IndexController.php
First we need to set up Ajax context switching in the main controller. Add the following init() function to the index controller found in controllers/IndexController.php
public function init()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('list', 'html')
->addActionContext('modify', 'html')
->initContext();
}
The html parameter is the type of Ajax request. You can also use JSON or XML.
Note: The modify context is not used in this tutorial but is merely there to demonstrate that you can have as many action contexts as you want.
Now we need to add the list action that we specified above in the addActionContext call to the IndexController.php.
public function listAction() {
// pretend this is a sophisticated database query
$data = array('red','green','blue','yellow');
$this->view->data = $data;
}
Create the list view scripts
By default, Zend Framework tries to render view scripts with the same name as the action. If our action’s name is list and is controlled by the controller named index, then Zend will try to render a view script located at view/scripts/index/list.phtml. Since we are using Ajax context switching, Zend Framework attempts to render view/scripts/index/list.ajax.phtml instead.
For testing my Ajax actions I usually create a normal view helper as well as the Ajax helper but then just include the Ajax view helper.
Create the following view scripts. The second script list.phtml is optional but might aid in troubleshooting.
views/scripts/index/list.ajax.phtml
<!-- views/scripts/list.ajax.phtml should contain something like the following --> <ul> <?php foreach ($this->data as $color) : ?> <li><?= $color ?></li> <?php endforeach; ?> </ul>
views/scripts/index/list.phtml
<?php
include('list.ajax.phtml');
jQuery time
The last thing we need to do is to add some HTML and JavaScript to our index.phtml view script to test everything out.
Add the following to the bottom of views/scripts/index/index.phtml
<div id="container">
</div>
<script type="text/javascript">
$(document).ready(function() {
$('#container').load('/default/index/list/format/html');
});
</script>
The most important part of that jQuery code is the content of the URL you specify. This is one of those cases when you need to specify the module and controller and action even if they are set to the default value.
‘/module/controller/action/format/html’
You must also not forget the format/html part. If you forget it, you’ll notice that Zend is rendering your layout too instead of just rendering the view script.
That’s it. You should now have a list of colours on the first page of your site.
UPDATE: there was an error in the jQuery code on the index.phtml view script. The code is correct now. I have also added a working project to my Google Code repository. Thanks to the commenters for pointing this out.
| Print article | This entry was posted by John T. Clark on March 3, 2010 at 8:08 am, and is filed under Because I Forget Things, Zend Framework. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |



about 2 years ago
im testin your code but its not working. i was given the path in layout.php file i.e headScript()->appendFile($this->baseUrl().’/js/jquery.js’, ‘text/javascript’)?>
its include in the page but not call the list function
about 2 years ago
Errr,
I think the problem is the following line:
$(‘#container’).load(‘/index/index/list/format/html’);
There is one “index” to much.
-> index/index/ will load the indexAction
But we want the listAction, so change it to:
$(‘#container’).load(‘/index/list/format/html’);
an it will work for ya!
Allright fellows!
about 2 years ago
Hi Folks,
There is still some problem in above code, after implementing it still the code not works.
Here are few steps to check the problem -
1. Make sure that “list.ajax.phtml” resides in this directory “{site}/application/views/scripts/index/”.
2.And this call ” $(‘#container’).load(‘/index/list/format/html’); ” must be changed to ” $(‘#container’).load(‘./index/list/format/html’); ”
These steps sorted out my problem , may be it will help others too.
Cheers !
about 2 years ago
I updated the post and added a link to a working project on Google Code. Thanks for pointing out my error.
about 2 years ago
Sorry guys; I dont see the need of this.
Just create a dedicated controller for your ajax calls, disable layout and renderer and use ZF AjaxLink()
cheers
about 2 years ago
Instead of using include, check out the partial view helper:
echo $this->partial(‘index/list.ajax.phtml’, array(‘data’ => $this->data));
Also, the url view helper is a very useful:
echo $this->url(array(‘controller’ => ‘index’, ‘action’ => ‘list’, ‘format’ => ‘html’));
about 2 years ago
nice example, works perfect for me
thx
about 2 years ago
Hi, i tried this script, working well, but i could not switch contexts like xml or json.
about 2 years ago
Thanks a lot. Your comment really helped!
about 1 year ago
Finally worked perfectly! Just do one thing – Do not use exit; at the end of the controller action similar to the normal AJAX POST actions.
Good Job
about 1 year ago
Thank you very much! Short and understandable, just what I needed.
about 11 months ago
My function listAction() has setLayout, but for ajax version it needs to be disabled. Where to put disableLayout() command?
about 11 months ago
It should go in your Controller like this:
class IndexController extends Zend_Controller_Action
{
public function init()
{
$this->_helper->layout->disableLayout();
}
}
about 11 months ago
Isn’t this disable layout for both normal and ajax version? Adding setLayout in indexAction sets layout again for both.
about 11 months ago
you can use isXmlHttpRequest to detect if ajax request.
public function init()
{
// disable layout and view if ajax request
if ($this->getRequest()->isXmlHttpRequest()) {
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
}
}