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", "/utility/search.city", // set params of element array( '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; $(eac).autocomplete({ minLength: 0, source: mysource, focus: function(event, ui) { $(eac).val(ui.item.label); return false; }, select: function(event, ui) { $(eac).val(ui.item.label); $(eac_id).val(ui.item.value); 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!




![Certification Authentication PHP Zend Certified Engineer [PHP5 Zend]](http://www.zend.com/images/training/certification_auth_logo_s.gif)
![[FSF Associate Member]](http://www.m4ss.net/wp-content/themes/m4ss/images/FSF_member.png)










