简体   繁体   中英

Add field in form with eventListener Symfony

I need some help to understand how to use the eventListener of Symfony. So, I have two button "add new book to sell" and "add new book to trade" in my index to steering on the same form of BookType. My issue is : if click on "add new book to sell" path => add the price field in form. I try this for my project but it's still not working. Also I build a personnal form for the BookType.

Here my code for the BookType form :

  public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('titreOuvrage',TextType::class,array('label'=>'Nom de l\\'ouvrage','attr'=>array('class'=>'form-control'))) ->add('resumeOuvrage',TextareaType::class,array('label'=>'Résumé de l\\'ouvrage','attr'=>array('class'=>'form-control'))) ->add('auteur', CollectionType::class, array('entry_type'=>AuteursType::class, 'allow_add'=>true, 'allow_delete'=>true)) ->add('editeur',EntityType::class,array('label'=>'Sélectionnez l\\'éditeur','attr'=>array('class'=>'form-control'),'class'=>'SB\\MainBundle\\Entity\\Editeurs','choice_label'=>'libelle_editeur')) ->add('etat',EntityType::class,array('label'=>'Cochez l\\'état dans lequel se trouve votre ouvrage','class'=>'SB\\MainBundle\\Entity\\EtatsOuvrages','choice_label'=>'libelle_etat','expanded'=>true)) ->add('categorie',EntityType::class,array('label'=>'Selectionnez une catégorie','attr'=>array('class'=>'form-control'),'class'=>'SB\\MainBundle\\Entity\\Categories','choice_label'=>'libelle_categorie')) ->add('genre',EntityType::class,array('label'=>'Cochez un ou plusieurs genre','class'=>'SB\\MainBundle\\Entity\\Genres','choice_label'=>'libelle_genre','multiple'=>true,'expanded'=>true)) // ->add('photosOuvragePath') ->add('photosOuvrageFile',FileType::class,array('label'=>'Ajouter des photos')) ->add('statutOuvrage',EntityType::class,array('label'=>'Que voulez-vous faire de l\\'ouvrage','attr'=>array('class'=>'form-control'),'class'=>'SB\\MainBundle\\Entity\\StatutsOuvrages','choice_label'=>'libelle_statut')); // doc : http://symfony.com/doc/2.8/form/dynamic_form_modification.html#form-events-underlying-data $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event, Request $request) { //$prix = $event->getData(); $form = $event->getForm(); $route = $request->attributes->get('sb_main_create_ouvrage_vente'); // on va afficher le champ du prix seulement si on est dans le formulaire de vente if ($route) { $form->add('prixOuvrage', TextType::class, array('label'=>'Entrez le prix de vente','attr'=>array('class'=>'form-control'))); } }) ; } 

Also, if it's doesn't work, I would like to know how to set a default value in a Controller function for set book => sell if click on "add new book to sell" path and book => trade if click on "add new book to trade" path.

you can put an attribute in the options array and read it in buildForm:

class BookType
{
    public function buildForm(FormBuilderInterface $builder, array $options)  {

        $builder->add('titreOuvrage',TextType::class,array('label'=>'Nom de l\'ouvrage','attr'=>array('class'=>'form-control')))
            ->add('resumeOuvrage',TextareaType::class,array('label'=>'Résumé de l\'ouvrage','attr'=>array('class'=>'form-control')))
            ->add('auteur', CollectionType::class, array('entry_type'=>AuteursType::class, 'allow_add'=>true, 'allow_delete'=>true))
            ->add('editeur',EntityType::class,array('label'=>'Sélectionnez l\'éditeur','attr'=>array('class'=>'form-control'),'class'=>'SB\MainBundle\Entity\Editeurs','choice_label'=>'libelle_editeur'))
            ->add('etat',EntityType::class,array('label'=>'Cochez l\'état dans lequel se trouve votre ouvrage','class'=>'SB\MainBundle\Entity\EtatsOuvrages','choice_label'=>'libelle_etat','expanded'=>true))
            ->add('categorie',EntityType::class,array('label'=>'Selectionnez une catégorie','attr'=>array('class'=>'form-control'),'class'=>'SB\MainBundle\Entity\Categories','choice_label'=>'libelle_categorie'))
            ->add('genre',EntityType::class,array('label'=>'Cochez un ou plusieurs genre','class'=>'SB\MainBundle\Entity\Genres','choice_label'=>'libelle_genre','multiple'=>true,'expanded'=>true))
//                ->add('photosOuvragePath')
            ->add('photosOuvrageFile',FileType::class,array('label'=>'Ajouter des photos'))
            ->add('statutOuvrage',EntityType::class,array('label'=>'Que voulez-vous faire de l\'ouvrage','attr'=>array('class'=>'form-control'),'class'=>'SB\MainBundle\Entity\StatutsOuvrages','choice_label'=>'libelle_statut'));

        if($options["booktype"] == "sell"){
            $builder->add('prixOuvrage',
                TextType::class,
                array('label'=>'Entrez le prix de vente','attr'=>array('class'=>'form-control')));
        }

    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'booktype' => 'sell',
        ));
    }
}

