Symfony 2.7, form won't submit if field is blank - forms

I have a classic form, with a few 'entity' type fields and one collection type fields. Those aren't causing any issue.
When I put data in all the field, except the description field, as I want it to be null or empty, and submit, my form is processed but the new entity not added to the database, as if the description field needed to be field.
Then I'm redirected to the same form with all data entered gone, as if it had been added in the database.
I've checked the field mapping, which is set to nullable :
/**
* #var string
*
* #ORM\Column(name="description_activite", type="text", nullable=true)
*/
private $descriptionActivite;
public function getDescriptionActivite(){return $this->descriptionActivite;}
public function setDescriptionActivite($value){$this->descriptionActivite=$value;return $this;}
And the field description in the formType file :
->add('descriptionActivite', 'textarea', array(
'label' => 'Description',
'attr' => array(
'class' => 'form-control',
// 'required' => false
)
))
I've also checked the database just in case, the field is created as a may be null field, I really don't know where that problem is coming from. Anyone ran into this already? Thanks

For those who meet the same problem, I solved it by :
Checking database if field may be null (was not the issue but would have been later)
Checking annotation, see if the field is set as nullable
AND LAST
->add('descriptionActivite', 'textarea', array(
'label' => 'Description',
'required' => false,
'attr' => array(
'class' => 'form-control',
)
))
the required option was place in the 'attr' array(), when it should not have, my bad.

Related

symfony2: selected value of choices fields

I get something strange with Symfony2 forms. I create a form with a propel entity, values are fine except the "select" (choices) field, that have no selected value.
I tried few tricks like:
$params['choices'] = array('N/A'=> 'N/A');
$params['data'] = array('N/A');
$params['preferred_choices'] = array('N/A');
Even with this, there is no preselected value. What's wrong ?
You can use data attribute for default selected item.
$param['data'] = 'N/A'
This is part of the Abstract "field" type ?
Fore example form,
$form = $this->createFormBuilder()
->add('category', 'choice', array(
'choices' => array(
0 => 'Books',
1 => 'Electronics',
2 => 'Hardware`
),
'data' => 1
))
->getForm();
In this example when the form loads the option Electronics should be selected as default
'empty_value' => 'Select Choice',
$builder->add('gender', 'choice', array(
'choices' => array('m' => 'Male', 'f' => 'Female')
'empty_value' => 'Select Choice',
));
I finally solved my problem. There were 2 things:
* reloading with Firefox, the previously selected value seems to be kept, so I coulnd't really test the changes until I closed the current tab and reopened one;
* I passed a single dimension array as values for the "choice" field, so Symfony2 re-indexed it with integer and my entity string value couldn't be hydrated to the symfony2 integer value of the field.

Symfony2 doctrine form - entity type

I'm trying to add an entity field in a symfony2 form but it's always giving me the same error: '500 (Internal Server Error) '.
This is the class i'm using to create the form. It was automatically programmed with doctrine and CRUD.
class ClientType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('companyName', 'text' , array( 'attr' => array( 'class' => 'companyname' ) ) )
->add('contactUserName','text' , array( 'attr' => array( 'class' => 'contactusername' ) ))
->add('phone','text' , array( 'attr' => array( 'class' => 'phone' ) ))
->add('subdomain','text' , array( 'attr' => array( 'class' => 'subdomain' ) ))
->add('email','text' , array( 'attr' => array( 'class' => 'email' ) ))
->add('website','text' , array( 'attr' => array( 'class' => 'website' ) ))
;
}
This works fine, but then, i try something like this:
->add('client', 'entity', array(
'class' => 'BackendBundle:Client'));
'500 (Internal Server Error)'
I tried so many different ways to do this, but it's always the same error.
The thing is, i can add or remove the fields that were created at the beggining when this class was done by the doctrine CRUD but if i try adding more fields with different types, it won't let me.
Should i make my own Type class so i can customize my forms or is there a way to modify the form doctrine made?
TY
The thing is, i can add or remove the fields that were created at the
beggining when this class was done by the doctrine CRUD but if i try
adding more fields with different types, it won't let me.
This is because the command that created your ClientType.php did so, based upon the structure of your BackendBundle\Entity\Client.php file. The form is mapped to the entity that you intend to create. If you want more fields on the form, you will need to add the fields as properties in your BackendBundle\Entity\Client.php, then run:
php bin/console doctrine:generate:entities <VENDOR>/<BUNDLE>/Entity/Client
or if using Symfony 2 < version 2.5
php app/console doctrine:generate:entities <VENDOR>/<BUNDLE>/Entity/Client
To generate the getters and setters for that field, and then
php bin/console doctrine:schema:update --force
or if using Symfony 2 < version 2.5
php app/console doctrine:schema:update --force
To add the new field(s) to the database table.
Now you can try to add the field as you were, ensuring that the first argument in the add() method exactly matches how you names your property in the entity.

