The question is similar to this one, but there is a huge difference: I do not have a fixed number of elements that I want to add.
Beneath is a preview of the form and how it should look like. I have a form for a user entity which includes different application entities and each application entity has several number of user group entities.

User
class User extends BaseUser
{
...
/**
* @ORM\ManyToMany(targetEntity="Application", inversedBy="users")
* @ORM\JoinTable(name="users_applications")
*/
protected $applications;
/**
* @ORM\ManyToMany(targetEntity="UserGroup", inversedBy="users")
* @ORM\JoinTable(name="users_groups")
*/
protected $user_groups;
Application
class Application
{
...
/**
* @ORM\ManyToMany(targetEntity="User", mappedBy="applications")
*/
protected $users;
/**
* @ORM\OneToMany(targetEntity="UserGroup", mappedBy="application")
*/
protected $user_groups;
User group
class UserGroup
{
...
/**
* @ORM\ManyToOne(targetEntity="Application", inversedBy="user_groups")
* @ORM\JoinColumn(name="application_id", referencedColumnName="id")
*/
protected $application;
/**
* @ORM\ManyToMany(targetEntity="User", mappedBy="user_groups")
*/
protected $users;
UserFormType
class UserFormType extends AbstractType
{
// Array of applications is generated in the Controller and passed over by the constructor
private $applications;
public function buildForm(FormBuilderInterface $builder, array $options)
{
...
if ($this->applications && count($this->applications) > 0)
{
foreach ($this->applications AS $application)
{
$builder->add('applications', 'entity', array
(
'class' => 'MyBundle:Application',
'property' => 'title',
'query_builder' => function(EntityRepository $er) use ($application)
{
return $er->createQueryBuilder('a')
->where('a.id = :id')
->setParameter('id', $application->getId());
},
'expanded' => true,
'multiple' => true
));
$builder->add('user_groups', 'entity', array
(
'class' => 'MyBundle:UserGroup',
'property' => 'title',
'query_builder' => function(EntityRepository $er) use ($application)
{
return $er->createQueryBuilder('ug')
->where('ug.application = :application')
->setParameter('application', $application);
},
'expanded' => true,
'multiple' => true
));
}
}
...
PROBLEM: I have already managed to include the application and user group entities, but since the application entities are added to the formbuilder by a loop, entities are overwritten, such that having multiple applications only one application gets rendered.
You do want collections. Collections allow for an arbitrary number of elements (which meets your requirements). I think the problem is you should have a UserGroupType so that collections work the way you want.
Here is more or less a complete example of your form types. Namespaces and other things omitted.
Controller (remember, you are passing in the User object to the form, don't do what you were doing with private $applications):
...
$user = ...;
$form = $this->createForm(new UserFormType(), $user);
Changes to UserFormType:
class UserFormType extends AbstractType
{
// Don't have that $applications member here...
public function buildForm(FormBuilderInterface $builder, array $options)
{
//...
// Your user has many UserGroups, so display each one as a UserGroup field (see UserGroupFormType)
$builder->add('user_groups', 'collection', array(
'type' => new UserGroupFormType() // I would make this type a service (http://symfony.com/doc/current/book/forms.html#defining-your-forms-as-services)
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Namespace\Entity\User'
));
}
// ... getname, etc.
}
New UserGroupFormType:
class UserGroupFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Each UserGroup has 1 application and multiple users
// The entity fields allow you to select these
$builder->add('application', 'entity', array
(
'class' => 'MyBundle:Application',
'property' => 'title',
'query_builder' => function(EntityRepository $er) use ($application)
{
return $er->createQueryBuilder('a')
->where('a.id = :id')
->setParameter('id', $application->getId());
},
'expanded' => true,
'multiple' => false
));
$builder->add('users', 'entity', array
(
'class' => 'MyBundle:User',
'property' => 'title',
'query_builder' => function(EntityRepository $er) use ($application)
{
return $er->createQueryBuilder('ug')
->where('ug.application = :application')
->setParameter('application', $application);
},
'expanded' => true,
'multiple' => true
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Namespace\Entity\UserGroup'
));
}
// ... getname, etc.
}
See also http://symfony.com/doc/current/cookbook/form/form_collections.html That shows you how to handle adding new UserGroups in the form (if you want that functionality).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With