Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EasyAdmin 3 : Nested forms

I'm trying to embed forms into forms. In my case : I want to embed Period and Price form into Offer form into Poi form. The architecture :

  • Poi form
    • Offer form
      • Price form
      • Period form

Relations:

  • Poi entity has relation OneToMany with Offer entity
  • Offer entity has relation OneToMany with Price entity and ManyToMany with Period entity.

I've been looking for solution for couple of days and I really need help, so if someone could help me it will be great.

1. First test : usage of CollectionField In my PoiCrudController :

public function configureFields(string $pageName): iterable {
    $offers = CollectionField::new('offers')
            ->setFormTypeOptions([
                'delete_empty' => true,
                'by_reference' => false,
            ])
            ->setEntryIsComplex(false)
            ->setCustomOptions([
                'allowAdd' => true,
                'allowDelete' => true,
                'entryType' => 'App\Form\OfferType',
                'showEntryLabel' => false,
            ]),

In OfferType :

class OfferType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {
    
        $builder
            ->add('description', CollectionType::class, array(
                'allow_add' => true,
                'allow_delete' => true,
                'delete_empty' => true,
                'by_reference' => false,
                'entry_type' => TextEditorType::class,
                'entry_options' => [
                  'label' => false,
                ],
                'label' => 'Description',
              ))

            ->add('createdAt')
            ->add('updatedAt')
            ->add('periods')
            ->add('poi')
        ;
    }
}

ERROR MESSAGE => The "App\Entity\Poi" entity has a repositoryClass set to "App\Entity\PoiRepository", but this is not a valid class. Check your class naming. If this is meant to be a service id, make sure this service exists and is tagged with "doctrine.repository_service".

If I replace 'entryType' => 'App\Form\OfferType', with 'entryType' => 'App\Form\PoiType' in PoiCrudController, and add this code in PoiType :

class PoiType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {
    
        $builder
            ->add('offers', CollectionType::class, array(
                'allow_add' => true,
                'allow_delete' => true,
                'delete_empty' => true,
                'by_reference' => false,
                'entry_type' => TextType::class, // cette ligne pose problème
                'entry_options' => [
                  'label' => false,
                ],
                'label' => 'Offres',
              ))

Then the Poi form is nested into Poi form where the field 'offer' appears. If I replace 'entry_type' => TextType::class with 'entry_type' => TextEditorType::class, a new error appears :

ERROR MESSAGE : Impossible to access an attribute ("customOptions") on a null variable. in vendor\easycorp\easyadmin-bundle\src\Resources\views\crud\form_theme.html.twig (line 424) {% set numOfRows = form.vars.ea_crud_form.ea_field.customOptions.get('numOfRows') %}

2. Second test : usage of CollectionField

In PoiCrudController :

    CollectionField::new('offers', 'Offres')
                ->allowAdd() 
                ->allowDelete()
                ->setEntryIsComplex(true)
                ->setEntryType(OfferCrudController::class)
            ->setFormTypeOptions([
                'by_reference' => 'false' 
            ]),

ERROR MESSAGE => Could not load type "App\Controller\Admin\OfferCrudController": class does not implement "Symfony\Component\Form\FormTypeInterface. My forms implement AbstractType so...

3. Third test : usage of AssociationField

In PoiCrudController :

    AssociationField::new('offers')
                ->setFormTypeOptions([
                    'by_reference' => false,
                    'multiple' => true,
                    'allow_add' => true
                ]),

ERROR MESSAGE => An error has occurred resolving the options of the form "Symfony\Bridge\Doctrine\Form\Type\EntityType": The option "allow_add" does not exist =>Issue #3528 [https://github.com/EasyCorp/EasyAdminBundle/issues/3528][2]

like image 227
LazyLez Avatar asked Jul 17 '20 11:07

LazyLez


1 Answers

I've been struggling with this issue for a long time myself, and I've finally found a solution.

I've chosen the Fist test pathway, but using Second test properties:

The CollectionField creating remains the same, just set OfferType form type istead of the OfferCrudController as the EntryType.

    CollectionField::new('offers', 'Offres')
            ->allowAdd() 
            ->allowDelete()
            ->setEntryIsComplex(true)
            ->setEntryType(OfferType::class)
        ->setFormTypeOptions([
            'by_reference' => 'false' 
        ]),

Then edit the OfferType:

class OfferType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add(...) // whatever you want
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Offer::class,

        ]);
    }
}

Adding the configureOptions method solved this for me.

like image 176
TomKorec Avatar answered Oct 29 '22 07:10

TomKorec