I try to apply documentation (https://symfony.com/doc/current/form/dynamic_form_modification.html) but i have some troubles when I receive the result of the first select (categoryLevel1Id) to collect options in the second select (categoryLevel2Id).
I'm new with Doctrine, and I think something escapes me.
Is there anybody can help for begining a better new year 😱🤞😬
With the following code (1), I hav an exception : Expected argument of type "int", "object" given at property path "categoryLevel1Id".
$builder->add('categoryLevel1Id', EntityType::class, [ 'class' => CategoryLevel1::class, 'label' => 'contrib.create.category_level1', 'placeholder' => 'contrib.create.category_level1_placeholder', 'query_builder' => function (EntityRepository $er) { return $er->createQueryBuilder('c') ->andWhere("c.langId = ?1") ->andWhere("c.validated = ?2") ->setParameter(1, $this->langService->getLangIdByLang(locale_get_default())) ->setParameter(2, 1); }, 'choice_label' => 'title', 'choice_attr' => function($choice, $key, $value) { return ['class' => 'text-dark']; }, ]);
With the following code (2), I have this exception: Argument 2 passed to App\Form\Front\Situ\CreateSituFormType::App\Form\Front\Situ{closure}() must be an instance of App\Entity\CategoryLevel1 or null, int given, called in ..\src\Form\Front\Situ\CreateSituFormType.php on line 147
$categories = $this->categoryLevel1Repository->findLocaleCategories(); $categoriesOptions = []; foreach ($categories as $categorie) { $categoriesOptions[] = [ $categorie['title'] => $categorie['id'], ]; } $builder->add('categoryLevel1Id', ChoiceType::class, [ 'choices' => call_user_func_array('array_merge', $categoriesOptions), 'label' => 'contrib.create.category_level1', 'label_attr' => ['class' => ''], 'placeholder' => 'contrib.create.category_level1_placeholder', 'choice_attr' => function($choice, $key, $value) { return ['class' => 'text-dark']; }, ]);
I tried to call a CategoryLevel1Type::class instead but it didn't work when code came to $formModifier = function (FormInterface $form..
of course or I did'nt know adapt code!
This is my buildForm() with any __construct before:
public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('title', TextType::class, [ 'label' => 'contrib.create.title', 'attr' => [ 'class' => 'mb-md-4', 'placeholder' => 'contrib.create.title_placeholder' ], ]) ->add('description', TextareaType::class, [ 'label' => 'contrib.create.description', 'attr' => [ 'rows' => '5', 'placeholder' => 'contrib.create.description_placeholder', ], ]) ; // Check locale categories level 1 $categories = $this->categoryLevel1Repository->findLocaleCategories(); // If no category, create it and its subcategory if (empty($categories)) { $builder ->add('categoryLevel1Id', CreateCategoryLevel1Type::class, [ 'label' => 'category.create.category_level1', 'label_attr' => ['class' => 'pt-0'], ]) ->add('categoryLevel2Id', CreateCategoryLevel2Type::class, [ 'label' => 'category.create.category_level2', 'label_attr' => ['class' => 'pt-0'], ]) ; } else { $builder->add('categoryLevel1Id', EntityType::class, [ 'class' => CategoryLevel1::class, 'label' => 'contrib.create.category_level1', 'placeholder' => 'contrib.create.category_level1_placeholder', 'query_builder' => function (EntityRepository $er) { return $er->createQueryBuilder('c') ->andWhere("c.langId = ?1") ->andWhere("c.validated = ?2") ->setParameter(1, $this->langService->getLangIdByLang(locale_get_default())) ->setParameter(2, 1); }, 'choice_label' => 'title', 'choice_attr' => function($choice, $key, $value) { return ['class' => 'text-dark']; }, ]); $formModifier = function (FormInterface $form, CategoryLevel1 $categoryLevel1 = null) { $categoriesLevel2 = null === $categoryLevel1 ? [] : $categoryLevel1->getGategoriesLevel2(); $form->add('categoryLevel2Id', EntityType::class, [ 'class' => 'App\Entity\CategoryLevel2', 'label' => 'contrib.create.category_level2', 'placeholder' => 'contrib.create.category_level2_placeholder', 'choices' => $categoriesLevel2, ]); }; $builder->addEventListener( FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($formModifier) { // this would be your entity, i.e. SportMeetup $data = $event->getData(); $formModifier($event->getForm(), $data->getCategoryLevel1Id()); } ); $builder->get('categoryLevel1Id')->addEventListener( FormEvents::POST_SUBMIT, function (FormEvent $event) use ($formModifier) { // It's important here to fetch $event->getForm()->getData(), as // $event->getData() will get you the client data (that is, the ID) $categoryLevel1 = $event->getForm()->getData(); // since we've added the listener to the child, we'll have to pass on // the parent to the callback functions! $formModifier($event->getForm()->getParent(), $categoryLevel1); // (Error code 2 here) } ); } } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => Situ::class, 'translation_domain' => 'user_messages', ]); }
Then Entities with Relations:
CategoryLevel1:
.../... /* * @ORM\OneToMany(targetEntity="App\Entity\CategoryLevel2", cascade={"persist", "remove"}, mappedBy="categoryLevel1Id") */ protected $categoriesLevel2; /* * @ORM\OneToMany(targetEntity=Situ::class, cascade={"persist", "remove"}, mappedBy="categoryLevel1") */ protected $situs; public function __construct() { $this->categoriesLevel2 = new ArrayCollection(); $this->situs = new ArrayCollection(); } .../... public function getGategoriesLevel2() { return $this->categoriesLevel2; } public function addCategoryLevel2(CategoryLevel2 $categoryLevel2) { $this->categoriesLevel2->add($categoryLevel2); $categoryLevel2->setCategoryLevel1($this); } public function getSitus() { return $this->situs; } public function addSitu(Situ $situ) { $this->situs->add($situ); $situ->setCategoryLevel1($this); }
CategoryLevel2:
.../... /** * @ORM\Column(type="integer") * @ORM\ManyToOne(targetEntity="App\Entity\CategoryLevel1", inversedBy="categoriesLevel2") */ private $categoryLevel1Id; /** * @ORM\Column(type="boolean") */ private $validated; /** * @ORM\OneToMany(targetEntity=Situ::class, cascade={"persist", "remove"}, mappedBy="categoryLevel2") */ protected $situs; public function __construct() { $this->situs = new ArrayCollection(); } .../... public function getSitus() { return $this->situs; } public function addSitu(Situ $situ) { $this->situs->add($situ); $situ->setCategoyLevel2($this); } .../...
Situ :
.../... /** * @ORM\Column(type="integer") */ private $categoryLevel1Id; /** * @ORM\Column(type="integer") */ private $categoryLevel2Id; /** * @ORM\ManyToOne(targetEntity=CategoryLevel1::class, inversedBy="situs") */ protected $categoryLevel1; /** * @ORM\ManyToOne(targetEntity=CategoryLevel2::class, inversedBy="situs") */ protected $categoryLevel2; .../...
Into SituController, nothing but :
public function createSitu(Request $request, User $user): Response { $situ = new Situ(); $form = $this->createForm(CreateSituFormType::class, $situ); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { // TODO } return $this->render('front/situ/new.html.twig', [ 'situ' => $situ, 'form' => $form->createView(), ]); }
Pleaaaase ! 🙏
https://stackoverflow.com/questions/65535610/symfony-5-2-problems-with-argument-passed-in-dynamically-modifification-form-u January 02, 2021 at 10:44AM
没有评论:
发表评论