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 :

Symfony 2 : formulaires de collections imbriquées


Sujet :

Symfony PHP

  1. #1
    Membre confirmé Avatar de ben.IT
    Homme Profil pro
    Inscrit en
    Janvier 2009
    Messages
    431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 431
    Points : 486
    Points
    486
    Par défaut Symfony 2 : formulaires de collections imbriquées
    salut,
    j'essaye de faire un formulaire contenant des sous formulaires de collections imbriquées.
    Voici la composition du formType :


    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
    class ParentFormType extends AbstractType 
    {
     
    	public function buildForm(FormBuilderInterface $builder, array $options) 
    	{	
    		$builder
    		      ->add('case', 'choice', array(
    				        'choices'   => array(
        						'case1'   =>  'case1',
        						'case2'   =>  'case2',
        						'case3'   =>  'case3',
    				)))
       			->add ('subForm1', 'collection', array (
    			 'type' => new Sub1FormType(),
    			 'allow_add' => true,
    			 'allow_delete' => true,
    			 'by_reference' => false
    			))
     
    	;
     
    		$builder->add('save',"submit") ;
    	}
     
     
    	public function setDefaultOptions(OptionsResolverInterface $resolver) {
    	}
     
    	public function getName() {
    		return 'formtestparenttype';
    	}
    }
    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 Sub1FormType extends AbstractType 
    {
     
    	public function buildForm(FormBuilderInterface $builder, array $options) 
    	{	
     
    		$builder
    		  ->add('fieldSub1',"text" )
    		  ->add ('childForm1', 'collection', array (
    		      'type' => new Sub2FormType,
    		      'allow_add' => true,
    		      'allow_delete' => true,
    		      'by_reference' => false
    		  ))
    		  ;
    	}
     
     
    	public function setDefaultOptions(OptionsResolverInterface $resolver) {
     
    	}
     
    	public function getName() {
    		return 'formtestsub1type';
    	}
    }
    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 Sub2FormType extends AbstractType 
    {
     
    	public function buildForm(FormBuilderInterface $builder, array $options) 
    	{	
     
    		$builder
    		       ->add('fieldSub2',"text" )
    		  	   ->add ('childForm1', 'collection', array (
    		      'type' => "text",
    		      'allow_add' => true,
    		      'allow_delete' => true,
    		      'by_reference' => false
    		  ))
    		  ;
    	}
     
     
    	public function setDefaultOptions(OptionsResolverInterface $resolver) {
     
    	}
     
    	public function getName() {
    		return 'formtestsub2type';
    	}
    }
    dans le controller :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     $form = $this->createForm(new ParentFormType() ) ;
    La ou je bloque, c'est sur la partie js pour ajouter dynamiquement les sous sous collections, est ce que quelqu'un aurait une idée, un exemple ?
    J'arrive à gérer les collections de profondeurs de niveau 1 mais pas de niveau 2.
    merci,
    ben

  2. #2
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    ya mannn rastafariiiiiiiiiiiiiiiiiiii,


    tu peux ajouter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    'prototype' => true,
    mais je pense que ça ne va pas regler ton problème.

    à partir du moment ou c'est une collection et qu'il y a allow_add et allow_delete ça se fait automatiquement


    qu'entends tu par gérer ? les boutons ADD et DELETE n'apparaisse pas, ne fonctionne pas ?

  3. #3
    Membre confirmé Avatar de ben.IT
    Homme Profil pro
    Inscrit en
    Janvier 2009
    Messages
    431
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 431
    Points : 486
    Points
    486
    Par défaut
    Salut,
    là ou je galère c'est que je n'arrive pas à afficher la sous collection, je pense que c'est mon JS qui n'est pas bon : voici mon twig+js :
    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
     
    {% extends '::base.html.twig' %}
    {% block body %}
     
    {{ form_start(form) }}
        {# render the task's only field: description #}
     
        <h3>Tags</h3>
        <ul class="subForm1" data-prototype="{{ form_widget(form.subForm1.vars.prototype)|e }}">
            {# iterate over each existing tag and render its only field: name #}
            {% for subForm1 in form.subForm1 %}
                <li>{{ form_row(subForm1) }}</li>
                 <ul class="subForm2" data-prototype="{{ form_widget(subForm2.vars.prototype)|e }}">
                {%for subForm2 in subForm1.subForm2 %}
                    <li>{{ form_row(subForm2) }}</li>
                {% endfor %}
     
            {% endfor %}
        </ul>
    {{ form_end(form) }}
     
     
     
    <script>
    var $collectionHolder;
     
    // setup an "add a tag" link
    var $addTagLink = $('<a href="#" class="add_tag_link">Add</a>');
    var $newLinkLi = $('<li></li>').append($addTagLink);
     
    jQuery(document).ready(function() {
     
     
        function addTagForm($collectionHolder, $newLinkLi) {
        // Get the data-prototype explained earlier
        var prototype = $collectionHolder.data('prototype');
     
        // get the new index
        var index = $collectionHolder.data('index');
     
        // Replace '__name__' in the prototype's HTML to
        // instead be a number based on how many items we have
        var newForm = prototype.replace(/__name__/g, index);
     
        // increase the index with one for the next item
        $collectionHolder.data('index', index + 1);
     
        // Display the form in the page in an li, before the "Add a tag" link li
        var $newFormLi = $('<li></li>').append(newForm);
        $newLinkLi.before($newFormLi);
    }
     
     
        $collectionHolder = $('ul.subForm1');
        $collectionHolder.append($newLinkLi);
     
        // count the current form inputs we have (e.g. 2), use that as the new
        // index when inserting a new item (e.g. 2)
        $collectionHolder.data('index', $collectionHolder.find(':input').length);
     
        $addTagLink.on('click', function(e) {
            e.preventDefault();
            addTagForm($collectionHolder, $newLinkLi);
        });
    });
    </script>
    {% endblock %}
    une idée ?
    a+

  4. #4
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    et en utilisant simplement un form_widget(nom_form)

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 3
    Points : 4
    Points
    4
    Par défaut
    J'ai eu affaire à ce problème et déjà il faut changer dans tes formType le __name__ en ajoutant un paramètre pour chaque collection :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    'prototype_name' => '__name__'
    avec à la place de __name__ un nom différent.

    Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ->add ('subForm1', 'collection', array (
    			 'type' => new Sub1FormType(),
    			 'allow_add' => true,
    			 'allow_delete' => true,
    			 'by_reference' => false
                             'prototype_name' => '__sub1__'
    			))
    Ensuite côté javascript tu ne peux pas utiliser la fonction javascript donnée par symfony tel quel. Il faut l'adapter de manière à pouvoir changer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var newForm = prototype.replace(/__name__/g, index);
    en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    var reg = new RegExp(prototype_name, 'g');
    var newElement = prototype.replace(reg, index);
    et bien vérifier que l'index est l'index du sous formulaire à l'intèrieur du formulaire parent. En gros
    Parent 1
    - Enfant 1
    - Enfant 2
    - Enfant n

    Parent 2
    - Enfant 3 (et pas ça)
    - Enfant 1
    - Enfant 2
    - Enfant n

    par contre à la validation quand tu as ajouté un formulaire parent via javascript si tu as une erreur du style

    Catchable Fatal Error: Argument 1 passed to TC\GlobalBundle\Entity\question::setMedias() must be an instance of Doctrine\Common\Collections\ArrayCollection, array given, called in /var/www/tc/vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php on line 438 and defined in /var/www/tc/src/TC/GlobalBundle/Entity/question.php line 260

    Comme j'ai eu dans mon code ben je ne saurai pas t'aider car j'ai eu le problème et je suis toujours dessus...

Discussions similaires

  1. [2.x] [Symfony 2] Formulaire imbriqué + Check & combobox
    Par REF26 dans le forum Symfony
    Réponses: 1
    Dernier message: 19/12/2013, 13h56
  2. [AC-2007] envoi de formulaire pour collecte de données
    Par Alain7751 dans le forum IHM
    Réponses: 1
    Dernier message: 31/07/2009, 14h49
  3. Session Formulaire et Collection
    Par Snyper dans le forum Struts 1
    Réponses: 7
    Dernier message: 05/04/2009, 12h56
  4. Réponses: 9
    Dernier message: 30/08/2008, 20h31
  5. [Spring MVC] Problème formulaire avec Collection
    Par arN34 dans le forum Spring Web
    Réponses: 1
    Dernier message: 16/09/2006, 13h17

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