PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, May 12, 2022

[FIXED] How to create dynamic cascade form in Symfony?

 May 12, 2022     dynamic, forms, symfony, symfony-forms     No comments   

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)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing