I just have created a patch for sfFormExtraPlugin. It provides a new form widget called sfWidgetFormJqueryTagSuggestion designed to suggest tags. It is based on the Tag Suggestion jQuery plugin of Remy Sharp.

You can download it from GitHub, just copy the files to the corresponding directories of your existing sfFormExtraPlugin installation or wait for upstream inclusion of my patch.
This widget integrates easily with sfPropelActAsTaggableBehaviorPlugin. Here is how to use it with this plugin.
You must have sfFormExtraPlugin with my patch and sfPropelActAsTaggableBehaviorPlugin properly installed and working. We consider that you have a model called Article with the taggable behavior.
Add jQuery to your javascripts
Like many others sfFormExtraPlugin widgets, the sfWidgetFormJqueryTagSuggestion requires jQuery to work. If you already have it installed, you can skip this step. Either, download jQuery to the
web/js/
directory of your project, open the
config/view.yml
file of your application and set it like that:
|
|
<code class="language-yaml">default: javascripts: [jquery-1.3.2.min.js]</code> |
Of course, change the filename if needed.
Put Javascripts and CSS into your web directory
sfFormExtraPlugin need some CSS and Javascripts to work properly, run the symfony plugin:publish-assets command to put them into corrects directories.
Create a static function to retrieve matching tags
Its time to extend the TagPeer model class to add it a method allowing to retrieve tags corresponding to a query. Creates a new file called MyTagPeer.class.php into the
lib/model/
directory of your project containing the following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
<code class="language-php">class MyTagPeer extends TagPeer { /** * Gets tags for a selector * * @param string $q * @param int $limit * @return array */ static public function retrieveForSelect($q, $limit = 10) { $criteria = new Criteria(); $criteria->add(TagPeer::NAME, '%'.$q.'%', Criteria::LIKE); $criteria->addAscendingOrderByColumn(TagPeer::NAME); $criteria->setLimit($limit); $tags = array(); foreach (TagPeer::doSelect($criteria) as $tag) { $tags[] = $tag->getName(); } return $tags; } }</code> |
Do not forget to run symfony cc to clear the cache after that.
Create a controller method to send the result as JSON
We have the model, we need the controller. Create a new module called tag by running symfony generate:module yourapp tag and add the following method to the tagActions class:
|
|
<code class="language-php">/** * Displays a JSON encoded tags array * * @param sfWebRequest $request * @return string */ public function executeSelect(sfWebRequest $request) { $this->getResponse()->setContentType('application/json'); $tags = MyTagPeer::retrieveForSelect($request->getParameter('tag')); return $this->renderText(json_encode($tags)); }</code> |
Open your
routing.yml
file and add the following line to be able to access this action:
|
|
<code class="language-php">tag_select: url: /select-tag param: { module: tag, action: select } </code> |
Modify your form to add the new tags suggestion widget
Open the form class you want to add this widget and add the following line to the end of the configure method:
|
|
<code class="language-php">$this->widgetSchema['tags'] = new sfWidgetFormJqueryTagSuggestion(array('url' => $this->getOption('url'), 'separator' => ', '));</code> |
We use the comma as separator instead of the space by default because this is the separator used by sfPropelActAsTaggableBehaviorPlugin.
Next, modify your call to the form in your actions to pass the AJAX URL as form option:
|
|
<code class="language-php">$this->form = new ArticleForm($article, array('url' => $this->generateUrl('article_select_tag')) );</code> |
It’s done!