Issue
I have been using Symfony 3 for a while, and until now I only generated simple forms. Now, I would like to generate a more complex, dynamic form and a bit of help would be appreciated.
My website references Products, that are associated to categories. Therefore, I created a ProductCategory entity which relies on the Doctrine extension Tree. The actual products are therefore the leaves of the tree structure, the other nodes (i.e. those with at least one child) are only product categories.
An example of such structure would be this one:
Food
Fruits
Apple
Pear
Vegetables
Pepper
Zucchini
Vehicle
Car
Bike
In this example, the products are Apple, Pear, Pepper, Zucchini, Car and Bike.
I would like to generate a form aimed at selecting a product. The expected behavior would be this one:
- Initially, the user sees a single dropdown list with the root categories (here Food and Vehicle)
- When the user selects a category, a new dropdown appears below the previous one, populated with the subcategories corresponding to the previously selected category (e.g. Fruits and Vegetables if Food had been chosen)
- This process should be recusrive until the user selected a product, i.e. a leaf of the tree structure.
In order for the form to be valid, the user must have selected a Product (leaf).
For now, I have been able to generate the initial form with the dropdown listing the root categories. Here is the code used to do this.
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use AppBundle\Entity\ProductCategory;
use AppBundle\Repository\ProductCategoryRepository;
class ProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('productCategory',EntityType::class,array(
'class' => 'AppBundle:ProductCategory',
'query_builder' => function(ProductCategoryRepository $repository){
return $repository->getRootNodesQueryBuilder();
},
'label' => 'product category',
'choice_label' => 'name',
'choice_value' => 'name',
'multiple' => false,
'expanded' => false,
'required' => true
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Product::class,
'method' => 'POST',
));
}
}
From this, the idea would be to use AJAX and jQuery to:
- Send the (current) selected category to the server, using the "change" event on the dropdown
- Generate and display the new dropdown below the previous one, with the adequate
However, I do not know how to modify the ProductType class in order to generate the new EntityType field based on the current selected category, then to send back the updated form in order to allow its display by jQuery.
Therefore, any help or advice would be more than welcome in order to make progress in building this dynamic form !
Solution
If I understand your problem correctly then you need to get child categories for given categories. You can pass it as a option to ProductType
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use AppBundle\Entity\ProductCategory;
use AppBundle\Repository\ProductCategoryRepository;
class ProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$category = $options['category'];
$builder->add('productCategory',EntityType::class,array(
'class' => 'AppBundle:ProductCategory',
'query_builder' => function(ProductCategoryRepository $repository) use ($category){
return $repository->getRootNodesQueryBuilder($category);
},
'label' => 'product category',
'choice_label' => 'name',
'choice_value' => 'name',
'multiple' => false,
'expanded' => false,
'required' => true
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Product::class,
'method' => 'POST',
'category' => null
));
}
}
In getRootNodesQueryBuilder() you can parse child categories based upon passed category. In controller (where you receive AJAX request), you can use it like
$form = $this->createForm(ProductType::class, $product, [
'category' => $request->get('category')
]);
Answered By - hanish singla Answer Checked By - Senaida (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.