Rojakcoder
Of Linux, Programming, and Singaporean Ramblings

Using Zend Framework with jQuery to do Auto-Completion

Thu, Jan 8, 2009 12:21PM +0800

This post describes how you can perform text field auto-completion with Zend Framework (ZF) and jQuery. To make full use of this post, you will need to have a working knowledge of Zend Framework and of jQuery. You don’t need to be an expert at using them though cos if you do, you probably won’t be reading this post. Here goes.

The basic assumptions here are that you’ve got your application running on the Zend Framework already and that your jQuery script is placed in the right place which means all your view scripts can access jQuery code.

The first step you want to do is to get the jQuery-based auto-completion code. I’ve tried a use a few but I found the one from PengoWorks to be the simplest to implement and understand. Simply download the files jquery.autocomplete.js and jquery.autocomplete.css from the PengoWorks link above and place them into your application directory structure.

For better understanding, I will illustrate with an example. I place the two files into this location ‘/public/js/lib/autocomplete/’. Then in the layout script (or the view script), I include the JavaScript and CSS files:

<link href="/js/lib/autocomplete/jquery.autocomplete.css" media="screen" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/js/lib/autocomplete/jquery.autocomplete.js" />

Note: you can use ZF to place the CSS file like this: $this->headLink()->appendStylesheet('/js/lib/autocomplete/jquery.autocomplete.css') (in the layout file)

If you are using the ZendX_JQuery component, you can use the following to add the JavaScript file: $view->jQuery()->addJavascriptFile('/js/lib/autocomplete/jquery.autocomplete.js') (in the bootstrap file)

Testing the Auto-Completion Feature

Before we go any further, you need to try if your JavaScript code works or not. You can do this without using a server.

Let’s say the following is placed in your view script (JavaScript and HTML elements in the same place):

<script type="text/javascript">
$(document).ready(function() {
        $('#username').autocompleteArray(['Jack', 'John', 'Jason', 'Jeremy', 'jimmy', 'jean']);
});
</script>

<input type="text" name="username" id="username" />

(Note: if you copy and paste the code here, take note of the double-quotes - it may not work in your text-editor so if the code doesn’t work, check the quotes first.)

(correction made to the code above, thanks to Kasper in the comments)

Then load the page in your browser. Place the cursor in the text box and type ‘j’ (without the quotes). You should see a list of names appear after about a second. If you see it, then your code is working! Woohoo!

(But if you don’t see it, post in the comments and see if anyone can help. I’ll try to help but I probably will be too time-strapped to do it in a timely manner.)

Preparing the Server Back-end

So at this step we’ve confirmed the front-end to be working. Now we need to make the back-end respond to a AJAX request from the client. With Zend Framework, this is very simple. I won’t muddle the waters here by trying to explain in detail how it works but I’ll explain the snippets in my code. You can get the complete reference from Zend Framework’s manual.

// /controllers/ProjectController.php
class ProjectController extends Zend_Controller_Action
{
    public function init()
    {
        $this->_helper->ajaxContext()->addActionContext('index', 'html')->initContext();
        parent::init();
    }

    public function indexAction()
    {
        if ($this->_helper->ajaxContext()->getCurrentContext()) {
            $this->view->words = array('leon', 'lionel', 'Lenny', 'Linda', 'Lindy');
        }
    }
}

// /views/scripts/project/index.ajax.phtml
foreach ($this->words as $word) {
    echo "{$word}\n";
}

(minor correction made, thanks to Robert for pointing out in the comments)

Explanation

Controller

The context initialization code is placed in the init() function because that function is invoked right after the controller’s constructor. Basically, what it says is the indexAction is able to accept AJAX requests. The parent::init() function is invoked so that any inherited initialization function will also be invoked.

In the indexAction function it checks to see if the request is an AJAX request (there can be also XML, JSON types but here we are only concerned with AJAX). If it is, it assigns an array of words to the view variable. In an actual application, you will probably be getting the values from the database.

View

The view script simply iterates through the array of words and output them as a string separated by a newline character (\n). This is the format that the auto-completion script recognises.

Note the file extension of the view script; it is .ajax.phtml instead of .phtml. This is to provide an alternate view for AJAX requests separate from normal HTTP requests.

Modifying the Front-end

So now that we’ve got the back-end working, we need to modify the front-end now to send an AJAX request to the server. This is very simply done by changing the code to:

$('#username').autocomplete('http://localhost/project/index/format/html');

Change ‘localhost’ to the URL where your application resides. You should be familiar with the parts ‘project’ (controller) and ‘index’ (action). The remaining part ‘/format/html’ is to tell Zend that the request is an AJAX request. Without this part, Zend will not return the AJAX response.

So now if you refresh your page and type ‘L’ in the text box, you should be getting the list of names from the server.

Congratulations in getting your Zend application talk with jQuery through AJAX!

Post your questions in the comments. If I’m able to answer them, I will. Have fun coding!

Tags: php zend jquery
comments powered by Disqus