2017-01-24 3 views
1

Мне нужна помощь, чтобы понять, как использовать eventListener Symfony. Итак, у меня есть две кнопки «добавить новую книгу для продажи» и «добавить новую книгу для торговли» в моем указателе на рулевое управление в той же форме BookType. Моя проблема: если вы нажмете «добавить новую книгу для продажи» path => добавьте поле цены в форму. Я пробовал this для моего проекта, но он все еще не работает. Также я создаю персональную форму для BookType.Добавить поле в форме с eventListener Symfony

Вот мой код для формы 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')); 
 
     // 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'))); 
 
      } 
 
     }) 
 
     ; 
 
    }

Кроме того, если это не работает, я хотел бы знать, как установить значение по умолчанию в функции контроллера для набора книги = > продайте, если щелкните по ссылке «добавить новую книгу для продажи» и введите book => trade, если щелкните по пути «добавить новую книгу для торговли».

+0

, чтобы иметь дело с форменными событий одна причина, почему я перестал использовать компонент формы. Я уверен, что $ request не будет доступен. – Cerad

+0

Да, $ request недоступен, теперь я это знаю. Спасибо. – Tirkal

ответ

0

вы можете поместить атрибут в массиве опций и прочитать его в 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', 
     )); 
    } 
} 

и в контроллере вы можете позвонить по разным трассам действия

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

или

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

Вы добавили строку из кода выше публичной функции configureOptions (OptionsResolver $ распознаватель) { $ resolver-> SetDefaults (массив ( 'Booktype' => 'продать', )); } –

+0

Спасибо, за ваш ответ;). Это работа для «добавления новой книги для продажи», но когда я нажимаю «добавить новую книгу для торговли», у меня есть эта проблема: ни свойство «prixOuvrage», ни один из методов «prixOuvrage()», «getprixOuvrage()»/"isprixOuvrage()" или "__call()" существуют и имеют открытый доступ. Если я прокомментирую div, содержащий from.prixOuvrage в моей форме, это работа, но я не хочу этого делать. – Tirkal

+0

Вы используете одно и то же сущность для обоих типов книг? объект книги должен также иметь переменную prixOuvrage –

0

С использованием сопоставленных суперклассов у вас должны быть такие объекты:

Суперкласс Книга

/** 
* @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; 
    } 
} 

TradeBook сущность, которая просто расширяет суперкласс:

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

} 

и SellBook объект с дополнительной переменной:

/** 
* @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; 
    } 


} 

В вашем FormType вы можете задать для данных данных:

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'))); 
     } 

    } 


} 

И в контроллере можно использовать два действия:

/** 
    * @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()) 
     ); 
    } 
+0

Существует два объекта при создании базы данных? Или у кого есть этот тип? – Tirkal

+0

Созданы 3 таблицы базы данных, таблица «книга», в которой хранятся данные, которые имеют оба типа книг, и столбец «тип», который содержит информацию о том, какой тип книги (определяется с помощью @ORM \ DiscriminatorColumn (name = "type" , type = "string")). таблицу «book_tradebook», которая должна иметь только идентификатор из «книги» и таблицу «book_sellbook», которая имеет дополнительную колонку для вашего «prixOuvrage» –

+0

Но вы можете f.ex. легко получить все объекты SellBook в контроллере с помощью $ this-> getDoctrine() -> getManager() -> getRepository (SellBook :: class) -> findAll(); –

Смежные вопросы