SymfonyCasts / dynamic-forms

Add dynamic/dependent fields to Symfony forms
https://symfonycasts.com
MIT License
98 stars 10 forks source link

How to work with Model Transformers? #17

Closed Gerben321 closed 9 months ago

Gerben321 commented 9 months ago

Thanks for this awesome package. It was a bit of messing around but I managed to get an existing form working with some dynamic fields.

However, I am facing a little problem. I've got an issue with model transformers. All of my dynamic fields have them. The reason is because my data in the database is stored differently from how it's shown to the user. So there's a transform action for getting and setting it from/to the database.

I can't figure out how to get these working. In my old situation I used to run this code:

$builder
  ->get('field')
  ->addModelTransformer(new CallbackTransformer(...etc

This is no longer working with the dynamic form fields. The error was somewhat expectable: 'The child with the name "field" does not exist.'. So, I wrapped the function in this:

if ($builder->has('field')) {

Sadly, this always returns false even though the field is rendered. How can I make this work again? I hope I don't have to work with the somewhat ugly Form Events.

Thanks in advance!

Gerben321 commented 9 months ago

Thanks I found a way.

parktrip commented 5 months ago

Dear @Gerben321, as I am currently facing the exact same issue, I would interested in how you solved this. Thank you in advance

j0r1s commented 1 month ago

You can create a custom form type and apply the transformer to it.

Let's assume this form type :

class YourFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('field', TextType::class)
            ->add('dependent', TextType::class)
        ;
        $builder->get('dependent')->addModelTransformer(YourTransformer::class);
    }
}

could be translated to :

class YourFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder = new DynamicFormBuilder($builder);

        $builder
            ->add('field', TextType::class)
            ->addDependent('dependent', 'field', function (DependentField $dependent, $field) {
                $dependent->add(CustomType::class);
            }
        ;
    }
}
// CustomType.php
class CustomType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->addModelTransformer(YourTransformer::class);
    }

    public function getParent()
    {
        return TextType::class;
    }
}