Précédent   Forum des professionnels en informatique > PHP > Bibliothèques et frameworks > symfony
symfony Forum d'entraide sur le framework PHP symfony. Avant de poster : cours symfony et FAQ symfony
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 21/03/2011, 18h25   #1
Invité régulier
 
Inscription : septembre 2007
Messages : 37
Détails du profil
Informations forums :
Inscription : septembre 2007
Messages : 37
Points : 5
Points : 5
Par défaut imbriquer dynamiquement des forms sur symfony

Bonjour,
je galère pour imbriquer dynamiquement des forms sur symfony et j'aimerai vos avis et conseils. J'ai cherché un peu partout, j'ai trouvé des bouts de réponse mais qui ne correspondent pas exactement à mon cas. J'ai donc des articles que j'aimerai associer à des tags ou non.
voici mon schéma (je simplifie au maximum):
Code :
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
 
Tag:
  connection: doctrine
  tableName: tag
  columns:
    id:
      type: integer(8)
      fixed: false
      unsigned: false
      primary: true
      sequence: tag_id
    nom:
      type: string()
      fixed: false
      unsigned: false
      notnull: true
      primary: false
  relations:
    ArticleTag:
      local: id
      foreign: tag_id
      type: many
Article:
  connection: doctrine
  tableName: article
  columns:
    id:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: true
      sequence: article_id
    nom:
      type: string()
      fixed: false
      unsigned: false
      notnull: true
      primary: false
    choixtag:
      type: integer(2)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
  relations:
    ArticleTag:
      local: id
      foreign: article_id
      type: many
ArticleTag:
  connection: doctrine
  tableName: article_tag
  columns:
    id:
      type: integer(8)
      fixed: false
      unsigned: false
      primary: true
      sequence: article_tag_id
    article_id:
      type: integer(4)
      fixed: false
      unsigned: false
      notnull: false
      primary: false
    tag_id:
      type: integer(4)
      fixed: false
      unsigned: false
      notnull: false
      primary: false
  relations:
    Article:
      local: article_id
      foreign: id
      type: one
    Tag:
      local: tag_id
      foreign: id
      type: one
j'ai ensuite créé un module Article puis j'ai modifié ma classe ArticleForm de la sorte:

Code :
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
 
class ArticleForm extends BaseArticleForm
{
	public function configure ()
  	{  		
		$this -> setWidgets (array (
		    'nom'   => new sfWidgetFormInput (),
                    'choixtag'   => new sfWidgetFormDoctrineChoice (0 => "non",  1 => "oui")
	        ));
 
	       $this -> widgetSchema -> setLabels (
                    blabla...
		));
 
		$this -> setValidators (
                    blabla...
		));
 
		$this -> validatorSchema -> setPostValidator (
                    blabla...
		);
 
		$this -> widgetSchema -> setNameFormat ('article[%s]');
 
  	}
}
puis j'ai modifié mon template newSuccess.php de mon module Article:
Code :
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
 
<?php use_javascript('/sfFormExtraPlugin/js/double_list.js') ?>
 
<script type="text/javascript">
jQuery().ready(function() {
 
	var choixId = jQuery("#article_article_tag_id").val();
	articletagadd (choixId);
 
	jQuery("#article_article_tag_id").change(
		function(event) {
			var choixId = jQuery(event.target).val();
			articletagadd (choixId);
  		}
  	);
});
 
function articletagadd (choixId) {
	if (1 == choixId) {
		jQuery.post('<?php echo url_for('articletag/add') ?>',
		{},
		function(data)
		{			    	
			jQuery("#affectation").html(data);
		});
	} else {
		jQuery("#affectation").empty();
	}
}
 
</script>
 
<?php use_helper ('I18N') ?>
 
<form action="<?php echo url_for('article/create') ?>" method="post" <?php $form -> isMultipart() and print 'enctype="multipart/form-data" ' ?> id="newArticle" class="form">
 
		<?php if ($form -> hasGlobalErrors ()): ?>
	    	<ul class="globalErrors">
	    		<?php foreach ($form -> getGlobalErrors () as $name => $error): ?>
	        	<li>- <?php echo $error ?></li>
	        	<?php endforeach; ?>
	    	</ul>
		<?php endif; ?>	
 
		<fieldset>
 
			<?php foreach ($form as $widget): ?>
 
				<?php if (!$widget -> isHidden ()) { ?>
 
				<div class="widget">
 
					<?php if ($widget -> hasError ()): ?>
					<div class="error">
					<?php echo $widget -> renderError () ?>
					</div>
					<?php endif; ?>
 
					<?php echo $widget -> renderLabel () ?>
 
					<?php echo $widget -> render() ?>
 
					<?php if ($widget -> renderHelp ()): ?>
					<p class="note"><?php echo $widget -> renderHelp () ?></p>
					<?php endif; ?>
 
				</div>
 
				<?php } else { ?>
 
					<?php echo $widget -> render () ?>
 
				<?php } ?>
 
			<?php endforeach; ?>
 
			<div id="affectation" />
 
		</fieldset>
 
		<button type="submit" class="button"><?php echo __('Add') ?></button>
 
