IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

imbriquer dynamiquement des forms sur symfony


Sujet :

Symfony PHP

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 44
    Points : 21
    Points
    21
    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 : 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
    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 : 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
     
    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 : 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
    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 : 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
     
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public function executeAdd (sfWebRequest $request)
      {
        $this->form = new ArticleTagForm ();
      }
    et mon template addSuccess:
    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
     
    <?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

  2. #2
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    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.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 44
    Points : 21
    Points
    21
    Par défaut
    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

  4. #4
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    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.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 44
    Points : 21
    Points
    21
    Par défaut
    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

  6. #6
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    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.

Discussions similaires

  1. Connectivité pour délimiter des formes sur une photo
    Par romu37fr dans le forum C++Builder
    Réponses: 2
    Dernier message: 27/06/2007, 14h28
  2. Réponses: 4
    Dernier message: 18/04/2006, 23h09
  3. Récupérer le code des form sur Qt designer
    Par Death83 dans le forum Qt
    Réponses: 2
    Dernier message: 10/10/2005, 00h00
  4. Réponses: 1
    Dernier message: 15/09/2005, 12h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo