How do I can create a in symfony form from the controller?
$form = $this->createFormBuilder($fupv)
->add('idUsuario', 'text')
->add('permiso', 'text')//I want a select here
->add('save', 'submit')
->getForm();
You need to use a choice Field Type.
There are various options depending on how you are populating the select.
A simple example;
$form = $this->createFormBuilder($fupv)->add('gender', 'choice', array(
'permiso' => array('a' => 'Admin', 'u' => 'User')
));
Have a look at the symfony docs for more examples.
You have to use the choice field type
->add('myField', 'choice', array(
'choices'=> array('choice1'=>'printedvalueofchoice1','choice2'=>'printedvalueofchoice2'),
'multiple'=> false,
'expanded'=> false ))
expanded set to true will turn your select into radio options
Related
I have created one dropdown for employee Role. In edit mode how to select user selected role.
$builder->add('homePageId', \Propel\Bundle\PropelBundle\Form\Type\ModelType::class , array(
'class' => 'Admin\HomePageBundle\Model\HomePage',
'required' => true,
'multiple' => false,
'expanded' => false,
'query' => HomePageQuery::create()->orderByName(),
'property' => 'name',
'preferred_choices' => array('5')
));
I have added "preferred_choices" for select "5" number role but not working.
Please help for fixed this issue.
The selected value is the object value. I'll try to explain this way:
$object = new Object();
$object->setHomePageId(5);
// kinda put the 5 as selected in your form, because your object contains 5 and the form is not binded yet.
$form = $this->createForm(ObjectType, $object);
$form->getData()->getHomePageId(); // will return 5
//kinda put the request parameter homepageId as selected in your form
$form->handleRequest($request);
$form->getData()->getHomePageId(); // will return the user selection
In my form, I have a field of type EntityClass:
$builder
->add(
'user',
EntityType::class,
[
'required' => false,
'label' => 'User',
'placeholder' => 'Please choose',
'choice_label' => 'email',
'choice_value' => 'id',
'class' => 'AppBundle:User',
]
)
;
This field works fine - until I try to pre-fill it from my PHP code. Then it stays empty, and only shows "Please choose".
Pre-filling looks like this:
$user = $this->userRepository->find(...);
$form->get('user')->setData($user);
But it also does not work if I call ->setData($user->getId()), or even ->setData($user->getEmail()).
So how do I prefill a field of type EntityType?
You should not prefill Form, you should prefill Model, if you need it.
$user = $this->userRepository->find(...);
$entity = new YourEntity();
$entity->setUser($user);
$form = $this->createForm(YourEntity::class, $entity);
And it's not about EntityType. It's about any Type in Symfony - there is no way to bind a default value for them. Data is binded on Model.
UPD from comment: It's not true, that Form could be used without Model. It could be used without Doctrine Entity or any other ORM (or not ORM) Entity. But they still operate with data, i.o. with model.
\Symfony\Component\Form\FormFactoryInterface has definition
public function create($type = 'form', $data = null, array $options = array());
So some kind of $data is always present when you're using Form Component.
The code below creates 2 radiobuttons, however they are not related to each other. One is rendered with a name description_form[friend] and the other one with the name - description_form[guide]. How can they be rendered with the same name? The documentation is not clear about this subject.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('friend', RadioType::class, array(
'label' => 'Friend',
'required' => false
))
->add('guide', RadioType::class, array(
'label' => 'Guide',
'required' => false
));
}
Using a list of RadioType is not quite easy, that's why everybody recommends you to use a ChoiceType which dynamically creates a radio list depending on an array of choice data.
When you create a FormTypeInterface, it has to represent (commonly) one field or one sub form in a global form, so each field name has to be unique to be mapped to the corresponding data.
The buildForm method allows to add some sub fields in you FormType, in your case the field holds two sub fields as radio button and each has a specific name, this is intended by default, but you should always keep in mind the global array data you want to deal with.
Here's your example :
class MyCustomFormType extends \Symfony\Component\Form\AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('friend', RadioType::class, array(
'label' => 'Friend',
'required' => false
))
->add('guide', RadioType::class, array(
'label' => 'Guide',
'required' => false
));
}
public function getBlockPrefix
{
return 'my_custom';
}
// ...
}
So this form type data should look like :
$myCustomFormData = array(
'friend' => $friendData,
'guide' => $guideData,
);
And nested in a global form it would be :
$formData = array(
'my_custom' => $myCustomFormData,
);
But you can name the field as you want :
// In a controller extending \Symfony\Bundle\FrameworkBundle\Controller\Controller
$form = $this->createFormBuilder()
->add('custom_field', MyCustomFormType::class)
->getForm();
// Then
$form->setData(array('custom_field' => $myCustomFormData));
Note that currently, since you map "friend" and "guide" data to RadioType they should hold a boolean value as :
$myCustomFormData = array(
'friend' => true, // checked
'guide' => false, // unchecked
);
But how would you unselect a value then ?
You should had a placeholder to do that, and handle it while submission...
Also, changing the name can be done using the finishView method of your type class, it takes the FormView (built view of your type), the form itself and the options as arguments :
public function finishView(FormView $view, FormInterface $form, array $options)
{
$childName = $view->vars['full_name']; // "my_custom" by default
foreach ($view as $childView) {
$childView->vars['full_name'] = $childName;
}
}
But you would also need to add a DataMapperInterface to get back the submitted value to the form type itself instead.
To do all that, you need to know how the Form Component works and it's not easy.
Easy way
So I agree with the other answers, you should use a ChoiceType to get it out-of-the-box.
I assume your custom form type is about choosing either a "friend" or a "guide", so it could look like this :
$builder
->add('fellow', ChoiceType::class, array(
'choices' => array(
'I have a friend' => 'friend',
'I\'d like a guide' => 'guide',
),
'expanded' => true, // use a radio list instead of a select input
// ...
Have a look at the official docs
Then your data will look like :
$form->add('custom_field', MyCustomFormType::class);
$form->setData(array(
'custom_field' => 'friend',
));
When rendered the "friend" choice will be selected and you will be able to change it to "guide".
An array of choices for the choices options takes labels as keys and choice values as values :
<div id="form_custom_field">
<input type="radio" name="form[custom_field]" value="friend" checked="checked">
<label>I have a friend</label>
<input type="radio" name="form[custom_field]" value="guide">
<label>I'd like a guide</label>
...
This is how I do radio buttons in Symfony 2.7 , hope it helps you.
$yes_no = array('1'=>'Yes','0'=>'No');
->add('myfieldname', 'choice',array(
'choices' => $yes_no,
'label'=>'YourLabelGoeshere',
'required'=>true,
'expanded'=>true,
'multiple'=>false,
'placeholder'=>false
))
Perhaps consider using the ChoiceType field.
See here: Documentation
This allows you to output the options as radio buttons if you choose.
RadioType is used internally by ChoiceType. In most use cases you want to use ChoiceType.
I feel the same as a forum user who posted this:
I implemented FOSUserBundle, and I want to add to RegisrationFormType roles that are taken from a table. When I had it like this:
->add('roles', 'choice', array('label' => 'Rol', 'required' => true,
'choices' => array( 'ROLE_ADMIN' => 'ADMINISTRADOR','ROLE_SUPERADMIN' => 'SUPERADMINISTRADOR',
'ROLE_USER' => 'USUARIO'), 'multiple' => true))
And it works! But they must leave the BD, I can not put the Entity field because roles should be an array, not an object. How I can generate the array with the roles taken from a table? In FosUSerbundle as you would add roles?
Thanks ....
I write because that user had no answer. I followed [the steps of official documentation] (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md) and adding the above lines in the register of FOSUserBundle works, but I want to work this from the database.
And then I used to create groups this. Two additional tables were created and even now joined a group or role in the list, but not how to show the login to register a new user.
Has anyone solved it?
So you have the roles in a table? You could inject the EntityManager in the form type and use it to fetch the choices.
->add('roles', 'choice', array(
'label' => 'Rol',
'choices' => $this->getRoles(),
'multiple' => true,
'required' => true,
))
Then create a method which gives you the data the way you need.
Something like:
public function getRoles()
{
$roles = array();
$er = $this->em->getRepository('AppBundle:Role');
$results = $er->createQueryBuilder('r')
// conditions here
->getQuery()
->getResult();
// process the array?
foreach ($results as $role) {
$roles[$role->getId()] = $role->getLabel();
}
return $roles;
}
Use case
I am learning Symfony2 and am creating a Table Tennis tracking app to learn the framework. I have configured my entities as follows.
Player 1..n Result n..1 Match
On my form I'd like to validate that the scores for a match are correct.
Implementation
Match has an ArrayCollection() of results.
My MatchType and ResultType forms contain the following.
// Form\MatchType
$builder->add('matchType', 'entity', array(
'class' => 'PingPongMatchesBundle:MatchType',
'property' => 'name',
)
)
->add('results', 'collection', array(
'type' => new ResultType(),
'allow_add' => true,
'by_reference' => false,
)
)
->add('notes');
// Form\ResultType
$builder->add('player', 'entity', array(
'class' => 'PingPongPlayerBundle:Player',
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('p')
->orderBy('p.firstName', 'ASC');
},
))
->add('score');
Issue
I need to be able to validate the scores. However I'm not sure how to approach this type of validation as I need to compare two instances of my Result#score in order to know if they are valid or not.
Is anyone able to suggest a method or approach that I could use in order to be able to compare Result#score between the two different instances? Can I validate the ArrayCollection in the Match entity for example?
You could creat a custom validator constraint on Match entity.
http://symfony.com/doc/2.0/cookbook/validation/custom_constraint.html
Take a look in Callback constraint:
http://symfony.com/doc/2.1/reference/constraints/Callback.html