Symfony2: Form Collection of entities with one-to-one relationship - php

I have 2 entities:
TransactionDefaultParametersEntity
Parameter: widgetType
Parameter: defaultParameters (Has one to one relationship with DefaultParametersEntity)
DefaultParametersEntity
Parameter: checkIn
Parameter: checkOut
Parameter: currency
Parameter: adults
The controller provides a collection of TransactionDefaultParametersEntities, and for each I want a form displayed with all DefaultParameterEntity parameters as well as the widgetType parameter provided by the TransactionDefaultParametersEntity.
Currently I have a form type for each entity:
TransactionDefaultParametersFormType
class DefaultSettingsFormType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('defaultParameters', 'collection', ['type' => default_parameters', 'allow_add' => true]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\TransactionDefaultParametersEntity',
'create' => false
));
}
public function getName()
{
return 'transaction_default_parameters';
}
}
DefaultParametersFormType
class DefaultParametersFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('widgetType', 'choice', [
'choices' => [
'Default',
'Booking Engine',
'Informative'
],
'label' => 'Widget Type'
])
->add('checkIn', 'text', ['label' => 'Check In'])
->add('checkOut', 'text', ['label' => 'Check Out'])
->add('currency', 'text', ['label' => 'Currency'])
->add('adults', 'text', ['label' => 'adults']);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\DefaultParametersEntity',
));
}
public function getName()
{
return 'default_parameters';
}
}
And lastly in the controller:
// $transactionDefaultParametersCollection is a collection of TransactionDefaultParameterEntities
$form = $this->createFormBuilder($transactionDefaultParametersCollection)
->add('transactionDefaultParameters', 'transaction_default_settings')
->add('save', 'submit', array('label' => 'Save'))
->getForm();
$form->handleRequest($request);
if ($form->isValid()) {
// do something
}
return $this->render(
'settings/editDefaults.html.twig',
[
'form' => $form->createView()
]
);
If this wasn't clear please let me know :). Also if I could be pointed to an article that would be very helpful. I looked at how to embed a collection of forms but this was a different case than the example provided.

Related

Add a child field for each Product Field - Symfony Forms

I'm trying to build a Order functionality with Symfony 4.4 Forms
I have this, so far
class OrderProductForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('customer', EntityType::class, [
'class' => 'App\Entity\Customers',
'choice_label' => 'name',
'label' =>'order_form.name'
])
->add('products', CollectionType::class, [
'entry_type' => ProductQuantityType::class,
'label' => '',
])
->getForm();
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'App\Entity\Order',
));
}
}
and
class ProductQuantityType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('products', EntityType::class, [
'class' => 'App\Entity\Products',
'expanded' => true,
'multiple' => true,
'choice_label' => 'name',
'label' =>''
])
->add('qty', IntegerType::class, [
'label' =>'order_form.qty'
])
->getForm();
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => null,
));
}
}
That won't render Product Quantity because it has no data. Symfony manual does not say how to do it ... CollectionType
What I really want is to add a Quantity Field for each product and at the same time to add as many products as I want.
This is the doctrine structure
Only the relevant code is included
class Order
{
/**
* #ORM\ManyToOne(targetEntity=Customers::class, inversedBy="orders")
* #ORM\JoinColumn(nullable=false)
*/
private $customer;
}
class Customers
{
/**
* #ORM\OneToMany(targetEntity=Order::class, mappedBy="customer", orphanRemoval=true)
*/
private $orders;
}
Any thoughts on how I can move forward with this ?
Thanks !

How to get related object in CollectionType in Symfony4

Please, could you explain how to get the object in the child form in CollectionType way (embedded form)?
The parent form is this one:
class ClienteRespuestasType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
dump ($options['data']);
$builder
->add('respuestas', CollectionType::class, array(
// each entry in the array will be an "email" field
'entry_type' => RespuestaType::class,
// these options are passed to each "email" type
'entry_options' => array(
'attr' => array('class' => 'email-box'),
)
))
->add('Guardar', SubmitType::class, array(
'attr' => array('class' => 'btn btn-default'),
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Cliente::class,
]);
}
}
The child form is the one below. The $options['data'] is null.
public function buildForm(FormBuilderInterface $builder, array $options)
{
dump ($options['data']);
$builder
->add('contestacion', null, array(
'label' => 'HOW TO GET ATTRIBUTE OF THIS CHILD FORM'
))
;
}
And the relation between classes Cliente and Respuesta:
/**
* #ORM\OneToMany(targetEntity="App\Entity\Respuesta", mappedBy="cliente", orphanRemoval=true)
*/
private $respuestas;
Thanks!

Symfony4 form - preselection in Collection of Entities

I have two entities with a Many->Many relation , appli and service
I want to create a form that would allow me to edit, add, or remove relations .
Those entities are linked as follow ..
Appli.php :
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Service", mappedBy="applis")
*/
private $services;
public function getService() {
return $this->services;
}
Service.php :
/**
* #ORM\ManyToMany(targetEntity="App\Entity\Appli", inversedBy="services")
* #ORM\JoinTable(name="service_to_app",
* joinColumns={#ORM\JoinColumn(name="services", referencedColumnName="id_service")},
* inverseJoinColumns={#ORM\JoinColumn(name="applis", referencedColumnName="id_apps")}
* )
*/
private $applis;
Notice that $services and $applis are arrayCollections .
Here is my formType :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$item = $builder->getData();
$builder /* ... */
->add('serviceCol', CollectionType::class, array(
'entry_type' => ServiceType::class,
'entry_options' => array('label' => false,),
'property_path' => 'service',
'allow_add' => true, 'allow_delete' => true,
));
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'data_class' => Appli::class,
));
}
and the serviceType :
class ServiceType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('service', EntityType::class, array(
'class' => Service::class,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('s')
->orderBy('s.id_service', 'ASC');},
'choice_label' => 'nom', 'property_path' => 'nom', 'label' => false));
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'data_class' => Service::class,
));
}
}
My issue so far is to preselect relations, I do have the correct amount of fields , but it's only default value and does not show the existing relations .
I could get to it without using the CollectionType field , but then , I would not be able to add / remove fields .
I cant fill the 'data' option since $item->getService() gives an arrayCollection , and I could not find a way to iterate through it during the Collection definition .
Is there any simple enough solution to this ?
So the fix was quite simple , the solution was on Symfony form - Access Entity inside child entry Type in a CollectionType
It also made me read How to Dynamically Modify Forms Using Form Events with a renewed attention !
here s is my ServiceType formBuilder :
$builder->addEventListener(FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($builder) {
$form = $event->getForm();
$service = $event->getData();
if($service instanceof Service) {
$form->add('service', EntityType::class, array(
'class' => Service::class,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('s')
->orderBy('s.id_service', 'ASC');},
'choice_label' => 'nom',
'property_path' => 'nom',
'label' => false,
'data' => $service ));
}
})
;

Symfony Form Collection error

I have two entities that are connected to each other by doctrine association many-to-one. I created a form collection but when i try to save something it hits me with an error.
The error that i'm getting:
Expected argument of type "Zenith\SurveyBundle\Entity\SurveyOption", "array" given
This is my first form the one that loads the collection.
class TestType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('option', CollectionType::class, [
'entry_type' => SurveyOptionType::class,
'allow_add' => true,
'allow_delete' => true,
'entry_options' => [
'label' => false,
],
])
->add('submit', SubmitType::class, [
'label' => 'Salveaza',
])
;
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => SurveyManager::class
]);
}
}
This is the form loaded by collection:
class SurveyOptionType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('isEnabled', CheckboxType::class, [
'label' => 'Chestionar Activ',
])
->add('headquarter', EntityType::class, [
'class' => HeadQuarterManager::class,
'multiple' => false,
'expanded' => false,
])
->add('userNumber', IntegerType::class, [
'attr' => [
'min' => '1',
'type' => 'number',
],
'label' => 'Numar Utilizatori',
])
;
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => SurveyOption::class
));
}
}
My Controller action:
public function newAction($surveyId, Request $request)
{
$surveyOption = new SurveyOption();
$em = $this->getDoctrine()->getManager();
$surveyRepository = $em->getRepository(SurveyManager::class);
$survey = $surveyRepository->findOneBy(['id' => $surveyId]);
$form = $this->createForm(TestType::class, $survey);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
}
return [
'surveyOption' => $surveyOption,
'form' => $form->createView(),
];
}
The question is useless.. because i'm a hurry and overburned .. i didn't notice few mistakes.. the forms where fine .. :-)

Symfony form type display ManyToOne entity information

I'm creating a form type to update options for accounts the user have.
I have 3 entities User, UserHasAccount and Account.
Here are the relations between them:
User (OTM) <-> (MTO) UserHasAccount (MTO) <-> (OTM) Account
In UserHasAccount I have 2 options options1 and options2 (boolean)
An account can be link to multiple user. I have a page where I want to be able to change the options foreach Users linked to this Account (/account/{id}/manage-user)
Here is the first form type to map the fields from User
class AccounUserOptionFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('user', 'entity', array(
'class' => 'AcmeUserBundle:User',
'property' => 'fullname',
))
->add('option1', 'checkbox', array(
'label' => 'account.form.option.one',
'required' => false,
'error_bubbling' => true,
))
->add('option2', 'checkbox', array(
'label' => 'account.form.option.two',
'required' => false,
'error_bubbling' => true,
))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\UserBundle\Entity\UserHasAccount',
'translation_domain' => 'AcmeAccountBundle'
));
}
public function getName()
{
return 'acme_update_account_option_type';
}
}
And the AccountUserOption form type:
class AccountUserOptionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// Display the collection of users
->add('accountUser', 'collection', array(
'type' => new AccountUserOptionFormType($options),
))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\AccountBundle\Entity\Account',
'cascade_validation' => true,
'validation_groups' => array('AcmeUpdateOption'),
));
}
public function getName()
{
return 'acme_account_user_option_type';
}
}
The problem I have is with:
->add('user', 'entity', array(
'class' => 'AcmeUserBundle:User',
'property' => 'fullname',
))
I just want to display (label or similar) the name of the user. Using entity is displaying a dropdown :/ Is there any core field type I could use or do I have to create a custom one? I would have think that this could be core.
Cheers,
Maxime

Categories