and in the controller you can call in different action routes

$this->createForm(BookType::class, $book, array("booktype" => "trade"));

or

$this->createForm(BookType::class, $book, array("booktype" => "sell"));

With using mapped superclasses you should have Entities like this:

The superclass Book

/**
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="type", type="string")
* @ORM\Table(name="book")
*/
abstract class Book
{
    /**
     * @ORM\Column(type="string", length=255)
     */
    protected $titreOuvrage;

    /**
     * @ORM\Column(type="string", length=255)
     */
    protected $resumeOuvrage;

//...other variables
    /**
     * @return mixed
     */
    public function getTitreOuvrage()
    {
        return $this->titreOuvrage;
    }

    /**
     * @param mixed $titreOuvrage
     */
    public function setTitreOuvrage($titreOuvrage)
    {
        $this->titreOuvrage = $titreOuvrage;
    }

    /**
     * @return mixed
     */
    public function getResumeOuvrage()
    {
        return $this->resumeOuvrage;
    }

    /**
     * @param mixed $resumeOuvrage
     */
    public function setResumeOuvrage($resumeOuvrage)
    {
        $this->resumeOuvrage = $resumeOuvrage;
    }
}

The TradeBook entity which just extends the superclass:

/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks()
 * @ORM\Table(name="book_tradebook")
 */
class TradeBook extends Book
{

}

and the SellBook entity with additional variable:

/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks()
 * @ORM\Table(name="book_sellbook")
 */
class SellBook extends Book
{
    /**
     * @ORM\Column(type="string", length=255)
     */
    protected $prixOuvrage;

    /**
     * @return mixed
     */
    public function getPrixOuvrage()
    {
        return $this->prixOuvrage;
    }

    /**
     * @param mixed $prixOuvrage
     */
    public function setPrixOuvrage($prixOuvrage)
    {
        $this->prixOuvrage = $prixOuvrage;
    }


}

In your FormType you can ask for the given data_class:

class BookType  extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)  {

        $builder->add('titreOuvrage',TextType::class,array('label'=>'Nom de l\'ouvrage','attr'=>array('class'=>'form-control')))
            ->add('resumeOuvrage',TextareaType::class,array('label'=>'Résumé de l\'ouvrage','attr'=>array('class'=>'form-control')));
            ->add('auteur', CollectionType::class, array('entry_type'=>AuteursType::class, 'allow_add'=>true, 'allow_delete'=>true))
            ->add('editeur',EntityType::class,array('label'=>'Sélectionnez l\'éditeur','attr'=>array('class'=>'form-control'),'class'=>'SB\MainBundle\Entity\Editeurs','choice_label'=>'libelle_editeur'))
            ->add('etat',EntityType::class,array('label'=>'Cochez l\'état dans lequel se trouve votre ouvrage','class'=>'SB\MainBundle\Entity\EtatsOuvrages','choice_label'=>'libelle_etat','expanded'=>true))
            ->add('categorie',EntityType::class,array('label'=>'Selectionnez une catégorie','attr'=>array('class'=>'form-control'),'class'=>'SB\MainBundle\Entity\Categories','choice_label'=>'libelle_categorie'))
            ->add('genre',EntityType::class,array('label'=>'Cochez un ou plusieurs genre','class'=>'SB\MainBundle\Entity\Genres','choice_label'=>'libelle_genre','multiple'=>true,'expanded'=>true))
//                ->add('photosOuvragePath')
            ->add('photosOuvrageFile',FileType::class,array('label'=>'Ajouter des photos'))
            ->add('statutOuvrage',EntityType::class,array('label'=>'Que voulez-vous faire de l\'ouvrage','attr'=>array('class'=>'form-control'),'class'=>'SB\MainBundle\Entity\StatutsOuvrages','choice_label'=>'libelle_statut'));

        if($options["data_class"] == SellBook::class){
            $builder->add('prixOuvrage',
                TextType::class,
                array('label'=>'Entrez le prix de vente','attr'=>array('class'=>'form-control')));
        }

    }


}

And in the controller you can use 2 actions:

   /**
     * @Route("/sell", name="book_sell")
     */
    public function newSellBookAction(){

        $book = new SellBook();
        $form = $this->createForm(BookType::class, $book);
        return $this->render(
            'AppBundle:book.create.html.twig',
            array("form" => $form->createView())
        );
    }

    /**
     * @Route("/trade", name="book_trade")
     */
    public function newTradeBookAction(){
        $book = new TradeBook();
        $form = $this->createForm(BookType::class, $book);
        return $this->render(
            'AppBundle:book.create.html.twig',
            array("form" => $form->createView())
        );
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM