Adding a non persisted Symfony form checkbox mess up with persistence - forms

I am trying to add a checkbox in my form in Symfony.
The aim of that checkbox is to eventually remove uploaded image if checked.
So it shows up only when a file is uploaded. I also want it to cancel upload before form entity is persisted.
But I am not there yet, the code that is supposed to do that is currently commented out.
This checkbox corresponds to a boolean property in my File class so that it allows to access its value in controller. At the beginning that property didn't exist and so I was unable to access this value from entity or form /getData.
My problem is having the field in my formtype messes up with persistence.
All properties acquired from the form are considered null by doctrine. Even though a file was selected, renamed with uniqid etc . When time has come to flush, the fields are considered null. Removing DeleteFile from form solved the issue. I have tried setting it with property mapped = false, to no avail.
Here is code from form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('file', 'file', array(
'label' => false
))
->add('deleteFile','checkbox', array(
'label' => 'Delete File',
'attr' => array('class' => 'delete_file'),
'mapped' => false,
))
;
}
Thank you for your input. I am also open to alternative solutions to that "interface" if a better solution can spare me from having to deal with this issue I am interested.

Related

FormType ChoiceType (select) data preset not working in view Symfony 3.4

In a Symfony 3.4 Application I have defined a MyFormType class with a ChoiceType element like that
$builder->add(
'my_field_1',
ChoiceType::class,
array(
'label' => 'My Label',
'placeholder' => 'nothing selected',
'choices' => $choicesArray,
'multiple' => false,
'expanded' => false,
'required' => false,
'mapped' => true,
'data' => $choicesPreset,
)
);
In a Controller I create the form passing in the needed object to preset data and then I pass the created view to a twig template.
In the template the form is rendered OK. Everything works except that the preset value of the ChoiceType select element is not set. The field is rendered with the placeholder option selected.
All other elements of the same form do load their preset values without problems. None of them is a ChoiceType though.
When debugging I see that the preset value is correct when creating the form class and also it is set to the field (I am not sure though which properties exactly have to be set in the FormBuilder element).
While debugging the ChoiceType preset value looks OK in the Controller as well.
However the template renders the placeholder.
I am not sure how to debug twig templates and if I knew I wouldn't know what to look for.
Any hints on what could go wrong here are very welcome.
EDIT:
While checking the choices and preset values aI discovered that the problem is actualy not coming from the form field itself or any of its options but from a data transformer.
I have this line directly below the code postet above:
$builder->get('my_entity')->addModelTransformer( $this->myEntityToNumberTransformer );
When deleting this line the preset value works (not the transformer though. Obviously...). So the question is acutaly: Why does the data transformer interfere with the preset value setup?
The problem was not in the field or the preset values but in the data transformer I mentioned in my edit. Fixing the data transformer fixed the problem with no preset values as well.

Symfony | Twig get field datas when display form

