Archivi tag: autocomplete

Zend Form, jQuery and autocomplete

When a component in a Framework is inflexible and difficult to maintain I believe is time to change way. ZendX_JQuery is powerful but not in the jQuery UI Autocomplete. After a thorough discussion about Autocomplete now we are at a dead end and we can only wait a new release. I prefer to change my way and go ahead.

This is my different solution for Autocomplete UI in Zend Form (without ZendX_JQuery).

First of all I extended the Zend_Form with a general class My_Form where I can set all defaults values of decorators, filters, validators, etc. Then I added my createMyAutoComplete method:

class My_Form extends Zend_Form
    // autcomplete extension of idfield
    private $_acExtension = "_ac";
     *  Create My AutoComplete Elements
        public function createMyAutoComplete($id, $source, $params=array())
            $idAc = $id . $this->_acExtension; // support element id for autocomplete
            // Create autocomplete element
            $this->addElement('text', $idAc, $params);
            // Create autocomplete hidden element (for id field)
            $this->addElement('hidden', $id, array('decorators' => $this->_noElementDecorator));
            // Add my custom Javascript functions to onLoad
            $view = $this->getView();
            $view->jQuery()->addOnLoad("MyAutocomplete.initialize('".$id."', '".$source."', '".$this->_acExtension."');");
            // return id of element Autocomplete to manage in group, add params, ecc...
            return $idAc;

Above you can see the createMyAutoComplete method to generate an autocomplete field and its support field id. The parameters are:

  • $id = the id of the element
  • $source = the source where to read data for autocomplete
  • $params = like the params of the Zend_Form (see below)

As we seen the method creates two elements, for example, if we set $id=”idcity” we will have:

  • idcity, hidden field (our real id)
  • idcity_ac, text field (support field, only for autocomplete feature)

Remember to enable jQuery in the view otherwise the $view->jQuery->addOnLoad() above does not work!

Then you can call this method in the Forms:

class Application_Form_User_City extends My_Form
	public function init()
	         // Set the method for the display form to POST
	         $this->setAttrib('id', 'user_city_form')
				->setAttrib('class', 'f1n120');
	        // element: Description
	        $this->addElement('text', 'description', array(
	            'label'      => $this->translate('Description'),
	            'attribs'      => array('size' => 35),
	            'required'   => true,
	            'filters'    => array('StringTrim'),
	            'validators' => array('NotEmpty'),
	       // element: City
               $idAc = $this->createMyAutoComplete( "idcity",
                                         // set params of element
                                             'label'    => $this->translate('City'),
                                             'attribs'    => array('size' => 25),
                                             'required' => true,
                                             'ignore'   => true, // to ignore when submit
                                             'filters'    => array('StringTrim'),
                                             'validators' => array('NotEmpty'),

So we can create quickly an AutoComplete element and its hidden field.
Note: Add ignore attrib not submit this field. So we’ll submit directly the id.

To finish I created a custom Javascript to manage the autocomplete element.
Include this one in your Javascript file:

    MyAutocomplete = {
        initialize: function(idelement, mysource, acext)
            eac = '#' + idelement + acext;
            eac_id = '#' + idelement;
                minLength: 0,
                source: mysource,
                focus: function(event, ui) {
                    return false;
                select: function(event, ui) {
                    return false;
            .data( "autocomplete" )._renderItem = function( ul, item ) {
                return $( "<li></li>" )
                    .data( "item.autocomplete", item )
                    .append( "<a>" + item.label + "</a>" )
                    .appendTo( ul );

The ajax response from the source must be an array with two fields: label and value.
This js function prepare data for every single item (_renderItem) and set the the value on the hidden field (eac_id). Need 3 parameters:

  • idelement – the real id
  • source – where to read data
  • acext – the extension of the autocomplete field

This parameters are set automatically in the above My_Form class.
Try it!