Reputation: 18660
I've this Form:
OrdersType
class OrdersType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Others $builder fields goes here
if ($this->register_type[0] == "natural")
{
$builder->add('person', new NaturalPersonType(), array('label' => FALSE));
}
elseif ($this->register_type[0] == "legal")
{
$builder->add('person', new LegalPersonType(), array('label' => FALSE));
}
}
}
PersonType
class PersonType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('description', 'text', array(
'required' => TRUE,
'label' => FALSE
))
->add('contact_person', 'text', array(
'required' => FALSE,
'label' => 'Persona de Contacto'
));
}
}
This is what I'm doing in the controller:
public function editAction($id = null)
{
$em = $this->getDoctrine()->getManager();
$order = $em->getRepository('FrontendBundle:Orders')->find($id);
$type = $order->getPerson()->getPersonType() === 1 ? "natural" : "legal";
$orderForm = $this->createForm(new OrdersType(array($type)), $order, array(
'action' => $this->generateUrl('update-order', array('id' => $id)),
'method' => 'POST',
));
return array(
'entity' => $order,
"form" => $orderForm->createView(),
'id' => $id
);
}
Then in my view I'm rendering fields as follow:
{{ form_widget(form.person.person.description) }}
The code renders the field right but without values and yes, it has values, where is the error? This are the others Forms I'm using:
LegalPersonType
class LegalPersonType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('rif', 'text', array(
'required' => true,
'label' => false,
'attr' => array(
'maxlength' => 10,
))
)
->add('identification_type', 'choice', array(
'label' => FALSE,
'choices' => RifType::getChoices(),
'attr' => array(
'class' => 'toSelect2'
)
))
->add('person', new PersonType(), array('label' => FALSE));
}
}
Working on mapping
PersonType
class PersonType extends AbstractType {
....
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Tanane\FrontendBundle\Entity\Person',
'inherit_data' => true
));
}
public function getName()
{
return 'person';
}
}
NaturalPersonType
class NaturalPersonType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder
->add('identification_type', 'choice', array(
'label' => 'Número de Cédula',
'choices' => CIType::getChoices()
))
->add('ci', 'number', array(
'required' => true,
'label' => false,
'attr' => array(
'maxlength' => 8,
))
)
->add('person', new PersonType(), array(
'label' => FALSE,
'data_class' => 'Tanane\FrontendBundle\Entity\NaturalPerson'
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Tanane\FrontendBundle\Entity\NaturalPerson'
));
}
public function getName()
{
return 'natural_person';
}
}
If I remove the setDefaultOptions
method from NaturalPersonType
I get this error:
The form's view data is expected to be of type scalar, array or an instance of \ArrayAccess, but is an instance of class Tanane\FrontendBundle\Entity\NaturalPerson. You can avoid this error by setting the "data_class" option to "Tanane\FrontendBundle\Entity\NaturalPerson" or by adding a view transformer that transforms an instance of class Tanane\FrontendBundle\Entity\NaturalPerson to scalar, array or an instance of \ArrayAccess.
If I leave as it's I get this other:
Method "description" for object "Symfony\Component\Form\FormView" does not exist in /var/www/html/tanane/src/Tanane/BackendBundle/Resources/views/Order/edit.html.twig at line 134
Upvotes: 1
Views: 126
Reputation: 1480
It looks like PersonType
is not being mapped correctly to your entity.
Since it's being used both by LegalPersonType
and NaturalPersonType
to handle some of their properties, I would define it as parent
of those two. This can be achieved by using the inherit_data
option (documentation).
Your code would look something like this:
PersonType
class PersonType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('description', 'text', array(
'required' => TRUE,
'label' => FALSE
))
->add('contact_person', 'text', array(
'required' => FALSE,
'label' => 'Persona de Contacto'
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'inherit_data' => true,
));
}
}
Note that you should remove the data_class
option from setDefaultOptions()
.
LegalPersonType
class LegalPersonType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('rif', 'text', array(
'required' => true,
'label' => false,
'attr' => array(
'maxlength' => 10,
))
)
->add('identification_type', 'choice', array(
'label' => FALSE,
'choices' => RifType::getChoices(),
'attr' => array(
'class' => 'toSelect2'
)
))
->add('data', new PersonType(), array(
'label' => FALSE,
'data_class' => 'YourBundle\Entity\LegalPerson',
));
}
}
Your NaturalPersonType
would look similar to LegalPersonType
.
Now, you can do this in your view:
{{ form_widget(form.person.data.description) }}
Upvotes: 2