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 :

Problème d'affichage d' un formulaire de type Collection [2.x]


Sujet :

Symfony PHP

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2014
    Messages : 9
    Points : 7
    Points
    7
    Par défaut Problème d'affichage d' un formulaire de type Collection
    Bonjour ,
    J'essaye de construire un formulaire imbriqué (Article et Commentaire ) , je me demande pourquoi les champs du formulaire Commentaire ne s'affiche pas au niveau de la vue .



    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
     <?php
     
    namespace Blog\newsBundle\Form;
     
    use Blog\newsBundle\Entity\Picture;
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    use Blog\newsBundle\Form\CommentaireType;
     
    class ArticleType extends AbstractType
    {
            /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('titre','text')
                ->add('auteur','text')
                ->add('datePub',"date")
                ->add('contenue',"textarea")
                ->add('commentaires','collection',array( 'type' => new CommentaireType(), 'prototype'=>true,'allow_add' =>true,'by_reference'=>false))
                ->add('Envoyer','submit')
                ->add('Annuler','reset');
     
     
        }
     
        /**
         * @param OptionsResolverInterface $resolver
         */
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'Blog\newsBundle\Entity\Article'
                //'cascade_validation' => true
            ));
        }
     
        /**
         * @return string
         */
        public function getName()
        {
            return 'blog_newsbundle_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
    <?php
     
    namespace Blog\newsBundle\Form;
     
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
     
    class CommentaireType extends AbstractType
    {
            /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('titre','text')
                ->add('auteur','text')
                ->add('datePubCom','date')
                ->add('contenue','textarea')
                //->add('article')
            ;
        }
     
        /**
         * @param OptionsResolverInterface $resolver
         */
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'Blog\newsBundle\Entity\Commentaire'
            ));
        }
     
        /**
         * @return string
         */
        public function getName()
        {
            return 'blog_newsbundle_commentaire';
        }
    }
    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
    <?php
    /**
     * Created by PhpStorm.
     * User: dev
     * Date: 08/03/14
     * Time: 10:43
     */
     
    namespace Blog\newsBundle\Controller;
     
     
    use Blog\newsBundle\Entity\Article;
    use Blog\newsBundle\Form\ArticleType;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
     
    class BlogController extends Controller{
     
     
        public function indexAction()
        {
            $article=new Article();
     
            $form=$this->createForm(new ArticleType(),$article);
     
            $request=$this->get('request');
     
            if($request->getMethod() == 'POST')
     
                $form->bind($request);
     
            if($form->isValid())
                {
                     $em=$this->getDoctrine()->getManager();
                     $em->persist($article);
                     $em->flush();
     
                   return $this->redirect($this->generateUrl('blognews_succes'));
     
                 }
     
            return $this->render('BlognewsBundle:Default:index.html.twig',array('form'=>$form->createView()));
        }
     
        public function succesAction()
        {
            $nom="PPP";
            return $this->render('BlognewsBundle:Blog:afficher.html.twig',array('nom'=>$nom));
        }
     
     
     
     
     
     
     
     
    }


  2. #2
    Membre régulier Avatar de DarckCrystale
    Femme Profil pro
    Développeuse Web
    Inscrit en
    Juin 2013
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 32
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeuse Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2013
    Messages : 71
    Points : 109
    Points
    109
    Par défaut
    Bonjour,

    Dans ta classe Article, tu as une relation OneToMany vers des commentaires ?

    Si tu regardes le html dans ton navigateur, est-ce qu'il y a des choses bizarres comme du javascript sous forme de gros pavés ?

  3. #3
    Membre expérimenté Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Points : 1 310
    Points
    1 310
    Par défaut
    En passant un new Article() à ton formulaire, tu lui donne un objet vide, avec une collection de commentaire vide elle aussi.
    Pas d'objet Commentaire => pas de formulaire associé.

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2014
    Messages : 9
    Points : 7
    Points
    7
    Par défaut
    @Nico_F Merci , mais ca c'est valable juste avec les collections ou bien je me trompe ?

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2014
    Messages : 9
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par DarckCrystale Voir le message
    Bonjour,

    Dans ta classe Article, tu as une relation OneToMany vers des commentaires ?

    Si tu regardes le html dans ton navigateur, est-ce qu'il y a des choses bizarres comme du javascript sous forme de gros pavés ?

    Oui j'ai une relation OneToMany et au niveau du HTML y a l'attribut data-prototype avec les choses bizarres , mais je crois que le problème vient de ma part , vu que je suis débutent , j'aimerai savoir si un formulaire de type collection on peut l'afficher comme tout autre type de champs ou bien je suis obligé de passer par du Javascipt .

  6. #6
    Membre régulier Avatar de DarckCrystale
    Femme Profil pro
    Développeuse Web
    Inscrit en
    Juin 2013
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 32
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeuse Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2013
    Messages : 71
    Points : 109
    Points
    109
    Par défaut
    Nope, tout est normal !

    Comme tu as un Article, mais plusieurs commentaires, Symfony se demande comment générer un formulaire pour tout enregistrer. Il fabrique alors un bout d'AJAX (le fameux Javascript en bloc) et le met dans le formulaire. Il faut alors en quelque sorte l'activer, c'est à dire le rende visible. Winzou l'explique plutôt bien : je ne connais rien au javascript, mais je m'en suis sortie avec ce qu'il donne.

    Dis-nous si ça te semble le bon moyen, voire si tu t'en sors pour afficher ton formulaire :3

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2014
    Messages : 9
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par DarckCrystale Voir le message
    Nope, tout est normal !

    Comme tu as un Article, mais plusieurs commentaires, Symfony se demande comment générer un formulaire pour tout enregistrer. Il fabrique alors un bout d'AJAX (le fameux Javascript en bloc) et le met dans le formulaire. Il faut alors en quelque sorte l'activer, c'est à dire le rende visible. Winzou l'explique plutôt bien : je ne connais rien au javascript, mais je m'en suis sortie avec ce qu'il donne.

    Dis-nous si ça te semble le bon moyen, voire si tu t'en sors pour afficher ton formulaire :3
    De même je ne connais rien en Jquery , c'est pour ca que j'ai trouvé une grande difficulté afin de comprendre le code de Winzou , mais j'ai pu trouver un code plutôt simple et facile à comprendre même s'il ne fournit pas un résultat complet .
    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
     
    <script src="http://code.jquery.com/jquery-1.11.0.min.js" type="text/javascript"></script>
    <script>
        $(function(){
     
            var index=0;
            var prototype=$('ul.form-coms').data('prototype');
     
            $('#form-coms-bttn').on('click',function(){
     
                var newForm=prototype.replace(/__name__/g,index++);
                var newLi=$('<li></li>');
                newLi.append(newForm);
                $(this).before(newLi);
     
            });
         });
    </script>

  8. #8
    Membre expérimenté Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Points : 1 310
    Points
    1 310
    Par défaut
    Citation Envoyé par ayoub246 Voir le message
    @Nico_F Merci , mais ca c'est valable juste avec les collections ou bien je me trompe ?
    De manière générale quand tu crées un formType avec Symfony, tu lui fournis un objet (entité doctrine ou non) dont il va récupérer les données existantes et dans lequel il va enregistrer les nouvelles saisies.

    Si tu crées un formulaire de type article et que tu veux un nouvel article : tu donnes à ton articleFormType un new Article().
    Si tu veux éditer un article existant, tu le récupères et tu le passes au articleFormType à la place du new Article().
    Si tu as une collection de 5 commentaires dans ton article et que ton formType comprend un collection de commentaireFormType, tu vas avoir le formulaire avec les valeurs de ton article et 5 formulaires de commentaires.
    Mais si tu passes un new Article() dont la collection de commentaire est vide, tu n'auras pas du tout l'affichage du commentaireFormType : c'est aussi simple que ça.

    Fais le test en rajoutant à la main un new Commentaire() dans la collection de commentaires de ton new Article() avant de le passer au formulaire.

  9. #9
    Membre régulier Avatar de DarckCrystale
    Femme Profil pro
    Développeuse Web
    Inscrit en
    Juin 2013
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 32
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeuse Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2013
    Messages : 71
    Points : 109
    Points
    109
    Par défaut
    Citation Envoyé par ayoub246 Voir le message
    De même je ne connais rien en Jquery , c'est pour ca que j'ai trouvé une grande difficulté afin de comprendre le code de Winzou
    JQuery est 'juste' une bibliothèque JavaScript, c'est à dire qu'il s'agit d'un monceau de fonctions en JavaScript qui facilite la vie des développeurs et qu'on peut intégrer à son projet.

    Quant au code de Winzou :
    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
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
     
    {# Ici, il signale l'emplacement de son fichier Twig #}
    {# src/Sdz/BlogBundle/Resources/views/Blog/formulaire.html.twig #}
     
    {# Ici, il affiche son formulaire #}
    {# Le formulaire reste inchangé #}
    <div class="well">
      <form method="post" {{ form_enctype(form) }}>
        {{ form_widget(form) }}
        <input type="submit" class="btn btn-primary" />
      </form>
    </div>
    {# Ici, le formulaire est fermé #}
     
    {# Ici, il charge la bibliothèque JQuery depuis le site officiel de JQuery #}
    {# On charge la bibliothèque jQuery. Ici, je la prends depuis le site jquery.com,
       mais si vous l'avez en local, changez simplement l'adresse. #}
    <script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
     
    {# Et ici commence le script #}
    {# Il faut savoir qu'en JavaScript, on peut aller chercher les variables par sélecteur, c'est à dire que dans le code html, tu as des balises, et que ces balises, on peut faire des choses en JavaScript avec en utilisant leur nom en html. #}
    {# Voici le script en question : #}
    <script type="text/javascript">
    $(document).ready(function() {
      // On récupère la balise <div> en question qui contient l'attribut « data-prototype » qui nous intéresse.
      // C'est là que ça t'intéresse : Winzou a une balise html qui contient le 'data-prototype' que tu as vu. 
      // Chez lui, elle s'appelle "sdz_blogbundle_articletype_categories", mais chez toi elle a un autre nom : 
      // à toi de changer cette variable pour donner le nom de la div à la place de "sdz_blogbundle_articletype_categories" :)
      var $container = $('div#sdz_blogbundle_articletype_categories');
     
      // On ajoute un lien pour ajouter une nouvelle catégorie
      // Ici, tu peux aussi modifier le code : vu que tu ne souhaites pas ajouter une catégorie, 
      // mais un commentaire, remplace categorie par commentaire :)
      var $lienAjout = $('<a href="#" id="ajout_categorie" class="btn">Ajouter une catégorie</a>');
      $container.append($lienAjout);
     
      // On ajoute un nouveau champ à chaque clic sur le lien d'ajout.
      $lienAjout.click(function(e) {
        // Pareil ici, on remplace dans le nom de la fonction Categorie par Commentaire
        ajouterCategorie($container);
        e.preventDefault(); // évite qu'un # apparaisse dans l'URL
        return false;
      });
     
      // On définit un compteur unique pour nommer les champs qu'on va ajouter dynamiquement
      // Là, c'est un petit truc qui va permettre de compter les commentaires à rajouter et de leur 
      // donner à chacun un identifiant unique, pas besoin d'y toucher.
      var index = $container.find(':input').length;
     
      // On ajoute un premier champ directement s'il n'en existe pas déjà un (cas d'un nouvel article par exemple).
      if (index == 0) {
        // ATTENTION ! Si la fonction ajouterCategorie a été renommée ajouterCommentaire, bien penser à la renommer ici aussi !
        ajouterCategorie($container);
      } else {
        // Pour chaque catégorie déjà existante, on ajoute un lien de suppression
        // On récupère depuis la variable container toutes les div enfant qu'elle contient (children('div')) 
        // et pour chacune d'entre elle (.each()), on ajoute un lien qui permet de la supprimer.
        $container.children('div').each(function() {
          ajouterLienSuppression($(this));
        });
      }
     
      // La fonction qui ajoute un formulaire Categorie
      // ATTENTION ! Toujours l'histoire de renommage Categorie/Commentaire ;)
      // Voici la fameuse fonction qu'on va utilise pour fabriquer de nouveaux commentaires dans ton formulaire :)
      function ajouterCategorie($container) {
        // Dans le contenu de l'attribut « data-prototype », on remplace :
        // - le texte "__name__label__" qu'il contient par le label du champ
        // - le texte "__name__" qu'il contient par le numéro du champ
        // Ici, on met dans la variable prototype une copie du champ data-prototype de la variable container qui est modifié : 
            // On prend le code dans data-prototype
                // On remplace dedans la chaîne __name__label__ par le label qu'il faut vraiment mettre, 
                // ici Catégorie n°{le numéro généré automatiquement de tout à l'heure} 
                // (donc bien penser à remplacer Catégorie par Commentaire pour toi) 
                // On remplace dedans la chaîne __name__ par le nom qu'il faut vraiment mettre, 
                // ici {le numéro généré automatiquement de tout à l'heure}
            // Toute le texte généré est mis dans la variable prototype.
        var $prototype = $($container.attr('data-prototype').replace(/__name__label__/g, 'Catégorie n°' + (index+1))
                                                            .replace(/__name__/g, index));
     
        // On ajoute au prototype un lien pour pouvoir supprimer la catégorie
        ajouterLienSuppression($prototype);
     
        // On ajoute le prototype modifié à la fin de la balise <div>
        $container.append($prototype);
     
        // Enfin, on incrémente le compteur pour que le prochain ajout se fasse avec un autre numéro
        index++;
      }
     
      // La fonction qui ajoute un lien de suppression d'une catégorie
      // La super fonction pour ajouter un lien qui supprime le commentaire 
      // (en fait, ça ne supprime pas un commentaire, mais juste une div qui contenait 
      // le formulaire de création d'un nouveau commentaire)
      function ajouterLienSuppression($prototype) {
        // Création du lien
        // On fabrique une variable qui va contenir un lien de suppression
        $lienSuppression = $('<a href="#" class="btn btn-danger">Supprimer</a>');
     
        // Ajout du lien
        // On ajoute ce lien à la variable prototype
        $prototype.append($lienSuppression);
     
        // Ajout du listener sur le clic du lien
        // On met en place un listener
        // (écouteur : un truc qui va faire des actions en fonction d'un événement) 
        // qui va écouter les événements de clic sur le lien de suppression
        $lienSuppression.click(function(e) {
          // Lorsque quelqu'un clique sur le lien, on supprime le prototype, donc la div, qui disparaît alors de la page
          $prototype.remove();
          e.preventDefault(); // évite qu'un # apparaisse dans l'URL
          return false;
        });
      }
    });
    </script>
    Voilou, je l'ai un peu plus commenté, hésite pas à poser des questions :3

    EDIT : pour compléter ce que dit Nico_F : ce qu'on fait là en JavaScript va générer un formulaire qui ressemblera sensiblement à ça :

    Nouvel Article
    nom :
    contenu :
    Nouveau Commentaire
    Ajouter un commentaire
    Commentaire n°1 :
    titre :
    contenu :
    Supprimer
    Envoyer

    Lorsqu'on clique sur Ajouter un commentaire, on obtiendra :
    Nouvel Article
    nom :
    contenu :
    Nouveau Commentaire
    Ajouter un commentaire
    Commentaire n°1 :
    titre :
    contenu :
    Supprimer
    Commentaire n°2 :
    titre :
    contenu :
    Supprimer
    Envoyer

    Donc peut-être que ce que te dit Nico_F sera plus adapté à ton projet, finalement, que ce que je t'ai dit, mais je pense que c'est aussi un aspect de Symfony à connaître, donc essayer les deux et faire ensuite un choix me semble judicieux

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Maroc

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2014
    Messages : 9
    Points : 7
    Points
    7
    Par défaut
    C'est exactement ce que je voulais comprendre et après avoir fait le test ça fonctionne comme je le souhaitais !
    Merci pour votre aide .

    Merci , à l'aide des commentaires que vous avez ajouté c'est devenue plus claire et simple , maintenant j'ai plus de choix et je vais pouvoir avancer .
    Merci beaucoup et je vous souhaite bonne chance

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 30/09/2008, 17h21
  2. Réponses: 5
    Dernier message: 14/06/2008, 08h32
  3. Problème d'affichage dans mon formulaire
    Par samus535 dans le forum IHM
    Réponses: 5
    Dernier message: 28/01/2008, 19h05
  4. Problème d'affichage dans un formulaire Access
    Par JohnDoeVS dans le forum VBA Access
    Réponses: 1
    Dernier message: 30/03/2007, 06h57
  5. Réponses: 6
    Dernier message: 19/05/2005, 11h06

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