Customize output of entity Field Type - symfony

I have a form to select users widh checkboxes.
Now, the list of users is displayed in the form but only the username is displayed. I would like to display all user data with each checkboxes: name, first name, email ...
How can I do this ?
$builder->add('users', 'entity', array(
'class' => 'AppBundle:User',
'choice_label' => 'username',
'expanded' => true,
'multiple' => true,
));

You should create a new method in the entity User. Something like:
public function getAllUserData(){
return $this->name .' | '. $this->email (As you want);
}
In the form:
$builder->add('users', 'entity', array(
'class' => 'AppBundle:User',
'choice_label' => 'allUserData',
'expanded' => true,
'multiple' => true,
));
Cheers...

Related

Symfony - Error with the data parameter on a form

Context of the problem :
I created a symfony form.
Each tool has a collection of modules.
The user has a collection of modules of any tool.
What I want :
I want for each tool there are checkboxes corresponding to the tool's modules. The module checkboxes that the user owns are checked.
([] = checkbox)
Tool1 : []Module1 [x]Module2 [x]Module3
Tool2 : []Module4 [x]Module5
Tool3 : [x]Module6 []Module7
What I currently have:
For each tool, there are checkboxes corresponding to the tool's modules. But I have a problem to tick the checkboxes of user's modules. I get an error on the data parameter.
The form field :
$user = $options['user'];
$tools = $options['tools'];
foreach ($tools as $tool) {
$name = 'profile_'.str_replace(array('-', ' ', '.'), '', $tool->getLibelle());
$builder
->add($name, ChoiceType::class, [
'label' => $tool->getLibelle(),
'choices' => $tool->getModules(),
'choice_value' => 'id',
'choice_label' => function (?Module $module) {
return $module ? $module->getName() : '';
},
'data'=> $user->getModules(), // ERROR HERE
'expanded' => true,
'multiple' => true,
'mapped'=>false
])
;
}
[...]
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => User::class,
'user'=> null,
'category'=> null,
'tools'=> null,
]);
}
The error :
My question :
Why do I have this error? How can I use the data parameter correctly to achieve the expected result?
You are on the good way, try to dump what is $user->getModules() returning, it has to be an array. May be is not returning an array, check te relation.
I did a little test and it works perfectly.
$name = 'name_field';
$builder->add($name,ChoiceType::class, array(
'choices' => array('Yes', 'No'),
'data' => array('Yes', false),
'mapped' => false,
'expanded' => true,
'multiple' => true
));
Here the solution :
Seems to me that $user->getModules() returns a collection. I managed to find another solution and that works (I changed the type of the field to EntityType)
foreach ($tools as $tool) {
$name = 'acces_'.str_replace(array('-', ' ', '.'), '', $tool->getLibelle());
$builder
->add($name, EntityType::class, [
'class'=> Module::class,
'label' => $tool->getLibelle(),
'data' => $user->getModules(),
'choices'=> $tool->getModules(),
'choice_value' => 'id',
'choice_label' => 'name',
'expanded' => true,
'multiple' => true,
'required' => true,
'mapped'=>false,
])
;
}
ChoiceType: data parameter need array
EntityType: data parameter need collection
Thanks for the help !

Symfony query builder with post submit data is not changing the values in EventListener

I have a filter form which is filtering for markets, types and airlines. When submitted, I'd like another dropdown (documentlist) to be filtered after the selected values. Therefore I created a post_submit eventlistener which is working (I dumped the values as you can see in the following code). But when then trying to update the documentlist values through a query builder and with the data from my filters, it's not working. Any ideas:
<?php
namespace DocumentBundle\Form\Document;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM;
use Doctrine\ORM\EntityRepository;
use Symfony\Bundle\FrameworkBundle\Controller;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use DocumentBundle\Form\Document\DocumentFilterType;
class DocumentDeactivationType extends DocumentFilterType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('type', 'choice', array('choices' => array(
'document_types.contract' => 1,
'document_types.general'=>2,
'document_types.goodwill_policy'=>3,
'document_types.pricesheet'=>4,
'document_types.yq_update'=>5,
'document_types.contract_addendum'=>6),
'choices_as_values' => true, 'label' => 'label.types',
'expanded' => false, 'multiple' => true,
'label' => 'label.type', 'required' => false,
'translation_domain' => 'Documents'))
->add('airlines', 'entity', array(
'class' => 'AppBundle:Airline', 'property' => 'id',
'query_builder' => function (EntityRepository $er){
return $er->createQueryBuilder('a')
->addOrderBy('a.id', 'ASC');
},
'choice_value' => 'id',
'choice_label' => 'id', 'label' => 'label.airlines',
'expanded' => false, 'multiple' => true, 'required' => false,
'translation_domain' => 'Documents'))
->add('markets', 'entity', array(
'class' => 'AppBundle:Market', 'property' => 'id',
'query_builder' => function (EntityRepository $er){
return $er->createQueryBuilder('m')
->addOrderBy('m.id', 'ASC');
},
'choice_value' => 'id',
'choice_label' => 'id', 'label' => 'label.markets',
'expanded' => false, 'multiple' => true, 'required' => false,
'translation_domain' => 'Documents'))
->add('documentlist', EntityType::class, array(
'class' => 'DocumentBundle:Document',
'property' => 'name',
'expanded' => false, 'multiple' => true,
'label' => 'label.document_list',
'empty_value' => "Select document",
'required' => false,
'mapped' => false,
'translation_domain' => 'Documents'));
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) use ($builder)
{
$form = $event->getForm();
$data = $event->getData();
$markets = $data['markets'];
$type = $data['type'];
$airlines = $data['airlines'];
dump($markets, $type);
$builder
->add('documentlist', EntityType::class, array(
'class' => 'DocumentBundle:Document',
'property' => 'name',
'expanded' => false, 'multiple' => true,
'label' => 'label.document_list',
'empty_value' => "Select document",
'required' => false,
'mapped' => false,
'translation_domain' => 'Documents',
'query_builder' => function (EntityRepository $er) use ($markets, $type, $airlines){
return $er->createQueryBuilder('e')
->where('e.markets = :markets')
->andWhere('e.airlines IN (:airlines)')
->andWhere('e.products IN (:products)')
->setParameter('e.markets', $markets)
->setParameter('e.airlines', $airlines)
->setParameter('e.type', $type);
},
));
});
}
public function getName()
{
return 'document_deactivation';
}
}
You cannot change the form (add or remove fields) in a POST_SUBMIT event. But you can in a PRE_SUBMIT event, so you just need to change POST_SUBMIT with PRE_SUBMIT.
But be careful because your form data won't be normalized in PRE_SUBMIT, so you will have to work with raw data from your form (an array), or to normalize manually your data.