I have a simple form to filter a list in function of themes :
$builder
->add('themes', EntityType::class, array(
'class' => 'XXBundle:Theme',
'choice_label' => 'image',
...
))
->add('save', SubmitType::class)
;
And in Twig I try to access all themes to do a specific render, in fact I would like to display Image (related to each theme : theme.image) instead of the theme.
I followed other solutions : Symfony2 + CreateFormBuilder how to render an image in a form
But it doesn't work :
form.vars.value.themes / form.vars.data.themes (or form.themes.vars.value / form.themes.vars.data this is the same)
exists but are always empty. Because this is a new form. If I submit the form, it works form.vars are not empty anymore.
How can I get themes when I display the form for the first time ? I followed the doc (http://symfony.com/doc/current/reference/forms/twig_reference.html#form-variables-reference) but I can't find what I want.
TY
Basically the EntityType is a List of choices - form.themes.vars.choices. Its an array of ChoiceView, to get entity simply access public data property.
So use this property to access to the entities:
form.themes.vars.choices
More accessible attribute are listed in the doc here.
Hope this help

Symfony2: How to add/remove entry forms for the collection field type?

I have a form that contains a collection field-type.
However I don't know how to add/remove fields to/from the collection.
$builder
// ...
->add('covers', 'collection', array(
'required' => false,
'type' => new BookCoverType(),
'allow_add' => true,
))
;
The rendered form looks like this:
How can I add a new cover using the collection form field?
Symfony does not provide the add/remove JavaScript methods/buttonss or any session-based solution without JavaScript out of the box.
It renders a data-prototype attribute that can be used as described in the documentation chapter How to Embed a Collection of Forms -> Allowing "new" tags with the "prototype".
Some bundles provide this functionality though. Those are primarily the bootstrap bundles:
braincrafted/bootstrap-bundle
mopa/bootstrap-bundle
...
Just dive into their code - i.e. braincrafted/bootstrapbundle's bc-bootstrap-collection.js.

Collection form and user

im developing a simple user profile editor for my app. The values that user can edit are, e-mail, password and phone numbers.
Obviouslly, i have the User entity, that have an Phone entity collection. Also, i have the UserProfileType and the PhoneType.
The buildForm method of userProfileType, include the phone numbers:
$builder
->add('telefonos','collection', array(
'type' => new TelefonoType(),
'required' => false,
'allow_add' => true,
'allow_delete' => true
))
And the PhoneType buildForm is:
$builder
->add('valor','text',array(
'required' => false
))
->add('descripcion','text', array(
'required' => false
))
->add('user')
;
The phone numbers are displayed correctly in Twig template...but the user field is displayed as combobox and allow the user "change the user value". I wish that the user value will be implicit. How can do this ?.
I am newest with Symfony forms. Please, help me. Thanks.
As you didn't tell Symfony what type should be your user field, it's trying to guess what is the most appropriate type (you can look here for some details). So, in your Telephone entity, I suppose that the user attribute is declared as a User (another entity of yours).
As a consequence, Symfony create a form field with entity type (doc here).
If you want an "implicit user set", this is quite impossible, you have to remove the field addition in you form builder, and call setUser manualy on your entity(ies) in your controller action or a service.
You can get the current logged in user from the security token, or directly in a controller action : $this->getUser()

Symfony2 Form : Select an entity or add a new one

I have an order and a client entity.
I am wondering if it's possible with the actual Symfony2 form system to create an order form which will allow to:
Select several clients from a dropdown (mix of collection and entity form type)
And to create new clients on the fly (the default way for the collection type) if not in the dropdown list.
I've seen some way to do it by creating multiple forms in the same page, but this is not the way I would like to achieve it.
Are there any better ways to do this?
I had a similar problem which may lead to your resolution:
I have a Category and Item relationship (Many-to-One) and I wanted to either select an existing item or create a new item.
In my Form class:
$builder->add('item', 'entity', array(
'label' => 'Item',
'class' => 'ExampleItemBundle:Item',
));
$builder->add('itemNew', new EmbedItemForm(), array(
'required' => FALSE,
'mapped' => FALSE,
'property_path' => 'item',
));
$builder->addEventListener(FormEvents::PRE_SUBMIT, function(FormEvent $event) {
$data = $event->getData();
$form = $event->getForm();
if (!empty($data['itemNew']['name'])) {
$form->remove('item');
$form->add('itemNew', new EmbedItemForm(), array(
'required' => TRUE,
'mapped' => TRUE,
'property_path' => 'item',
));
}
});
You can map two fields in a form to the same property using the property_path option. Then, using form events, use the submitted data to make a decision and modify the form so that only one of the fields has a mapped option that is true.
If I have understood, you want to create and store new clients in a Form "on fly", at the moment. I think that you have to do that using JavaScript and set an additional action in your controller.
JS -> Capture the event to add new client to you database (i.e. "Add new" button click event)
JS -> Inside this event, call via AJAX to your controller with the values of new client. (Using FOSJsRoutingBundle is easy to do)
Symfony2 -> Inside your new action, store the new client in your database.
JS -> OnSuccess event, in your AJAX call, add the new Client to your DropDownBox
(ddb.append(new element tag)
Just doing that you have your new client stored in the database and added to your dropdownbox
For my part i had the same kind of problem and i resolved it by creating 2 attribute in my formType;
For example, for you it would be:
customer->entity
new_customer-> collection
In your order entity file you will have to add 3 methods (getter, setter, and remover) getter and remover don't do anything but setter should call the setCustomer(c)
I'm not sure if it is the best way but it's the only way I figure it out!
The collection Form type allows to add and delete on the fly with allow_add and allow_delete attribute.
More informations by following these 2 links :
Official collection form field type reference
Cookbook about add and delete on the fly with collection type
If you don't like to get supplementary forms on the same page, you can integrate them in dialog boxes... But you definitely need a form to create new items...