mapmath
mapmath

Reputation: 1532

Symfony: Embeding Collection of Forms issue

Symfony version: 3

I need to create a form that insert user data into two tables. So I am following this method in the Symfony doc. I have two entities called Users and Address and I have created two form builders like below,

AddressType

class AddressType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('address');
        $builder->add('postCode');
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'PIE10Bundle\Entity\Address',
        ));
    }
 }

UserType

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('firstname');
        $builder->add('lastname');

        $builder->add('address', 
                      CollectionType::class, 
                      array(
                            'entry_type' => AddressType::class
         ));

        $builder->add('Add User', SubmitType::class);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'PIE10Bundle\Entity\Users',

        ));
    }
}

and my Contoller,

public function addNewUserAction(Request $request)
{
    $user    = new Users;
    $address = new Address;

    $form = $this->createForm(UserType::class, $user);

    $form->handleRequest($request);

    return $this->render('PIE10Bundle:Form:newuser.html.twig',
                         array(
                                'title' => 'Add New User',
                                'form'  => $form->createView()
    ));
}

and yes finally the view PIE10Bundle:Form:newuser.html.twig

{% extends "PIE10Bundle::layout.html.twig" %}
{% block cmi_body %}
<div class="row">
    <div class="col-md-2">

    </div>
    <div class="col-md-6">
        {{form_start(form)}}
            {{form_widget(form)}}
        {{form_end(form)}}
    </div>
</div>
<div class="row">
    {{ dump(form) }}
</div>
{% endblock %}

And I am getting something like the below. enter image description here

in the form I am not getting the text fields for following

$builder->add('address');
$builder->add('postCode');

I need to know if I am missing something in my code or the reason for not getting the two text fields and how to fix this issue.

Thanks in advance.

Upvotes: 0

Views: 77

Answers (3)

Robert Wade
Robert Wade

Reputation: 5003

In your User class:

change:

$builder->add('address', 
     CollectionType::class, 
     array(
           'entry_type' => AddressType::class,array('label' => false)
     ));

to:

$builder->add('address', AddressType::class);

CollectionType is used when your relationship is one-to-many or many-to-many. So if your user was able to have multiple addresses, you would use CollectionType (but with some modification to your code).

UPDATE to deal with multiple labels:
You have two Address labels because when you add the formtype AddressType in your UserForm it takes on the label "Address" by default. Also inside your AddressType you have a field for "Address" which takes on the label "Address" by default, hence the two labels. Look at the code above. I've added array('label' => false) to the AddressType which will remove the first instance and leave the label on the actual field.

Upvotes: 1

Beno&#238;t
Beno&#238;t

Reputation: 602

Inside the __construct of your user, add a new address instance

public function __construct()
{
    $this->address = new Address();
}

With that you will see the missing form fields

Upvotes: 1

Mert &#214;ks&#252;z
Mert &#214;ks&#252;z

Reputation: 1071

You have to extend AddressType from UserType

Change your AddressType like that;

    class AddressType extends UserType
    {
        public function buildForm(FormBuilderInterface $builder, array         $options)
        {
            parent::buildForm($builder, $options);
            $builder->add('address');
            $builder->add('postCode');
        }

        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'PIE10Bundle\Entity\Address',
            ));
        }
     }

delete this part;

     $builder->add('address', 
                  CollectionType::class, 
                  array(
                        'entry_type' => AddressType::class
     ));

Upvotes: 1

Related Questions