I have an entity that is on the back of three one-to-one mappings. The FittingStep object FittingStep displayed by FittingStepSingleValue , etc. FittingStep has a fittingStepType field that identifies which of the three objects FittingStep should look for. I want to insert this object into the FittingStep edit FittingStep .
I defined forms as services for each of the subforms:
services: ihear.form.fitting_step_single_value: class: Ihear\FittingBundle\Form\FittingStepSingleValueType arguments: [@security.context] tags: - name: form.type alias: ihear_fittingbundle_fittingstepsinglevaluetype ihear.form.fitting_step_double_value: class: Ihear\FittingBundle\Form\FittingStepDoubleValueType arguments: [@security.context] tags: - name: form.type alias: ihear_fittingbundle_fittingstepdoublevaluetype ihear.form.fitting_step_option: class: Ihear\FittingBundle\Form\FittingStepOptionType arguments: [@security.context] tags: - name: form.type alias: ihear_fittingbundle_fittingstepoptiontype
These service classes look like this (pretty simple)
class FittingStepSingleValueType extends AbstractType { private $securityContext; public function __construct(SecurityContext $securityContext) { $this->securityContext = $securityContext; } public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('max1') ->add('description1') ->add('fittingStep', 'hidden') ; } public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => 'Ihear\FittingBundle\Entity\FittingStepSingleValue' )); } public function getName() { return 'ihear_fittingbundle_fittingstepsinglevaluetype'; } }
My form uses the EventListener in PRE_SET_DATA to add the appropriate field of the inline form:
class FittingStepType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('name') ->add('abbreviation') ->add('description') ->add('fittingStepType', 'choice', ['choices' => ['SingleValue' => 'SingleValue', 'DoubleValue' => 'DoubleValue', 'Option' => 'Option'], 'empty_value' => 'select one please']) ; $formModifier = function(FormInterface $form, $fittingStepType) { switch ($fittingStepType) { case 'SingleValue': $form->add('fittingStepSingleValue', 'ihear_fittingbundle_fittingstepsinglevaluetype'); if ($form->has('fittingStepDoubleValue')) $form->remove('fittingStepDoubleValue'); if ($form->has('fittingStepOption')) $form->remove('fittingStepOption'); break; case 'DoubleValue': $form->add('fittingStepDoubleValue', 'ihear_fittingbundle_fittingstepdoublevaluetype'); if ($form->has('fittingStepSingleValue')) $form->remove('fittingStepSingleValue'); if ($form->has('fittingStepOption')) $form->remove('fittingStepOption'); break; case 'Option': $form->add('fittingStepOption', 'ihear_fittingbundle_fittingstepoptiontype'); if ($form->has('fittingStepSingleValue')) $form->remove('fittingStepSingleValue'); if ($form->has('fittingStepDoubleValue')) $form->remove('fittingStepDoubleValue'); break; } }; $builder->addEventListener( FormEvents::PRE_SET_DATA, function(FormEvent $event) use ($formModifier) { $form = $event->getForm();
My controller for the edit action:
public function editAction($id) { $em = $this->getDoctrine()->getManager(); $entity = $em->getRepository('IhearFittingBundle:FittingStep')->find($id); if (!$entity) { throw $this->createNotFoundException( 'Unable to find FittingStep entity.'); } $editForm = $this->createForm(new FittingStepType(), $entity); $deleteForm = $this->createDeleteForm($id); return array( 'entity' => $entity, 'edit_form' => $editForm->createView(), 'delete_form' => $deleteForm->createView(), ); }
When I try to load a form, I get an exception:
It is expected that the data of the form type will be of the scalar, array, or instance \ ArrayAccess type, but is an instance of the class Ihear \ FittingBundle \ Entity \ FittingStep. You can avoid this error by setting the "data_class" option for "Ihear \ FittingBundle \ Entity \ FittingStep" or by adding a transformer view that converts an instance of the Ihear \ FittingBundle \ Entity \ FittingStep class for a scalar, array, or instance from \ ArrayAccess.
What am I doing wrong? There seems to be some connection between matching objects between objects and displaying on the form. As a side note, I have successfully used the closure of $formModifier in my create form, so it works great when creating a new object with an inline form.