How to build nested forms in Symfony

905 views Asked by At

I'm using EasyAdmin to create a controller for an entity (Processes), which is related to another entity (Sections) (a one-to-many relationship) that has a relationship to another entity (Sub-Sections) (also one-to-many).

In the "new" form of Processes I have a field that is of type EasyAdmin Collection to add sections, but since those sections have subsections, I need to add another equal field within Sections for the subsections... that has the same behavior as the subsections. fields of type EasyAdmin Collection (which when clicking on "Add item", shows a mini form for that other entity).

The main form is for creating a Process, the "sections" field is for adding sections to that Process, and within sections, is where I need another button like the one in EasyAdmin to create more sub-sections for that section.

This is the main form of Processes:


enter image description here

And this is what the Collection type field looks like with the fields to create Sections:


enter image description here


This is the process controller: (I created a custom field for sections called "SeccionType")

    namespace App\Controller\Admin;

    use App\Entity\Proceso;
    use App\Form\Type\SeccionType;
    use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
    use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
    use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
    use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
    use EasyCorp\Bundle\EasyAdminBundle\Field\CollectionField;

    class ProcesoCrudController extends AbstractCrudController
    {
       public static function getEntityFqcn(): string
       {
           return Proceso::class;
       }

       public function configureFields(string $pageName): iterable
       {
           yield TextField::new('nombre');
           yield TextEditorField::new('descripcion');
           yield CollectionField::new('secciones')        // <--- This is Sections field with the custom Symfony formType
                ->setEntryType(SeccionType::class)
                ->setFormTypeOptions(['block_prefix' => 'secciones_form',])
                ->addCssClass('actividadesFld');
           yield BooleanField::new('estado')->renderAsSwitch(false);
       }
    }

And this is the class of the custom field SeccionType

namespace App\Form\Type;

use App\Entity\Seccion;
use App\Entity\Proceso;
use App\Entity\Subseccion;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\FormTypeInterface;
use EasyCorp\Bundle\EasyAdminBundle\Field\CollectionField;
use Symfony\Component\Validator\Constraints\NotNull;

class SeccionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('name')
            ->add('description')
            ->add('order')
            ->add('tag')
            // ->add('proccess')
            ->add('subSection', CollectionType::class, ['entry_type' => ..?]);
        ;
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => Seccion::class,
        ]);
    }
}

Any help or suggestion, I will be infinitely grateful

1

There are 1 answers

2
Ryierth On BEST ANSWER

it seems you did not add the allow-add => true option to your CollectionType in SeccionType.php, as well as prototype => true. You should also probably create a SubSeccionType to give in the entry-type option. That should be a good start to move along.