Generate data attribute to each checkbox in Symfony type

->add('research_subject', EntityType::class, array(
'mapped' => false,
'class' => Subject::class,
'label' => 'Research Subject',
'expanded' => true,
'multiple' => true,
'query_builder' => function (EntityRepository $er) {
$db = $er->createQueryBuilder('w');
$db ->where($db->expr()->andX(
$db->expr()->isNotNull('w.pid')
));
$db->orderBy('w.pid', 'ASC');
return $db;
},
'choice_label' => 'name_system',
))
I need to add to each check box data attribute. Is that is possible?
I need that for extra sort of checkboxes in twig latter. I need to group checkboxes by pid value in separate div section.
'choice_attr' => function($val, $key, $index) {
return ['data-pid' => $val->getPid()];
},
I had use this as solution, like https://stackoverflow.com/users/4224384/yceruto
Suggest.
You would use the "choice_attr" option for this:
[...]
'expanded' => true,
'multiple' => true,
'choice_attr' => function($val, $key, $index) {
return ['data' => $key];
},
[...]

Symfony 2.8 - FormBuilder : why field becomes required when I define its type?

I'm building a form like with two non mandatory fileds :
$form = $this->createFormBuilder($contact);
$form->add('name');
$form->add('subject', TextType::class);
$form->getForm();
After rendering the first field is not required (it's normal) but why the second is ?! What's wrong with this code ?
Thanks :)
The problem must be the related entity to this form. Are name and subject nullable?. If no ORM configured then you need to manually set the required attribute to each form field. Look the example of a contact form without ORM.
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('fullName', null, array(
'required' => true,
'attr' => array(
'placeholder' => 'Name',
'class' => 'text gradient'
)))
->add('email','email', array(
'required' => true,
'attr' => array(
'placeholder' => 'Email',
'class' => 'text gradient'
)))
->add('subject', null, array(
'required' => true,
'attr' => array(
'placeholder' => 'Subject',
'class' => 'text gradient'
)))
->add('body', 'textarea', array(
'required' => true,
'attr' => array(
'placeholder' => 'Message',
'class' => 'text gradient'
)));
}
required default value is defined in type class method configureOptions()
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'required' => true,
));
}
and in all parents for this type (parent is defined by getParent() method)
first parent is Symfony\Component\Form\Extension\Core\Type\FormType and there required default value is defined as true, to it is strange that first input is not required.
you can define required while adding new element $form->add('subject', TextType::class, array('required' => false));

More advance entity join in FormBuilder Symfony2

I have two entities. First is Clinic an second is ClinicOpeningHours.
ClinicOpeningHours is mapped by Clinic id, but not in revers. I'm trying to find solution to get whole (7) records (mon - sun) and join it in ClinicFormType to have all this in one form.
$clinic = $em->getRepository('MyEntity:Clinic')->findOneBy(array(etc));
$form = $this->createForm(new ClinicFormType(), $clinic);
My form type:
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('name', 'text', array('label' => 'Name'));
$builder->add('services', 'entity', array(
'class' => 'MyEntity:Service',
'property' => 'name',
'label' => 'Services',
'required' => false,
'multiple' => true,
'attr' => array(
'data-placeholder' => "Choose one...",
'multiple' => 'multiple',
'class' => "chzn-select"
)
))
->add('WEEK DAYS', 'entity', array(
'label' => 'Property Language',
'class' => 'MyEntity:ClinicOpeningHours',
'query_builder' => SEVER RECORDS FROM DB MAPPED BY ID
},
));
}

Resources