Easyadminbundle: How can I create a dynamic form?

Created on 15 Aug 2016  路  2Comments  路  Source: EasyCorp/EasyAdminBundle

Hallo,

Does somebody know how can a man dynamic change any properties from .yml-file?
I want to create dynamic choices. I make PRE_NEW/PRE_EDIT event, but this don't work.

class EasyAdminSubscriber implements EventSubscriberInterface
{
    /**@var SiteServiceInterface */
    protected $siteService;

    public function __construct($currentSite, $siteService, $voucherService)
    {
        $this->currentSite = $currentSite;
        $this->siteService = $siteService;
        $this->voucherService = $voucherService;
    }

    public static function getSubscribedEvents()
    {
        return array(
            EasyAdminEvents::PRE_NEW => array('setSitenameChoices'),
            EasyAdminEvents::PRE_EDIT => array('setSitenameChoices'),
        );
    }

    public function setSitenameChoices(GenericEvent $event)
    {
        $entity = $event['entity'];
        if ($entity['class'] == 'App\MyBundle\Entity\VoucherBatch') {
            $entity['new']['fields']['choiceSitename']['type_options']['choices'] = $this->getSitenameChoices();

            $event['entity'] = $entity;
        }
    }

    private function getSitenameChoices()
    {
        $sitename = $this->siteService->getConfiguredSitenames();
        return array_combine($sitename, $sitename);
    }
}

Does somebody know another way for this purpose?
Thank you very much.

Most helpful comment

This is exactly what I'm trying to do now.

Sadly, it never works, because internally easyadmin always uses the configManager, which is private and immutable. All data you have access to are merely read-only copies. Your best bet might be to add/replace the field manually in the createEntityFormBuilder method.

In fact here's the solution I found:

public function createYourThingEntityFormBuilder($entity, $view)
{
    $builder = parent::createEntityFormBuilder($entity, $view);
    if ($builder->has('products')) {
        $builder->remove('products');
        $builder->add('products', ChoiceType::class, [
            'choices' => $entity->getProducts(),
            'choice_label' => 'rawName',
            'attr' => ['multiple' => true, 'data-widget' => 'select2'],
            'choice_attr' => function ($allChoices, $currentChoiceKey) {
                return ['selected' => 'selected'];
            },
        ]);
    }
    return $builder;
}

This will create a choiceType field with the fancy select2 dropbox, and populate it with whatever choices you specify via the choices option and the defaults specified in the choice_attr option.
Bear in mind that if you use EntityType, without flushed entities, it will throw, despite the error suggesting persisting them would suffice. (That's been my experience anyway. More testing might be needed.)

Of course, this will add your new field form at the end of the form, so it may mess up the arrangement of your form. A workaround for this is just to get the succeeding fields, remove them as well and add them in order. Silly, but it'll work.

All 2 comments

Maybe the best approach for this is to use the getEntityFormOptions or getVoucherBatchEntityFormOptions method in a custom controller.

This is exactly what I'm trying to do now.

Sadly, it never works, because internally easyadmin always uses the configManager, which is private and immutable. All data you have access to are merely read-only copies. Your best bet might be to add/replace the field manually in the createEntityFormBuilder method.

In fact here's the solution I found:

public function createYourThingEntityFormBuilder($entity, $view)
{
    $builder = parent::createEntityFormBuilder($entity, $view);
    if ($builder->has('products')) {
        $builder->remove('products');
        $builder->add('products', ChoiceType::class, [
            'choices' => $entity->getProducts(),
            'choice_label' => 'rawName',
            'attr' => ['multiple' => true, 'data-widget' => 'select2'],
            'choice_attr' => function ($allChoices, $currentChoiceKey) {
                return ['selected' => 'selected'];
            },
        ]);
    }
    return $builder;
}

This will create a choiceType field with the fancy select2 dropbox, and populate it with whatever choices you specify via the choices option and the defaults specified in the choice_attr option.
Bear in mind that if you use EntityType, without flushed entities, it will throw, despite the error suggesting persisting them would suffice. (That's been my experience anyway. More testing might be needed.)

Of course, this will add your new field form at the end of the form, so it may mess up the arrangement of your form. A workaround for this is just to get the succeeding fields, remove them as well and add them in order. Silly, but it'll work.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

haithem-rihane picture haithem-rihane  路  4Comments

Wait4Code picture Wait4Code  路  3Comments

lukasluecke picture lukasluecke  路  3Comments

liarco picture liarco  路  3Comments

devkbsc picture devkbsc  路  3Comments