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 :

Enregistrer deux instances de la même Entité dans un seul formulaire [2.x]


Sujet :

Symfony PHP

  1. #1
    Membre du Club
    Homme Profil pro
    developpeur
    Inscrit en
    Février 2010
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : developpeur

    Informations forums :
    Inscription : Février 2010
    Messages : 54
    Points : 65
    Points
    65
    Par défaut Enregistrer deux instances de la même Entité dans un seul formulaire
    Bonjour,
    Je souhaiterais pouvoir persister en un seul formulaire deux instances d'une même entité. Pour cela, j'ai créé un formulaire en appelant deux fois la méthode createForm (avec les mêmes arguments...) depuis un controlleur. Je suppose que cette pratique est douteuse. Voici le code que j'ai placé dans celui-ci :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public function newAction($id, $nb)
    {
        $forms = array();
        for ($i = 1; $i <= $nb; $i++) {
            $entity = new Noeud();
            $forms[]   = $this->createForm(new NoeudType(), $entity)->createView();
        }
     
        return $this->render('PaipaiCatalogueBundle:Noeud:remplircontenu.html.twig', array(
            'forms'   => $forms,
            'id'      => $id
        ));
    }
    la classe NoeudType :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class NoeudType extends AbstractType
    {
        public function buildForm(FormBuilder $builder, array $options)
        {
            $builder
                ->add('nom')
            ;
        }
    }
    le fichier twig associé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <form action="{{ path('noeud_creercontenu4', { 'id': id}) }}" method="post" {{ form_enctype(forms[0]) }}>
     
    {% for formulaire in forms %}
        {{ form_widget(formulaire) }}
    {% endfor %}
        <p>
            <button type="submit">Create</button>
        </p>
    </form>
    Avec ce code, les 2 champs texte ont le même attribut name (il est composé du nom de l'entité suivi du nom de la propriété entre crochet). J'imagine que c'est normal puisque j'instancie deux formulaires sans établir de lien entre eux... Au final je ne récupère les infos que sur une seule instance. Comment pensez vous faire ??
    Merci d'avance et bonne journée

  2. #2
    Membre actif
    Homme Profil pro
    Freelance
    Inscrit en
    Décembre 2003
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : Décembre 2003
    Messages : 423
    Points : 259
    Points
    259
    Par défaut


    A mon avis le problème est surtout que tes deux formulaires ont le même "nom" ... du coup tes champs (formatés à partir du nom du formulaire et du nom du champ) sont identiques ... du coup ta requête Post ne contiendra qu'une seule key ... exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    <form ...>
      <input type="text" name="noeud[name]" />
      <input type="text" name="noeud[name]" />
    </form>
    à la soumission de ce formulaire ta variable $_POST ne contiendra qu'une seule entrée $_POST[noeud][name].


    Du coup ce que je pense qu'il faut que tu fasses c'est :
    1- Modifier ton constructeur
    2- Modifier la méthode getName()

    Quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    class NoeudFormType extends AbstractType
    {
        protected $nameSuffix;
        public function __construct($nameSuffix=null)
        {
            $this->nameSuffix = is_null($nameSuffix)?'':$nameSuffix;
            parent::__construct(); // Pas nécessaire
        }
     
        public function getName()
        {
            return parent::getName().$this->nameSuffix;
        }
    Du coup lors de l'utilisation (dans ton Controller) tu peux tenter quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    $forms = array();
        for ($i = 1; $i <= $nb; $i++) {
            $entity = new Noeud();
            $forms[]   = $this->createForm(new NoeudType($i), $entity)->createView();
        }
    sans conviction sur ma proposition de résolution, mais le soucis originel est une question de "nom des champs en double sur ta page".


    Bonne chance
    "La théorie, c’est quand on sait tout et que rien ne fonctionne. La pratique, c’est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : rien ne fonctionne ... et personne ne sait pourquoi !" et malheureusement c'est souvent le cas en Développement...

  3. #3
    Membre actif
    Homme Profil pro
    Freelance
    Inscrit en
    Décembre 2003
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : Décembre 2003
    Messages : 423
    Points : 259
    Points
    259
    Par défaut
    Re,

    Une meilleur solution serait peut-être aussi de faire un formulaire plus général et de faire de l'incrustation de formulaires (via une collection).

    Voir : http://symfony.com/doc/current/book/...ction-of-forms

    Certaines contraintes son cela dit à vérifier.
    "La théorie, c’est quand on sait tout et que rien ne fonctionne. La pratique, c’est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : rien ne fonctionne ... et personne ne sait pourquoi !" et malheureusement c'est souvent le cas en Développement...

  4. #4
    Membre du Club
    Homme Profil pro
    developpeur
    Inscrit en
    Février 2010
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : developpeur

    Informations forums :
    Inscription : Février 2010
    Messages : 54
    Points : 65
    Points
    65
    Par défaut
    Bonjour Bleys,
    Et bien écoute j'ai suivi ton premier conseil ( en fait je ne connaissais pas la méthode getName() ) du coup mon problème est résolu ! Effectivement peut-être existe-t-il d'autres solutions ? en tout cas celle ci me convient !
    Merci et bonne journée

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2013
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Bonjour,désolé de déterrer ce sujet,mais je cherche la même chose que lhapaipai,et je comprend pas trop la réponse de Bleys surtout pour la classe NoeudFormType .
    voici mes codes:

    contrôleur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $forms = array();
     
        for ($i = 1; $i <= 5; $i++) {
            $entre = new EntreeTP();
            $forms[]   = $this->createForm(new EntreeTPType($i), $entre)->createView();
    EntreeTPType
    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
      public function buildForm(FormBuilderInterface $builder, array $options)
        {
     
     
     $builder
     
                ->add('tempsPasse','text',array('label'  => ' '))
     
            ;
        }
     
        /**
         * @param OptionsResolverInterface $resolver
         */
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'Grc\GtpBundle\Entity\EntreeTP'
            ));
        }
     
        /**
         * @return string
         */
        public function getName()
        {
            return 'grc_gtpbundle_entreetp';
        }
    }
    formulaire à inclure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <form  method="post" {{ form_enctype(forms[0]) }}>
     
    {% for formulaire in forms %}
        <td>{{ form_widget(formulaire) }}</td>
    {% endfor %}
        <p>
            <button type="submit">valider</button>
        </p>
    </form>

  6. #6
    Membre actif
    Homme Profil pro
    Freelance
    Inscrit en
    Décembre 2003
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Freelance

    Informations forums :
    Inscription : Décembre 2003
    Messages : 423
    Points : 259
    Points
    259
    Par défaut
    Bonjour,

    Oublie ma réponse qui est bien obsolète et très en dehors du principe de formulaires de Symfony.

    Intéresse-toi plutôt au type de formulaire Collection.
    Je vais répondre très succinctement, mais l'idée serait donc plutôt de créer un formulaire qui contient un champ Collection et dont le formType de ta collection est ton EntreeTPType.

    Reste ensuite à initialiser tes données correctement pour transmettre tes 5 entrées initiales éventuellement, et ce sera plus propre.

    Nullement besoin de X formulaires ici (la var $forms et en plus c'est pas dans la logique du composant form). Ce devrait être 1 formulaire qui contient une collection de EntreeTPType.

    Plus d'infos par ici : http://symfony.com/fr/doc/current/re...ollection.html

    Bon code !
    "La théorie, c’est quand on sait tout et que rien ne fonctionne. La pratique, c’est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : rien ne fonctionne ... et personne ne sait pourquoi !" et malheureusement c'est souvent le cas en Développement...

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2013
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Merci Bleys pour ta réponse,je vais suivre ton lien.

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2013
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2013
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Bonjour,en essayant d'utiliser les collections je me retrouve avec cette erreur : "FatalErrorException: Error: Maximum function nesting level of '100' reached, aborting! in C:\wamp\www\Symfony\src\Grc\GtpBundle\Form\EntreeTPType.php line 48"
    j'ai cherché sur internet ,j'ai trouvé qu'il faut mettre une valeur supérieure à 100 à la ligne xdebug.max_nesting_level = 100 mais je la trouve pas dans mon php.ini.

    voila ce que j'ai fait:

    Contrôleur:

    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
     
    namespace Grc\GtpBundle\Controller;
     
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Symfony\Component\HttpFoundation\Response;
     
    use Grc\GtpBundle\Entity\EntreeTP;
    use Grc\GtpBundle\Form\EntreeTPType;
     
     
    $entree = new EntreeTP;
    $form = $this->createForm(new EntreeTPType, $entree);
     
    return $this->render('GrcGtpBundle:Gtp:feuilleTP.html.twig', array('nomMois'=>$nom_mois,'annee'=>$annee,							'dateDebSemaineFr'=>$dateDebSemaineFr,'num_week'=>$num_week,'jourTexte'=>$jourTexte,'dateSemaine'=>$dateSemaine,
    								'urlP'=>$urlP,'urlN'=>$urlN,'form'=>$form->createView())
    								);
    EntreeTPType
    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
    namespace Grc\GtpBundle\Form;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    
     $builder
            
    			->add( 'tempsPasse','collection',array(
    			'type' => new EntreeTPType(),
                 'allow_add'    => true,
                'allow_delete' => true,
    			'options' =>array(
    			'label'  => ' ')))
    
            ;
        }
        
        /**
         * @param OptionsResolverInterface $resolver
         */
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'Grc\GtpBundle\Entity\EntreeTP'
            ));
        }
    
        /**
         * @return string
         */
        public function getName()
        {
            return 'grc_gtpbundle_entreetp'; //FatalErrorException: Error: Maximum function nesting level of '100' reached, aborting! in C:\wamp\www\Symfony\src\Grc\GtpBundle\Form\EntreeTPType.php line 48
        }
    }
    Merci d'avance pour votre aide.

    Edit: j'ai créé un nouveau sujet voir ce lien http://www.developpez.net/forums/d14...g/#post7853274

  9. #9
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2013
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2013
    Messages : 1
    Points : 3
    Points
    3
    Par défaut Demande aide
    Bonjour Bleys,

    Désolé de revenir sur ce vieux topic, mais je suis fasse à un problème similaire et j'ai utilisé ta première méthode, mais cependant je demande qu'on la persistance de mes données vont se faire au niveau de mon controller étant donner que je reçois un array de mon formulaire. Pouvez-vous me montrer la démarche à suivre pour persister les données svp.


    Merci Cordialement.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. editer plusieurs entitées dans un seul formulaire.
    Par lepirlouit dans le forum Struts 1
    Réponses: 1
    Dernier message: 01/04/2010, 11h18
  2. comment créer deux instances d'une même base de données
    Par Dev_info dans le forum Administration
    Réponses: 5
    Dernier message: 19/03/2008, 18h59
  3. Deux instances avec le même nom.
    Par Denn's dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 14/03/2008, 09h09
  4. Réponses: 11
    Dernier message: 30/06/2007, 04h34
  5. Réponses: 2
    Dernier message: 09/06/2006, 19h34

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