So, I have a formbuilder action which has, in part, this:
->add('apples_group', 'entity',
array(
'class' => 'ThingMainBundle:ApplesGroup',
'multiple' => true,
'expanded' => true,
'property' => 'applesName'
)
)
This currently outputs as a multi-select box in this code:
{{ form_widget(form.apples_group, { "attr": {"class": "fields-list" } }) }}
Sometimes - in a different View - this needs not to be multiple, and should be a dropdown box instead. Is there a way to specify to the widget that the attribute multiple should be false when you render this widget?
(Validation of if this allowed to be multiple in this circumstance is already on the back end)
It is better to create
// YourFormType.php
public function __construct(Apple $apple)
{
$this->apple = $apple;
}
and
->add('apples_group', 'entity',
array(
'class' => 'ThingMainBundle:ApplesGroup',
'multiple' => $this->apple->isMultiple() , // you set it in admin, right?
'expanded' => true,
'property' => 'applesName'
)
)
controller:
$entity = new Apple() ;
$form = $this->createForm( new YourFormType($entity), $entity) ;
So it looks like the actual answer is to wait until https://github.com/symfony/symfony/issues/6602 lands.
Related
I am using Symfony 5, I want to have a "User Edit" page in administration, in which I will change User Roles, I want to have checkboxes to define which role assign to user, so for that, I need Collection Type with CheckboxType entry inside (if I am true), but for first I can't use user roles array as value for collection type
$builder
->add('roles', CollectionType::class, [
'entry_type' => CheckboxType::class,
'entry_options' => [
'required' => false,
],
])
This throws error
Unable to transform value for property path "[0]": Expected a Boolean.
after that, I tried to use a model transformer to change the value, below is code how I did that
$builder->get('roles')
->addModelTransformer(new CallbackTransformer(
function($rolesAsArray){
$rolesAsArray = array_flip($rolesAsArray);
foreach($rolesAsArray as &$role){
$role = true; // I also tried to set key instead of value - true
}
return $rolesAsArray;
},
function($rolesAsString){
dump($rolesAsString);die;
}
));
After this, I didn't get an error but I get the form with this look
So I haven't any option to change labels, and even I am submitting a form with these fields it throws an error
Expected argument of type "array", "null" given at property path "roles".
I found a way to do this with Select Box, but I can't found any way to do it with Checkbox.
If you have any ideas tell me, please.
You can use ChoiceType :
$builder->add('roles', ChoiceType::class, array(
'label' => 'form.label.role',
'choices' => User::ROLES,
'choice_translation_domain' => 'user',
'multiple' => true,
'expanded' => true,
'required' => true,
));
In User entity:
const ROLES = array(
'roles.admin' => 'ROLE_ADMIN',
'roles.secretary' => 'ROLE_SECRETARY',
'roles.user' => 'ROLE_USER'
);
I am working on an existing Symfony 3.3 project, and I have been asked to register a dropdown field in a results filter form that should contain all the values from a field in the database.
Until now, what I have do is the following that partially works:
$builder->add(
'newField',
EntityType::class,
[
'class' => Transaction::class,
'required' => false,
'multiple' => false,
'label' => 'New Field',
'choice_label' => 'newField',
'placeholder' => 'Choose a value'
]
)
The above code is able to display the values correctly, but unfortunately, because the table has repeatedly the same values, I get a long list of all the same values.
Instead, what I need to achieve is to display the DISTINCT values from the database.
I have tried the query_builder, but to be honest I am not sure I use it correctly as I am not an experienced Symfony developer.
Any idea on how to display the entries of the given column with DISTINCT results?
As you said yourself, you can use the query builder to achieve this. Something as simple as this should achieve what you're after:
->add('fooBar', EntityType::class, [
'query_builder' => function (EntityRepository $repository) {
return $repository
->createQueryBuilder('f')
->distinct();
},
]);
You can also specify a flag to be distinct and remember not to return the result but return the query. You can read more here
You are right,
Query_builder is the way to go.
So first create the method of what you want to do in TransactionRepository.
class TransactionRepository extends EntityRepository
{
//....
public function getDistinctValues()
{
//Return what you want to get, I cannot write this for you without your entity
}
}
Then use it in the FormType :
$builder->add(
'newField',
EntityType::class,
[
'class' => Transaction::class,
'required' => false,
'multiple' => false,
'label' => 'New Field',
'choice_label' => 'newField',
'placeholder' => 'Choose a value',
'query_builder' => function(TransactionRepository $repository) {
return $repository->getDistinctValues();
}
]
)
And you should be good to go.
I've have a formtype that has an entitytype field.
$builder->add('canRead', EntityType::class, [
'attr' => ['style' => 'height:150px;'],
'choice_value' => 'id',
'required' => true,
'multiple' => true,
'expanded' => false,
'class' => 'AppBundle\Entity\User',
'query_builder' => function (EntityRepository $er) {
$qb = $er->createQueryBuilder('e');
$qb->innerJoin('e.roles', 'r')->where('r.role LIKE :role')->setParameter('role', 'ROLE_ADMIN_%')
->orderBy('e.lastName', 'ASC')
->addOrderBy('e.firstGame', 'ASC');
return $qb;
},
]);
In the controller, I call this like that:
$form = $this->createForm(MedicalType::class, null, [ 'data'=>[] ]);
Where the 'data' is meant to be the selected values for the generated multiple select-field.
I've tried to pass a single User object, an array of User id's, arraycollection of Users, etc.. All of my tries before was the part from "query_builder"s results of course.
Did not work neither of them. Does someone know a solution to pass "selected" values for an entitytype field in formbuilder?
Thank you in advance.
The second parameter to createForm() being null seems to be the problem.
Lets say you have an array of user objects:
$data = [$user1, $user2];
Then try creating the form like that:
$form = $this->createForm(MedicalType::class, $data);
or this way:
$form = $this->createForm(MedicalType::class, array(), [ 'data'=> $data ]);
I tried the above solution but it didn't work for me so this might be helpful for someone else.
I had to pass an array of modules to the form so that it will be the default selected values, so in my controller i did this:
function testAction(){
$modules=array();
//here i'm just loading the modules that will be the default selected values
for ($i=7;$i<20;$i++){
$modules[]=$this->getDoctrine()->getRepository("AppBundle:Module")->find($i);
}
//passing the modules to the form
$form=$this->createForm(ModuleFieldType::class, array(), [ 'data'=> $modules ]);
return $this->render("/Security/test.html.twig",array("form"=>$form->createView()));
}
And in my form I did this :
$builder->add('module', EntityType::class, array(
'class' => 'AppBundle\Entity\Module',
'choice_label' => 'libelle',
'label' => 'Modules Enseignés',
'placeholder'=>"selectionez les modules enseigné",
'group_by' => function (Module $module) {
return $module->getDepartement()->getName();
},
"attr"=>array("id"=>"modulesSelect"),
'multiple' => true,
//you need add this to the form in order to read the data
'data'=>$options['data'],
));
The result was like that in the rendered form:
The rendered form
is it possible to update an option field after adding it ?
$builder
->add('examens', 'entity', array(
'class' => 'TelegrammeExamenBundle:ExamExamen',
'property' => 'libelle',
'required' => true,
'empty_value' => 'Sélectionnez un examen',
//'data' => $this->em->getReference("TelegrammeExamenBundle:ExamExamen", 510),
'data' => null,
'query_builder' => function(ExamenRepository $r) {
return $r->getSelectList();
},
'attr' => array('class' => 'bg_white_filet_gris')
))
;
how modify field option ??? (setOption don't exist)
if (...) $builder->get('examens')->setOption('property', 'test');
You can simply ->add() it again. As the API documentation suggests for the add method:
Adds or replaces a child to the form
http://api.symfony.com/2.8/Symfony/Component/Form/FormInterface.html#method_add
This can be used to modify form elements for example in a FormEvent.
Alternatively the FormBuilder provides a setAttribute() method which can be used as follows:
$builder->get('examens')->setAttribute('property', 'test');
My buildForm class is like this below.
$builder->add('icon','entity',
array(
'class' => 'UserBundle:IconPics',
'property' => 'label', // .. or whatever property the image location is stored.
'expanded' => true,
'multiple' => false,
'label' => 'form.icon', 'translation_domain' => 'FOSUserBundle',
'query_builder' => function ($repository) {
return $repository->createQueryBuilder('i')
->add('where', 'i.enabled = true');
}
));
How can I set the default vaule for this radiobutton?
According to Peter Bailey's answer
use Acme\UserBundle\Entity\IconPics;
//
$IconPics = new IconPics();
// howw can I select the target Icon?????
You can set the initial data for a form in a couple ways
With the data option
'data' => $default
Where $default is an instance of UserBundle\Entity\IconPics
Providing an initial data source
// Assuming form is created in a controller
$data = new WhateverYourEntitiyIs();
$defaultIcon = new \UserBundle\Entity\IconPics();
// Set properties on $defaultIcon here
// or select $defaultIcon via the repository
$data->setIcon( $defaultIcon );
$form = $this->createForm( 'form_type', $data );