</form>
j'ai aussi créé mon module ArticleTag pour l'association donc voici la classe ArticleTagForm:
Code :
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
 
class ArticleTagForm extends BaseArticleTagForm
{
	public function configure()
  	{
  		$aChoices = array();
		foreach ($aTags = Doctrine::getTable ('Tag') -> getAll() as $oTag) {
  			$aChoices[$oTag-> id] = $oTag-> nom;
		}
 
  		$this -> setWidgets (array (
		     'affectation' => new sfWidgetFormSelectDoubleList (array(
	    	 	'choices' => $aChoices,
	    	  	'label_associated' => 'Associated',  
	    	  	'label_unassociated' => 'Unassociated'
	    	 ))
	    ));
 
	    $this -> widgetSchema -> setLabels (array (
	  		'affectation' => 'Assignment'
		));
 
  		$this -> widgetSchema -> setNameFormat ('article[%s]');
  	}
}
mon action:
Code :
1
2
3
4
5
 
public function executeAdd (sfWebRequest $request)
  {
    $this->form = new ArticleTagForm ();
  }
et mon template addSuccess:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
<?php use_helper ('I18N') ?>
 
<div class="widget">
 
		<?php if ($form['affectation'] -> hasError ()): ?>
		<div class="error">
		<?php echo $form['affectation'] -> renderError () ?>
		</div>
		<?php endif; ?>
 
		<?php echo $form['affectation'] -> renderLabel () ?>
 
		<?php echo $form['affectation'] -> render() ?>
 
</div>
donc c'est tout beau j'ai bien mon formulaire, quant je sélectionne le choix "oui" j'ai bien mon multiplemachinselect qui s'affiche avec mes tag dans "non associé".
Cependant quant je clique sur le bouton "ajouter" j'ai ce message : "Unexpected extra form field named "affectation"."
je me doute bien qu'il faut lui dire quelque part qu'il y a un champ affection à associer a mon formulaire principale. De plus je perd mes choix de sélection de tag (faut imaginer que j'en ai sélectionné bcp ^^). Apres ou est qu'on rajoute en DB l'association Article Form ? du coté du formulaire principale ? ou de actionclass.php du module ArticleTag.
je suis un peu perdu si vous avez des idées, si j'ai fait fausse route ou pas, des exemples d'utilisation, je suis preneur.
Merci d'avance
Wind
wind_of_o est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/03/2011, 11h57   #2
Modérateur
 
Avatar de Michel Rotta
 
Homme Michel Rotta
Responsable d'exploitation informatique
Inscription : septembre 2005
Messages : 4 913
Détails du profil
Informations personnelles :
Nom : Homme Michel Rotta
Âge : 49
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Responsable d'exploitation informatique
Secteur : Distribution

Informations forums :
Inscription : septembre 2005
Messages : 4 913
Points : 7 505
Points : 7 505
Le plugin sfDoctrineActAsTaggablePlugin gère correctement les tag, plus d'information dans la salle plugin dans le sujet sur les plugins les plus utilisés

J'avoue que ton message est un peu long et demanderait à recréer, en local, les mêmes conditions que les tiennes pour pouvoir être utilisé, ce qui n'est pas possible (question de temps).

J'ai l'impression qu'il faut que tu éclaircisses avant, et pour toi, ton schéma de qui fait quoi (humain et couches logiciels). Un petit schéma UML là pourrait t'aider à y voir plus claire.

N'oublie pas la possibilité de travailler en mode dégrader (sans javascript) à éventuellement prendre en compte.

Vu ton approche, je dirais que si c'est ajax qui affiche les tag, c'est ajax qui envoie les modifs. Attention à ce qui ce passe alors lors de la création d'un enregistrement (qui existe virtuellement à l'écran mais pas en base), tu ne peux sauvegarder de tag pour un enregistrement qui n'a pas été sauvegardé en base et tu dois sauvegarder les tag avant d'envoyer le form en validation... Il faut bien réfléchir avant de mettre ceci en œuvre.
__________________
Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).
  • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
  • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
  • Une discussion est terminée ? Alors le bouton est votre ami !
Michel Rotta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/03/2011, 13h05   #3
Invité régulier
 
