Symfony Error in Optional Form Field - php

I have the next form in Symfony 2.7:
$form = $this->createFormBuilder($entity)
->add('laboratorio',null, array('required'=>false)->getForm();
"laboratorio" is a field of type entity. But when I submit the form whitout select a value I got the next error:
An exception occurred while executing
'SELECT n0_.id AS id0, n0_.codigo AS codigo1,
n0_.nombre AS nombre2 FROM nom_laboratorio
n0_ WHERE n0_.id IN (?)' with params [""]:
I think that Symfony should not try to find the entity by his id when the optional field is blank.
Even I try whith $this->submit($request,true) instead of $this->handleRequest($request) in the controller but nothing change.
There is something I am ignoring?

Please try to use the empty_data option.
$form = $this->createFormBuilder($entity)
->add('laboratorio',null, array(
'required' => false,
'placeholder' => 'Choose the laboratorio',
'empty_data' => null,
)->getForm();

Related

Symfony Dynamically change field attributes after submission

so I Have this Symfony Form field :
$builder
->add('field1', CheckboxType::class, [
'required' => false,
])
->add('field2', NumberType::class, [
'disabled' => !$entite->getField1(),
'required' => $entite->getField1(),
]);
When the form is build, the field2 attributes are set depending on the entity field1 value.
Then, in the form, field2 HTML attributes are dynamically changes using javascript : if field1 value change, when add or remove 'disabled' / 'required" attributes accordingly.
The problem is, if the field2 is disabled when the form is build and then when enabled id with js, if we submit the form, in PHP the field2 is still disabled.
So I also change attributes in php, by adding this in the FormType:
...
$builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'preSubmit']);
....
public function preSubmit(FormEvent $event)
{
$data = $event->getData(); // here $data['field2'] has the correct value
$form = $event->getForm(); // here $form->get('field2') value is null and disabled is true
// trying to remove the field
$form->remove('field2');
// And then re-add it with new attributes
$form
->add('field2', NumberType::class, [
'data' => $data['field2'],
'disabled' => !$data['field1'],
'required' => $data['field1'],
]);
}
So is there a bettey way to change attributes fields after submission (without removing and adding the field with new attributes) ??
Edit
So this works until I set an incorrect value type for field2.
field2 is a NumberType, and is I set an alpha value (like 'azerty')
instead of returning the formview with the fild error message, I get a Symfony Error :
A cycle was detected. Listeners to the PRE_SET_DATA event must not call getData() if the form data has not already been set. You should call getData() on the FormEvent object instead.
How I can prevent that and get the field error message instead.
Thanks.

Default value in ActiveDropDownList

