Bonjour,
Je viens exposer un problème qui se pose à moi depuis quelques jours concernant le plugin sfFormExtra et plus précisément le widget sfWidgetFormJQueryAutocompleter. Celui-ci permet, lorsque une touche est enfoncée dans un champs input, d'afficher sous ce dernier une liste de valeurs tirées de la base de données grâce à un appel ajax vers le serveur, ce qui permet une saisie plus rapide des valeurs. Le problème est que je n'arrive pas à sauvegarder d'autres valeurs que celles présentes dans la base. Je vais illustrer mon problème grâce à un cas très simple.
Soit un projet symfony ayant le modèle suivant (schema.yml) :
Un modèle très simple, avec une seule table donc. Afin de mettre des valeurs dans la base de test j'ai préparé ces fixtures (fixtures.yml) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Personne: columns: nom: { type: string(255), notnull: true } ville: { type: string(255), notnull: true }
L'autocompletion portera sur le champ Ville qui contient trois valeurs distinctes. Le plugin sfFormExtra étant installé (ainsi que les librairies js liées, les css, etc...) voici le formulaire Personne :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 Personne: <?php for ($i=1; $i<=100; $i++): ?> personne_<?php echo $i ?>: nom: personne_<?php echo $i.chr(10) ?> ville: <?php echo ($i % 3 == 0 ? 'Paris' : ($i % 3 == 1 ? 'Londres' : 'Rome')).chr(10) ?> <?php endfor ?>
On note que le sfWidgetFormJqueryAutocompleter pointe vers une action personne/personneVilleAutocomplete (la fameuse option 'url'). Cette option renvoie du json permettant l'affichage de la liste par autocomplétion (de ce côté là tout fonctionne). Voici l'action class du module personne :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 class PersonneForm extends BasePersonneForm { public function configure() { sfContext::getInstance()->getConfiguration()->loadHelpers('Url'); $this->widgetSchema['nom'] = new sfWidgetFormInputText(); $this->widgetSchema['ville'] = new sfWidgetFormJQueryAutocompleter(array('url' => url_for('personne/personneVilleAutocomplete'))); } }
Je ne mets pas ici le code des templates. L'autocompletion fonctionne correctement. Si j'insère un nouveau contact, par exemple Gérard de Paris (Paris est une des valeurs présente pour le champ ville dans la table Personne) je trouverai ce nouvel élément dans phpMyAdmin, par contre je ne verrai pas Herbert de Montpellier après le form->save(), mais il est vrai que Montpellier n'est pas une valeur présente dans le champ ville.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 class personneActions extends sfActions { /** * Executes index action * * @param sfRequest $request A request object */ public function executeIndex(sfWebRequest $request) { $this->form = new PersonneForm(); } public function executeValider(sfWebRequest $request){ $this->form = new PersonneForm(); if($request->hasParameter('personne')){ $this->form->bind($request->getParameter('personne')); if ($this->form->isValid()){ $this->form->save(); } } } public function executePersonneVilleAutocomplete(sfWebRequest $request){ $this->getResponse()->setContentType('application/json'); $req = sprintf(" SELECT DISTINCT(ville) as ville FROM personne WHERE TRIM(UPPER(ville)) LIKE '%%%s%%' GROUP BY ville LIMIT %s", $request->getParameter('q'), $request->getParameter('limit')); $statement = Doctrine_Manager::getInstance()->connection(); $villes = $statement->execute($req)->fetchAll(); $response = array(); foreach($villes as $ville) $response[$ville['ville']] = $ville['ville']; return $this->renderText(json_encode($response)); } }
Pour résumer je ne peux sauvegarder que des tuples dont les champs de formulaires correspondants dotés d'un widget autocomplete ont été renseignés avec une valeur deja présente dans ce même champs côté base de données (j'essaie d'être le plus clair possible). Moi je voudrai pouvoir mettre n'importe quoi comme valeur.
Et là je butte sur ce gros caillou. Auriez-vous des idées ? Merci pour votre aide.
Partager