How to set the name of a form without a class? - symfony

Here is written how to set the name of a form with a class:
http://symfony.com/doc/2.0/book/forms.html#creating-form-classes
but how to set the name of this form?
$form = $this->createFormBuilder($defaultData)
->add('name', 'text')
->add('email', 'email')
->getForm();
Well, I'm trying to get post parameters after submitting it this way:
$postData = $request->request->get('form_name');

I would like to bring some more precision. At least, for the most recent version of Symfony (2.1), the correct symtax (documented on the API) is:
<?php
public FormBuilderInterface createNamedBuilder(string $name, string|FormTypeInterface $type = 'form', mixed $data = null, array $options = array(), FormBuilderInterface $parent = null)
It is important because you can still pass options to the FormBuilder.
For a more concrete example:
<?php
$form = $this->get('form.factory')->createNamedBuilder('user', 'form', null, array(
'constraints' => $collectionConstraint,
))
->add('name', 'text')
->add('email', 'email')
->getForm();

There is no shortcut method for this purpose. Instead you have to access the method createNamedBuilder in the form factory:
$this->get('form.factory')->createNamedBuilder('form', 'form_name', $defaultData)
->add('name', 'text')
->add('email', 'email')
->getForm();

If you're using Symfony 3.1, the field types have changed to use their explicit class (FormType, TextType, and EmailType) and the parameter position for the value of the form name attribute has switched places with the FormType parameter in the createNamedBuilder function.
$this->get('form.factory')
->createNamedBuilder('form_name', FormType::class, $defaultData)
->add('name', TextType::class)
->add('email', EmailType::class)
->getForm();

Is there any reason why you don't just do:
$data = $form->getData();

In version 2.4.1 of Symfony, the solution is:
$form = $this->createFormBuilder ( NULL, array ( 'attr' => array ( 'name' => 'myFormName', 'id' => 'myFormId' ) ) )
->add (..
You can also set other form attributes this way, but I've not tried. Replace NULL with your data if you want.

Related

How to prefill field of type EntityType from PHP

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.

Symfony2, Sonata, FormMapper, add hidden field to be handled in PrePersist/PreUpdate

I actually did some tricks so i could be able to persist a user if its ID is passed by an url parameter. (Custom action from user list).
/admin/se/api/bundle/create?user=7
I actually could not find how to send the user entity returned by a findByOne(array('id' => $user_id)) so i guess i'll need to pass the $user_id through a hidden field and handle its value in a PrePersist
Otherwise passing the id that way
->add('user', 'hidden', array('data' => $user_id))
will return an error :
This value is not valid.
Symfony\Component\Validator\ConstraintViolation
Object(Symfony\Component\Form\Form).children[user] = 7
Caused by:
Symfony\Component\Form\Exception\TransformationFailedException
Compound forms expect an array or NULL on submission.
This is my first attempt that is not working :
$container = $this->getConfigurationPool()->getContainer();
$request = $container->get('request');
$user_id = $request->get('user');
if(!empty($user_id)){
$em = $this->getModelManager()->getEntityManager($this->getClass());
$user = $em->getRepository('ApiBundle:User')->findOneBy(array('id' => $user_id));
if($user){
$formMapper
->with('User', array('description' => '<strong>User : </strong>'.$user->getDisplayName()))
->add('user', 'hidden', array('data' => $user_id))
// this of course doesn't work as explained above. How can i have my own hidden input not related to any property
->end();
}
So how would i do that? Any better solution is welcomed.
Well this is the best trick i found. I wish 'sonata_type_model_hidden' has more options. I guess i could do my own custom field to be able to do that. But i'm not sure how and anyway this solution is fast to implement.
$formMapper
->with('Guide', array('description' => '<strong>Guide : </strong>'.$guide->getDisplayName()))
->add('guide', 'sonata_type_model_autocomplete', array(
'property' => array('firstname', 'lastname', 'username', 'email'),
'data_class' => null, // IMPORTANT
'data' => $guide,
'attr' => array('class' => 'sonata-autocomplete-hidden'), // custom class
'label_attr' => array('class' => 'sonata-autocomplete-hidden'), // custom class
)
)
->end();
To hide the field :
.sonata-autocomplete-hidden{
display:none;
}
If you have any better solutions, you're welcome.

<select> in Symfony

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

Custom choices list of sonata_type_model field with Sonata Admin

I am using Sonata Admin and I have a field of categories and I need to show them in order like a tree in select:
<select>
<option>Category father-1</option>
<option>--Category child-1-1</option>
<option>--Category child-1-2</option>
<option>--Category child-1-3</option>
<option>----Category child-1-3-1</option>
<option>----Category child-1-3-2</option>
<option>--Category child-1-4</option>
<option>--...</option>
<option>Category father-2</option>
</select>
It's possible? I have tried it including in 'choice_list' an array generate in getTreeCatsArray method:
protected function configureFormFields(FormMapper $formMapper)
{
$tree_cat_array = $this->em->getRepository('MyBundle:Category')->getTreeCatsArray();
$formMapper
->add('category', 'sonata_type_model', array(
'empty_value' => '',
'choice_list' => $tree_cat_array));
}
This shows the error:
The option "choice_list" with value "Array" is expected to be of type "null", "Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface"
I am not sure if I must use field type 'sonata_type_model' or 'choice'
OK, I've got the list of categories ordered in tree to include it in the related entity as follows:
protected function configureFormFields(FormMapper $formMapper)
{
$em = $this->modelManager->getEntityManager('MyBundle\Entity\Category');
$query = $em->createQueryBuilder('c')
->select('c')
->from('MyBundle:Category', 'c')
->where('c.parent IS NOT NULL')
->orderBy('c.root, c.lft', 'ASC');
$formMapper
...
->add('categoria', 'sonata_type_model', array(
'required' => true,
'query' => $query
))
...
;
}
I hope it can help someone
Try:
->add('category', 'entity', array(
'class' => 'Acme\Entity\Category',
)
This will work only if you have entity Category.
See this article about creating a tree editor for Category entity for SonataAdminBundle. Here is the same article in Russian, but contains missing code in the first variant.
Afterreading the above answers I had to do the following to get the functionality the OP was after:
protected function configureFormFields(FormMapper $formMapper)
{
$em = $this->modelManager->getEntityManager('YourBundleFile\YourBundleFileBundle\Entity\YourEntity');
$qb = $em->createQueryBuilder();
$qb = $qb->add('select', 'u')
->add('from', 'YourBundleFile\YourBundleFileBundle\Entity\YourEntity u');
$query = $qb->getQuery();
$arrayType = $query->getArrayResult();
$formMapper
->add('yourProperty', 'choice', array('choices'=>$arrayType))
-end();
}

How to update record with edit form?

I Have this code, that must update object in DB with data from form, but it says that i must use setId() instead of direct changind property "ID". But i need to get "ID" from hiding field from previous form. How can i get that works?
$rPhone = new RejectedPhone();
$em = $this->getDoctrine()->getEntityManager();
$repository = $em->getRepository("TelnetSmsBundle:RejectedPhone");
$addRPhoneForm = $this->createFormBuilder($rPhone)
->add('id', 'hidden')
->add('phone', 'text', array("label" => "Номер телефона (обязательно через 7-ку!):"))
->add('description', 'textarea', array("label" => "Описание:"))
->getForm();
$addRPhoneForm->bindRequest($request);
var_dump($rPhone); exit();
$em->flush();
I think you need this:
$addRPhoneForm ->setData($rPhone);
I think you forgot the persist method:
$em->persist($rPhone);

Resources