I've inherited a piece of code from an old developer and currently trying to figure out the method behind how it submits.
I'm currently trying to get a quick fix in place where I hide one of his fields to get the form submitting, the issue I'm having is that I can't seem to set the dropdownlist to a default value, which should be United Kingdom, with the id 826 in the database.
echo CHtml::ActiveDropDownList($address, 'country_id', CHtml::listData(Country::model()->findAll(), 'id', 'name', 'continent'), array(
'class' => 'col-md-5 hidden',
'prompt' => 'Select Country',
'label' => 'something here',
'ajax' => array(
'type' => 'POST',
'url' => CController::createUrl('/user/UpdateRegions'),
'dataType' => 'json',
'data' => array('country_id' => 'js:this.value', 'YII_CSRF_TOKEN' => Yii::app()->request->csrfToken),
'success' => 'function(data) {
$("#Address_country_region_id").html(data.country_id);
$("#Address_country_region_id").removeClass(\'hidden\');
if($("#venue_id").val() === "") {
$("#Address_country_region_id").addClass(\'hidden\');
}
}',
)));
$path = CController::createUrl('/admin/user/UpdateRegions');
$id = $address->id;
// On Load
Yii::app()->clientScript->registerScript('ready', '
$.ajax({
type: \'POST\',
dataType : \'json\',
data: {\'country_id\': $(\'#Address_country_id\').val(), \'update_id\' : "' . $id . '"},
url: "' . $path . '",
success: function(data){
$(\'#Address_country_region_id\').html(data.country_id);
}
})
');
How do I get this dropdownlist pointing towards the country_id of 826 as the page loads so I can hide the field and pass the validation of the form.
regards.
this code you pasted does this:
the first part renders a dropdown which does an ajax request on change to /user/UpdateRegions to fill the dependent dropdown for the regions.
the second part does also an ajax request when the page is "ready". So that the region select is filled when the page is ready.
Your script should output the id 826 if you printout the current set id.
If not the value isn't correctly set to the address model.
echo $address->country_id;
If you want to set the default value you can do this at multiple places. e.g. in the controller 'before' the actual submitted value is set or in the model code itself (depends on your code e.g. if you have an additional form model which is extended from your activerecord model).
The correct line in your controller could be before something like this:
$address->country_id= 826;
before one of these lines in your controller
$address->attributes=Yii::app()->request->getQuery(get_class($address));
or
$address->attributes=Yii::app()->request->getPost(get_class($address));
or
$address->attributes=$_POST['address']; // or $_GET
If you have difficulties to find the correct position post some controller code.
I guess you could find some help also here
Yii 1.1: An Easy Solution for Dependent dropDownList Using AJAX
To set default value for $address model, put
$address->country_id = Yii::app()->request->getParam(get_class($address).'[country_id]', 816);
before
echo CHtml::ActiveDropDownList($address, 'country_id', CHtml::listData(Country::model()->findAll(), 'id', 'name', 'continent'), array(

Symfony2 having issues with multiple property in form types

I'm pretty deep into a complex Symfony2 project, with many entities and join tables in forms etc. but I'm having a strange issue with the "multiple" attribute within the form builder.
Basically I have a form where a user can add an illness to the CRM, and each illness can be attached to a specific store (depending on the language used). There is a list of stores that can be chosen by the user within this form, and the values are stored in a join table. However I only want one store to be chosen (i.e. a select drop down) rather than a multiple select list but using the false value for the multiple attribute throws an error which I will outline later.
Firstly, here is the buildForm() code in my Type.php file:
$builder->add('name' , 'text');
$builder->add('description' , 'textarea');
$builder->add('store', 'entity',
array(
'class' => 'AppBundle:Store',
'empty_value' => 'Choose store',
'property' => 'name',
'multiple' => false,
));
$builder->add('save', 'submit', array(
'attr' => array(
'class' => 'btn btn-primary'
),
));
And the entry for the store field in my Entity:
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Store", inversedBy="illness", cascade={"persist"})
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="store_id", referencedColumnName="id")
* })
*/
public $store;
However, if I used the false declaration for the multiple attribute in the form Type, when the form is submitted I receive the following error:
Warning: spl_object_hash() expects parameter 1 to be object, string given
because it looks like it's passing the text value of the select box, rather than the relevant Entity. When set as a multiple select box (i.e. set to true) then it works fine and persists as it should.
My controller code:
$addIllness = new Illness();
$form = $this->createForm(new IllnessType($em), $addIllness);
$form->handleRequest($request);
if ($form->isValid()) {
$em->persist($addIllness);
$em->flush();
return $this->redirect($this->generateUrl('app_illness_table'));
}
Having it as a multiple select box is not the end of the world, though I'd rather have it as a drop down select so the user cannot select more than one store - rather than me having to add an error message or note to tell them otherwise.
If anyone has an ideas as to why this may be happening, or has encountered it before please let me know, I would be very grateful!
Thank you
Michael

Symfony2 form is not valid but entity gets saved anyway?

I couldn't find a solution for my current problem in the web.
I got a formular and an entity.
If the formular is not valid ($form->isValid() returns false), the entity is saved with the invalid data anyway. I see the form errors and that's correct. But my entity should not be updated if the form is not valid. What is going wrong here?
My entity got a hand full fields and a many-to-many relation with extra fields too.
I can show you some code parts:
$entry = $em->getRepository('MyAppBundle:Entry')->find($id);
// ...
$form = $this->createForm(new EntryType($this->getUser(), $entry), $entry);
$request = $this->getRequest();
if ($request->getMethod() == 'POST') {
$form->bind($request);
// ...
// i set custom errors here by myself!
if ($entry->getDeadlineEnable() && NULL === $entry->getDeadlineAt()) {
$form->get('deadline_at')->addError(new FormError('Please enter a date.'));
}
// ...
if ($form->isValid()) {
$em->merge($entry);
$em->flush();
// ...
return $this->redirect($this->generateUrl('MyAppBundle_homepage'));
As you can see, I check the form with isValid, which works correct. It returns false if there is a form error, e.g.
$form->get('deadline_at')->addError(new FormError('Please enter a date.'));
But the entitiy gets updated exactly here in this line anyway:
if ($form->isValid()) {
Why is this?
This is a really bad problem here. I don't know why this happens.
Thanks for any advice.
EDIT:
More information:
I use validators too for all fields wich has simple conditions.
I do this in the EntryType.php # public function buildForm(FormBuilderInterface $builder, array $options), e.g.:
$builder->add('min_commitments', null, array(
'label' => 'Zusagen mindestens',
'attr' => array(
'class' => 'form-control',
'placeholder' => 'Ab wievielen findet\'s statt?',
'min' => 0,
'max' => 100,
),
'required' => false,
'invalid_message' => 'Das ist keine gütige Angabe.',
'constraints' => array(
new Range(array(
'minMessage' => 'Mindestens 1.',
'maxMessage' => 'Maximal 100.',
'min' => 1,
'max' => 100,
)),
),
));
This is a number field to type in a number between 1 and 100.
But for some fileds i use my own validation direclty in the controller action method because the fields (most of them are a combination of a checkbox field and an text field belonging to to this checkbox) because many fields are interdependent.
I still don't know whats wrong with isValid and why the entity behind this form gets saved even the form is not completely valid. isValid returns false there if an error exists (correct).
Could this maybe be caused by the many to many relation ship?
I implementet such a relationship to allow the user to select many checkboxes, where each checkbox represents an user. The relation rows are saved into the relation table EntryUser.
Here is the many to many field in the form definition (Entry.php):
/**
* #ORM\OneToMany(targetEntity="EntryUser", mappedBy="entry", cascade={"all"}, orphanRemoval=true)
*/
protected $entry_users; // One more thing: this is a one to many but it is a many to many relationship at all because i created a relationship table with extra fields so it bacame a own entity. on the other side, the file User.php got the oppsite part of the many-to-many relationship with:
User.php:
/**
* #ORM\OneToMany(targetEntity="EntryUser" , mappedBy="user" , cascade={"all"} , orphanRemoval=true)
*/
protected $entry_users;
The form->bind is what is actually updating the entity with posted
data regardless of the data's validity. You must have another flush
getting kicked off somewhere. Perhaps a listener? Normal workflow for
$form->isValid() === false is to redisplay the form with the invalid
data and error messages. Once again, it would appear that you have
something calling $em->flush.-
Credit to #Cerad
Have you ever tried validators? http://symfony.com/doc/current/book/validation.html
If your attached code is from your controller - the problem is that your condition is wrong.
if ($entry->getDeadlineEnable() && NULL === $entry->getDeadlineAt()) {
$form->get('deadline_at')->addError(new FormError('Please enter a date.'));
}
Controller isn't the best place to valide. How are you going to reuse the validator for the form?

Symfony2 add extra selectbox

I added extra select box (choice type) and mapped=>false see the code below.
However when I submit the form. It returned the error msg "This value is not valid."
$form->add('extraField' ,'choice', array(
'required' => false,
'choices' => $arrayChoices,
'mapped'=>false,
'data' =>$id
));
What did I do wrong here?
Ok, after this doc : http://symfony.com/doc/current/reference/forms/types/choice.html#choices
I don't see 'data' option. Try to remove it please. (and , what is the use of this field [data]? )
Are you sure that $id is valid array key for $arrayChoices?
Also, when you submit the form, the request must contain a valid key inside of $arrayChoices

Categories