So I have a form on which I want to be able to modify multiple fields, to make it short I have followed the documentation regarding FormEvents to add an event listener on my category field.
And it does work, when I select a category the product categories(prodcat) of the category I've chosen shows up.
However I also have in my form a Type of product(top) field and I want to be able to choose a product category and have the type of products(top) related to the product category(prodcat), but when I add another PRE_SET_DATA AND POST_SUBMIT To my form it does not work. I can read off category but not prodcat.
Is there a way to listen to multiple fields ?
I did test them seperatly and they both work, but when they are together it only works for category.
Here is my form type :
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('category', EntityType::class,[
'class' => Category::class,
'choice_label' => 'cat_name'
])
->add('filter', EntityType::class,[
'class' => Filter::class,
'choice_label' => 'name'
])
->add('name', TextType::class,[
'required' => true,
'label' => 'Nom de produit',
'constraints'=>[
new Length([
'min' => 3,
'max'=> 55,
'minMessage' => "Le nom de catégorie doit avoir un minimum de {{ limit }} caractères.",
'maxMessage' => "Le nom de catégorie ne doit pas faire plus de {{ limit }} caractéres."
])
]
])
->add('image', FileType::class,[
'mapped'=> false,
'required' => false,
'constraints' => [
new File([
'mimeTypes' => [
'image/jpg',
'image/png',
'image/jpeg',
'image/bmp',
'image/webp',
'image/svg+xml',
'image/gif',
],
'mimeTypesMessage'=>"Ce fichier ({{ type }}) n'est pas au format valide.
Veuillez mettre un fichier de type : .jpeg, .png, .gif, .svg, .jpg, .webp, .bmp",
])
],
])
->add('state', ChoiceType::class,[
'label' => 'état',
'choices' => [
'Neuf' => 'Neuf',
'Occasion' => 'Occasion',
'Reconditionné' => 'Reconditionné'
]
])
->add('description')
->add('prodcat', EntityType::class,[
'class' => ProductCat::class,
'choice_label' => 'pc_name',
'label' => 'Catégorie de produit',
])
->add('top', EntityType::class,[
'class' => Top::class,
// 'choices' => $top,
'choice_label' => 'top_name',
'label' => 'Top',
]);
;
//this part is what helps me get the right prodcat depending on which category I choose
$formModifier = function (FormInterface $form, Category $category = null){
$prodcat = null === $category ? [] : $category->getProductCats();
$form->add('prodcat', EntityType::class,[
'class' => ProductCat::class,
'choices' => $prodcat,
'label' => 'Catégorie de produit',
]);
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifier){
$data = $event->getData();
$formModifier($event->getForm(), $data->getCategory());
}
)
;
$builder->get('category')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier){
$category = $event->getForm()->getData();
$formModifier($event->getForm()->getParent(), $category);
}
)
;
/*and sadly this part is what is supposed to help me get the right top depending on what prodcat
has been selected*/
$addTopForm = function(FormInterface $form, ProductCat $prodcat = null){
$top = null === $prodcat ? [] : $prodcat->getTops();
$form->add('top', EntityType::class,[
'class' => Top::class,
'choices' => $top,
'label' => 'Top',
]);
}
;
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($addTopForm){
$data = $event->getData();
$addTopForm($event->getForm(), $data->getProdCat());
}
)
;
$builder->get('prodcat')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($addTopForm){
$prodcat = $event->getForm()->getData();
$addTopForm($event->getForm()->getParent(), $prodcat);
}
)
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Products::class,
]);
}
}
If there is any additional information needed, feel free to ask. Thank you for reading.
I tried to modify multiple fields in order to have everything filtered through what the user has selected, alas only one field works correctly.