Remove null values coming from empty collection form item

I'm trying to implement a ManyToMany relation in a form between 2 entities (say, Product and Category to make simpe) and use the method described in the docs with prototype and javascript (http://symfony.com/doc/current/cookbook/form/form_collections.html).
Here is the line from ProductType that create the category collection :
$builder->add('categories', 'collection', array(
'type' => 'entity',
'options' => array(
'class' => 'AppBundle:Category',
'property'=>'name',
'empty_value' => 'Select a category',
'required' => false),
'allow_add' => true,
'allow_delete' => true,
));
When I had a new item, a new select appear set to the empty value 'Select a category'. The problem is that if I don't change the empty value, it is sent to the server and after a $form->bind() my Product object get some null values in the $category ArrayCollection.
I first though to test the value in the setter in Product entity, and add 'by_reference'=>false in the ProductType, but in this case I get an exception stating that null is not an instance of Category.
How can I make sure the empty values are ignored ?
Citing the documentation on 'delete_empty':
If you want to explicitly remove entirely empty collection entries from your form you have to set this option to true
$builder->add('categories', 'collection', array(
'type' => 'entity',
'options' => array(
'class' => 'AppBundle:Category',
'property'=>'name',
'empty_value' => 'Select a category'),
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true
));
Since you use embedded forms, you could run in some issues such as Warning: spl_object_hash() expects parameter 1 to be object, null given when passing empty collections.
Removing required=>false as explained on this answer did not work for me.
A similar issue is referenced here on github and resolved by the PR 9773
I finally found a way to handle that with Event listeners.
This discussion give the meaning of all FormEvents.
In this case, PRE_BIND (replaced by PRE_SUBMIT in 2.1 and later) will allow us to modify the data before it is bind to the Entity.
Looking at the implementation of Form in Symfony source is the only source of information I found on how to use those Events. For PRE_BIND, we see that the form data will be updated by the event data, so we can alter it with $event->setData(...). The following snippet will loop through the data, unset all null values and set it back.
$builder->addEventListener(FormEvents::PRE_BIND, function(FormEvent $event){
$data = $event->getData();
if(isset($data["categories"])) {
foreach($data as $key=>$value) {
if(!isset($value) || $value == "")
unset($data[$key]);
}
$event->setData($data);
});
Hope this can help others !
Since Symfony 3.4 you can pass a closure to delete_empty:
$builder
->add('authors', CollectionType::class, [
'delete_empty' => function ($author) {
return empty($author['firstName']);
},
]);
https://github.com/symfony/symfony/commit/c0d99d13c023f9a5c87338581c2a4a674b78f85f

symfony2 form entity option value

i need to create a form with symfony that has an entity type, so this is im using
->add('assignee', 'entity', array(
'label' => 'Assignee',
'class' => 'PortalBundle:TrnUser',
'property' => 'username',
))
in the generated html it assigns userid as the option value, but i need the username as the option value. something like,
<option value="admin">admin</option>
how can i do this? please help.
thanks..
You need data transformers. They help you to show data in form as you want.
There you can find all information about Data Transformers in Symfony2:
http://symfony.com/doc/current/cookbook/form/data_transformers.html
You could use the 'choice_value' option with the name of the field you want to use instead of the id.
$builder
->add('user', 'entity', [
'class' => 'YourBundle\Entity\Locations',
'property' => 'name',
'choice_value' => 'name',
'required' => true,
])

Symfony2 - Translate entity field type options

I'm using the FormBuilder to create my form. That works fine. The problem is my "Licence Object" which creates an select field with options. These options should be translated. But how to do that?
$form = $this ->createFormBuilder($request)
->add('title', 'text',
array( 'label' => $this->get('translator')->trans('form.title', array(), 'client_request_a_photo'))
)
->add('description', 'textarea',
array( 'label' => $this->get('translator')->trans('form.description', array(), 'client_request_a_photo'))
)
->add('licence','document',
array('class'=>'WunschbildBundle\Document\Licence', 'property'=>'options',
'label' => $this->get('translator')->trans('form.licence', array(), 'client_request_a_photo'))
)
->getForm();
In any case, you don't provide what is the 'document' field type, so we can't help much. However, from what I understand the options are fetched through the attribute 'options' of the 'Licence' object. If you want those to be translated, the object 'Licence' must be translatable and the attribute 'options' must have translations. You can do this by using the doctrine extensions bundle. The documentation about Translatable can be found here. Hope this help.