Petit guide pratique pour sfFormExtraPlugin
Sommaire
sfWidgetFormDoctrineJQueryAutocompleter
Intro
Avoir un input "text" qui aille chercher des enregistrements en base est extrêmement utile lorsqu'on veut trouver une parade à un select bien trop volumineux. Pour se faire, la solution se trouve, au moins partiellement dans le plugin dont il est question ici : sfFormExtraPlugin. Elle se nomme "sfWidgetFormJQueryAutocompleter".
Trouver le bon widget
Si vous fonctionnez avec Propel, rien à redire de plus, allez voir le tutoriel dédié, et tout sera réglé. Pour ceux qui sont sous Doctrine, la chose se complique à l'heure où j'écris ces lignes : il n'existe pas officiellement de widget spécialisé pour Doctrine, ce qui nous simplifierai quand même beaucoup la tâche. Allons donc fouiller dans le "trac" de Symfony : http://trac.symfony-project.org/ticket/6012
Récupérez le fichier attaché et ajoutez-le dans "lib/widget/". Videz le cache avec un "php symfony cc". Vous avez votre widget pour Doctrine. Mais ce n'est que le début.
Les mains dans le code
Le formulaire
Dans votre classe formulaire correspondante, effectuez les ajouts suivants (à adaptés à votre schéma, ici le module courant étant "individu" et les objets recherchés sont de la classe "Entreprise") à sa méthode "configure()" :
public function configure() { sfLoader::loadHelpers(array('Url')) $this->widgetSchema['entreprise_id']->setOption('renderer_class', 'sfWidgetFormDoctrineJQueryAutocompleter'); $this->widgetSchema['entreprise_id']->setOption('renderer_options', array( "model" => "Entreprise", "url" => url_for("individu/ajax"), )); }
L'action
Nous voyons ici que l'action appelée pour le module "individu" est "ajax". Il nous faut donc gérer cette action, en allant dans le fichier "apps/backend/modules/individu/actions/actions.class.php" et en créant la fonction "executeAjax()" de la manière suivante :
public function executeAjax($request) { $this->getResponse()->setContentType('application/json'); $request = Doctrine::getTable("Entreprise")->createQuery() ->where("nom_courant ILIKE ?","%".$request->getParameter('q')."%") ->limit($request->getParameter('limit')) ->execute() ->getData(); $entreprises = array(); foreach ( $request as $entreprise ) $entreprises[$entreprise->id] = (string) $entreprise; return $this->renderText(json_encode($entreprises)); }
Voilà, votre widget est chaud et prêt à servir !
cxWidgetFormDoctrineJQuerySelectMany
Intro
Avoir un widget permettant de sélectionner plusieurs enregistrements, type liaison n-n (many-to-many), dont la table cible est très volumineuse... cela se traduits par deux conséquences facheuses :
- temps de chargement long (voire même dépassant les limites autorisées par PHP)
- select "multiple" tellement long qu'il est impossible de bien s'y retrouver
Ainsi, je vous propose ici un widget très intéressant, développé à coté du projet symfony, dans un plugin venant en complément de sfFormExtraPlugin. Il se compose d'un sfWidgetFormJQueryAutocompleter et d'un select multiple.
Il se nomme "cxWidgetFormDoctrineJQuerySelectMany" (ou "cxWidgetFormPropelJQuerySelectMany" si vous utilisez Propel). Vous pouvez le trouver temporairement ici : http://www.libre-informatique.fr/stock/cxFormExtraPlugin-20090428-BeTa.tar.gz
Les mains dans le code
Le formulaire
Dans votre classe formulaire correspondante, effectuez les ajouts suivants (à adaptés à votre schéma, ici les objets recherchés sont de la classe "Entreprise" et nous reprenons la méthode Ajax définie précédemment dans le module "entreprise") à sa méthode "configure()" :
public function configure() { sfLoader::loadHelpers(array('Url')) $this->widgetSchema['entreprise_id'] = new sfWidgetFormDoctrineJQueryAutocompleter(array( "model" => "Entreprise", "url" => url_for('entreprise/ajax'), )); }
L'action
cf. exemple précédent.
Voilà, votre widget est chaud et prêt à servir !
Remerciements
Merci à tout le chan #symfony-fr @ freenode.net, en particulier [MA]Pascal, Garfield-fr, et en particulier crasher, ...
Merci aussi à Libre Informatique, pour le temps de travail pris à rédiger cette documentation.