Creating Autocomplete input field for Symfony based web form

Posted on Category:Symfony

This post describes steps required to create jQuery/AJAX input text field with autocomplete feature using Symfony php framework. It is assumed that you know how to create a web form, and install Symfony plugins, so that part won’t be explained here.
A Symfony plugin sfFormExtraPlugin is required, and, of course, jQuery (I’m using sfJqueryReloadedPlugin).

In form class add this to enable jQuery Autocomplete widget:
[php]
# lib/form/Doctrine/YourFormName.class.php

$city = new sfWidgetFormDoctrineJQueryAutocompleter(array(
‘url’ => ‘/autocomplete’,
‘model’ => ‘City’,
‘value_callback’ => ‘findOneById’
));

$this->setWidget(‘city_id’, $city);
[/php]
Note that widget requires parameters url, model and value_callback to work properly. Here is a brief overview of their meanings:

  • url: URL name on which Autocomplete widget will send queries for possible values
  • model: Name of model that will be used for transforming ID’s to text values of autocomplete options
  • value_callback: Method that will be used for transforming ID’s to text values

You’ll need to create action to handle Autocompleter’s requests. Create one in some module like this:
[php]
# apps/frontend/modules/MODULE_NAME/actions/actions.class.php

public function executeAutocomplete(sfWebRequest $request)
{
$result = Doctrine_Core::getTable(‘City’)
->findCityByName($request[‘q’])
->toKeyValueArray(‘id’, ‘title’);
return $this->renderText(json_encode($result));
}
[/php]
This Action will search Table “City” for entries that resemble search request and return them in a JSON array required by Autocomplete plugin.
Add a route to routing.yml file:
[php]
autocomplete:
url: /autocomplete
param: { module: MODULE_NAME, action autocomplete}
[/php]

Finally, add a method in model class to handle queries required by your action method:
[php]
public function findCityByName($name, $limit=10)
{
return Doctrine_Core::getTable(‘City’)
->createQuery(‘c’)
->where(“c.title LIKE ‘%{$name}%'”)
->limit($limit)
->execute();
}
[/php]