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 :

SF2 - Comment personnaliser l'affichage d'un formulaire lorsque le champ est de type entity ? [2.x]


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 SF2 - Comment personnaliser l'affichage d'un formulaire lorsque le champ est de type entity ?
    Salut,
    j'ai créé un formulaire basé sur un champ 'entity'. Ce formulaire est constitué de checkboxes qui permmettent de choisir une entité (ici, il sagit de voiture). Ca marche mais j'ai besoin d'afficher plusieurs informations relatives à l'entité 'car'. Actuellement, le form n'affiche que l'id des entités 'Car' conformément à ce que j'ai implémenté mais j'aurais besoin d'afficher d'autres infos comme la couleur, la puissance etc.... Le but est de fabriquer un formulaire avec des checkboxes qui permettent à l'utilisateur de sélectionner plusieurs voitures.
    Est ce que quelqu'un sait comment je peux faire ?
    merci,
    d'avance,
    Ben


    Le controleur :
    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
    public function chooserAction() {
            //symfony.com/doc/current/reference/forms/types/entity.html
            $cars = $this->getDoctrine()
                    ->getRepository('CarBundle:Car')
                    ->find(1);
            $formBuilder = $this->createFormBuilder();
            /*
              foreach ($cars as $car) {
              $formBuilder->add($car->getId() ,'checkbox')->getForm();
              }
             */
            $formBuilder->add('cars', 'entity', array(
                'class' => 'CarBundle:Car',
                'property' => 'id',
                'expanded' => 'true',
                'multiple' => 'true',
            ));
     
            $formBuilder->add('save', 'submit');
            $form = $formBuilder->getForm();
            $request = $this->get('request');
            $form->handleRequest($request);
            if ($form->isValid()) {
                echo "ok";
     
    //            return $this->redirect($this->generateUrl('car_show', array('id' => $car->getId())));
            }
     
            return $this->render('CarBundle:Car:chooser.html.twig', array('form' => $form->createView()));
        }

    L'entité :
    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
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
      <?php
     
    namespace Foobar\CarBundle\Entity;
     
    use Doctrine\ORM\Mapping as ORM;
     
    /**
     * Car
     *
     * @ORM\Table()
     * @ORM\Entity(repositoryClass="Foobar\CarBundle\Entity\CarRepository")
     */
    class Car
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
     
        /**
         * @var string
         *
         * @ORM\Column(name="name", type="string", length=255)
         */
        private $name;
     
        /**
         * @var string
         *
         * @ORM\Column(name="brand", type="string", length=255)
         */
        private $brand;
     
        /**
         * @var string
         *
         * @ORM\Column(name="color", type="string", length=255)
         */
        private $color;
     
        /**
         * @var integer
         *
         * @ORM\Column(name="power", type="integer")
         */
        private $power;
     
     
        /**
         * Get id
         *
         * @return integer 
         */
        public function getId()
        {
            return $this->id;
        }
     
        /**
         * Set name
         *
         * @param string $name
         * @return Car
         */
        public function setName($name)
        {
            $this->name = $name;
     
            return $this;
        }
     
        /**
         * Get name
         *
         * @return string 
         */
        public function getName()
        {
            return $this->name;
        }
     
        /**
         * Set brand
         *
         * @param string $brand
         * @return Car
         */
        public function setBrand($brand)
        {
            $this->brand = $brand;
     
            return $this;
        }
     
        /**
         * Get brand
         *
         * @return string 
         */
        public function getBrand()
        {
            return $this->brand;
        }
     
        /**
         * Set color
         *
         * @param string $color
         * @return Car
         */
        public function setColor($color)
        {
            $this->color = $color;
     
            return $this;
        }
     
        /**
         * Get color
         *
         * @return string 
         */
        public function getColor()
        {
            return $this->color;
        }
     
        /**
         * Set power
         *
         * @param integer $power
         * @return Car
         */
        public function setPower($power)
        {
            $this->power = $power;
     
            return $this;
        }
     
        /**
         * Get power
         *
         * @return integer 
         */
        public function getPower()
        {
            return $this->power;
        }
    }
    La vue :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    car chooser
    {{ form(form) }}

  2. #2
    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
    Salut, tu peux implémenter une méthode __toString() dans ton entité 'Car' qui te retourne la concaténation des infos dont tu as besoin.
    C'est cette méthode qui est utilisée pour afficher une valeur correspondant aux entités : si elle n'existe pas, c'est l'ID qui est affiché par défaut.

    ++

  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,
    merci pour ta ta réponse,
    le __toString ca ne me convient pas car je serai amené à afficher des images ou des choses plus complexes.
    Du coup, ce que j'ai envisagé, c'est faire un appel à une méthode du controleur via render(controller(...)) qui me rend la fiche détaillée d'une entité car (template dédié)
    ...

  4. #4
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2009
    Messages : 875
    Points : 1 313
    Points
    1 313
    Par défaut
    Il faut créer un nouveau widget [doc], le faire étendre entity (ca j'ai jamais fait, si ca coince tu peux toujours wrapper tes entités en tableaux et les passer au choices)
    ensuite tu dois faire ton affichage personnalisé (qui reprend le fichier twig form_div_layout.html.twig)

    C'est un peu dur la première fois, mais c'est plus rapide après. (contrairement aux ébats...)

  5. #5
    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
    Citation Envoyé par gototog Voir le message

    C'est un peu dur la première fois, mais c'est plus rapide après. (contrairement aux ébats...)
    looooooooooooool

  6. #6
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Points : 1 050
    Points
    1 050
    Par défaut
    Bonjour,

    le rendu des formulaires est défini par défaut dans ce fichier twig
    https://github.com/symfony/symfony/b...yout.html.twig
    Tu peux t'en inspirer pour rendre ton formulaire

    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
     
    {{form_start(form)}}
     
    {{form_label(form.cars)}}
     
    <ul id="{{form.cars.vars.id}}" >
     {%for carForm in form.cars%}
      <li>
       {{form_widget(carForm)}} {#la checkbox#}
       <label for="{{carForm.vars.id}}">
       {# la variable "carForm.vars.data" correspond à ton entité "Car" #}
       {{carForm.vars.data.name}} 
       <img src="{{carForm.vars.data.imgUrl}}" />
      </label>
      </li>
     {%endfor%}
    </ul>
    {%do form.cars.setRendered(true)%} {#pour que ce champ n'apparaisse pas dans le form_rest#}
     
    {{form_errors(form.cars)}}
     
    {{form_end(form)}}
    Pour aller + loin tu peux regarder du coté des themes de formulaire
    http://symfony.com/fr/doc/current/co...aire-avec-twig


    [EDIT] Correctif le code ci-dessus ne peux pas fonctionner, utiliser ceci:

    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
    {{form_start(form)}}
    
    {{form_label(form.cars)}}
    
    <ul id="{{form.cars.vars.id}}" >
     {%for carForm in form.cars%}
      <li>
       {{form_widget(carForm)}} {#la checkbox#}
       {%set entity= form.cars.vars.choices[carForm.vars.value].data %}
        {# la variable "entity" correspond à ton entité "Car" #}
       <label for="{{entity.id}}">  
       {{entity.name}} 
       <img src="{{entity.imgUrl}}" />
      </label>
      </li>
     {%endfor%}
    </ul>
    {%do form.cars.setRendered(true)%} {#pour que ce champ n'apparaisse pas dans le form_rest#}
    
    {{form_errors(form.cars)}}
    
    {{form_end(form)}}

  7. #7
    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
    Ok je comprends effectivement si tu as besoin de rendre plus que du texte, le toString() ou l'option property ne te servira à rien.
    Je n'aime pas la technique qui consiste à faire un render : si tu as 20 choix à afficher tu vas faire un render pour chaque voiture : c'est autant de requêtes HTTP qui vont te gaspiller un temps fou pour au final faire quelque chose qui peut se gérer au niveau de twig.

    gototog et arnooo999 t'ont mis sur la bonne voie avec deux solutions différentes :

    - La méthode d'arnooo999 : elle a l'avantage d'être relativement simple : tu fais le découpage du formulaire widget par widget et tu rajoutes ton cadre (que tu auras pris le soin d'exporter dans un template ou une macro par exemple) là ou tu souhaites qu'il apparaisse. C'est simple, rapide et efficace. Comme il l'a si bien dit dit si tu veux aller plus loin après il y a le theming de form, ce que gototog propose.
    - La méthode de gototog : elle a l'avantage d'être souple et réutilisable : en themant ton formulaire avec un widget custom, tu n'as plus besoin de détailler le formulaire dans le template. Et si tu dois utiliser ce formulaire ou cette partie de formulaire ailleurs tu n'auras qu'a utiliser ton thème de formulaire. Dans ce cas je pense qu'il faudra te baser sur le widget form_row et l'ajuster ou en faire un nouveau.

    Je préfère la deuxième solution pour le coté réutilisable (dans le cas bien sur ou tu as besoin de réutiliser cette partie de formulaire).

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2011
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2011
    Messages : 29
    Points : 31
    Points
    31
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $formBuilder->add('cars', 'entity', array(
                'class' => 'CarBundle:Car',
                'property' => 'id',
                'expanded' => 'true',
                'multiple' => 'true',
            ));
    En notant 'property' => 'id' tu demandes l'affichage de la propriété "id"

    Si tu souhaites juste changer le "texte" pas le "rendu html" des checkbox, jouer avec property doit être suffisant

    Il est possible de créer un getter dans ton entité pour rendre le texte voulu :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        public function getCheckboxText()
        {
            return $this->name . ' - '
                    . $this->brand . ' - '
                    . $this->color;
        }
    Et l'utiliser dans le formbuilder

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $formBuilder->add('cars', 'entity', array(
                'class' => 'CarBundle:Car',
                'property' => 'checkboxText',
                'expanded' => 'true',
                'multiple' => 'true',
            ));

    Après pour un rendu html plus complexe, soit tu crées un custom type ou tout simplement une macro (ou simple include). Les deux sont réutilisables

  9. #9
    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 arnooo999,
    merci pour ta réponse. Ça fonctionne.
    j'ignorai tout des variables de formulaire, après lecture de la doc ça va un peu mieux.

    Une dernière question, pourquoi quand est ce que j'essaye de visualiser le contenu de la variable formulaire via {{ dump(form.cars.vars) }} ca ne me dump pas le contenu ?
    merci.
    a+
    ben

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 06/04/2014, 15h38
  2. Réponses: 6
    Dernier message: 13/08/2010, 15h25
  3. Erreurs, warnings, comment personnaliser l'affichage?
    Par Sunsawe dans le forum Visual C++
    Réponses: 2
    Dernier message: 01/12/2008, 13h19
  4. Réponses: 4
    Dernier message: 29/10/2008, 21h44
  5. Comment empécher l'affichage de 2 formulaire identique
    Par AndreDvl dans le forum Windows Forms
    Réponses: 2
    Dernier message: 27/12/2007, 22h46

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