1

I have a Symfony Form Type and I want to inject on it another form I have Created:

$form = $this->createFormBuilder();
$form->add('quantity', NumberType::class);
$form->add('options', ProductOptionType::class);
$form->add('notes', TextareaType::class, ]);

ProductOptionType is another type I have created but on this type I inject on constructor the current product so I know then what available options this product has in order to add in the form (ie color, size etc).

class ProductOptionType extends AbstractType
{    
    private $productOptions;

    public function __construct(Product $product)
    {
        $this->productOptions = $product->getOptions();
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        foreach ($this->productOptions as $option) {
            $builder->add($option->getId(), ChoiceType::class, [
                'choices' => $option->getChoicesForForm(),
                'label' => $option->getName()
            ]);
        }
    }
}

The Problem is how to pass the constructor here???

$form->add('options', ProductOptionType::class);

The above throws contstructor none error as it instantiates the type without passign to the injector the product.

Also this one throws exception:

$form->add('options', new ProductOptionType($product));

Because it expects a string and not an object.

1

1 Answer 1

3

You could pass extra data with the options

class ProductOptionType extends AbstractType
{    

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $productOptions = $options['productOptions'];

        foreach ($productOptions as $option) {
            $builder->add($option->getId(), ChoiceType::class, [
                'choices' => $option->getChoicesForForm(),
                'label' => $option->getName()
            ]);
        }
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        // you can define a required option field for work
        $resolver->setRequired([
             'productOptions',
         ]);
         // ...
         // You could specify which type of class is supported
        $resolver->setAllowedTypes([
             'productOptions' => ProductOptions:class,
         ]);
    }

}

Then use it in the form creation as follow:

$form->add('options', ProductOptionType::class, ['productOptions' => $product]);

Hope this help

Sign up to request clarification or add additional context in comments.

1 Comment

Yes this is a nice solution thanks! Just for the record from this $form->add('options', ProductOptionType::class, null, ['productOptions' => $product]); remove the null as then it has 4 arguments.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.