Inscription : septembre 2007
Messages : 37
Détails du profil
Informations forums :
Inscription : septembre 2007
Messages : 37
Points : 5
Points : 5
l'exemple des tags était bidon je n'utilise pas du tout des tags, j'ai juste essayé de traduire mon problème en un exemple simple, d'ou l'idée avec des articles et des tags.

J'ai donné pas mal de code juste pour avoir un aperçu de la méthode que j'essayai de mettre en place.

Plus littéralement, j'aimerai faire apparaitre en ajax un sfWidgetFormSelectDoubleList dépendant d'un choix utilisateur, exemple je veux associer des tags à un article ou pas.
Donc si je sélectionne "oui" à une association de tag, mon sfWidgetFormSelectDoubleList apparait.
Ca c'est pour le coté fonctionnel.

Coté DB c'est assez simple, on a une table Article, une table Tag (qui regroupe tous les tags possibles) et une table ArticleTag qui traduit l'association quant il y en a une oue plusieurs, exemple d'enregistrement:

Article (id=1 nom='CD')
Tag (id=1 nom='musique', id=2 nom='voiture')
ArticleTag (id=1 article_id=1 tag_id=1)

et étant débutant sur symfony je ne sais guère comment procéder de façon conventionnel.

Wind
wind_of_o est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/03/2011, 14h53   #4
Modérateur
 
Avatar de Michel Rotta
 
Homme Michel Rotta
Responsable d'exploitation informatique
Inscription : septembre 2005
Messages : 4 913
Détails du profil
Informations personnelles :
Nom : Homme Michel Rotta
Âge : 49
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Responsable d'exploitation informatique
Secteur : Distribution

Informations forums :
Inscription : septembre 2005
Messages : 4 913
Points : 7 505
Points : 7 505
J'ai du mal a suivre.

Tu dis : "l'exemple des tags était bidon..." soit, mais tu ne parles que de tag derrière...

Regardes le fonctionnement du plugin. Démontes son code, tu devrais trouver des réponses.

Mets au propre (au sens propre et au sens figuré) qui doit faire quoi dans ton interface idéale.
__________________
Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).
  • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
  • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
  • Une discussion est terminée ? Alors le bouton est votre ami !
Michel Rotta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/03/2011, 15h07   #5
Invité régulier
 
Inscription : septembre 2007
Messages : 37
Détails du profil
Informations forums :
Inscription : septembre 2007
Messages : 37
Points : 5
Points : 5
Visiblement mon langage "sms" en déroute certain ...

J'ai une problématique qui n'a juste rien à voir avec des tags, j'ai essayé de transposer mon problème en un exemple simple pour qu'un maximum de gens puissent m'aider à "réflectionner" sur l'imbrication de formulaires dynamiquement, c'est tout.

Merci tout de même à ton implication intensive pour faire vivre ce forum.

Quant j'aurai suffisamment de vécu et de recul sur Symfony j'y participerai également.

Wind
wind_of_o est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/03/2011, 15h19   #6
Modérateur
 
Avatar de Michel Rotta
 
Homme Michel Rotta
Responsable d'exploitation informatique
Inscription : septembre 2005
Messages : 4 913
Détails du profil
Informations personnelles :
Nom : Homme Michel Rotta
Âge : 49
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Responsable d'exploitation informatique
Secteur : Distribution

Informations forums :
Inscription : septembre 2005
Messages : 4 913
Points : 7 505
Points : 7 505
Pour gérer ce type de cas, tu as deux possibilités, une basée sur des forms généré en PHP et traités en PHP. Un peux comme celle utilisé par le plugin.

Cas PHP pure.
Tu coches la case "je veux des tags" et valide le form.
PHP réaffiche le form avec les widgets permettant de gérer les tags (si la liaison n-n entre la table article et tag est bien faîte, il n'y a presque rien à inventer, la génération s'occupe de presque tout (il faut choisir le type d'affichage) ).

Avantage, à la création pas de problème, la case n'est pas cochée. Valider l'enregistrement va le sauvegarder avant d'afficher les choix, donc on travaillera toujours sur un enregistrement existant.


Cas AJAX.
Tu coches la case "je veux des tags".
JS va créer (ou afficher) les zones de saisie.

Le principe veux que, si les zones sont créer par JS, c'est JS qui prépare et envoie les données. Par contre, si elle sont pré préparée par le form et juste affichée par le code JS, elle peuvent être validées par le PHP qui les a créées.

Reste le cas de zones créées par JS et validées par du PHP, ce n'est jamais l'idéal, même si, bien écris, cela peut marcher. C'est par contre très sensible aux moindres modifications futures.
__________________
Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).
  • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
  • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
  • Une discussion est terminée ? Alors le bouton est votre ami !
Michel Rotta est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 23h14.


 
 
 
 
Partenaires

Hébergement Web