How to set a class attribute to a Symfony form input with an attribut from entity linked - forms

I have in my form a "beds" attribute, an entity linked to another "bedroom".
I would like for each input to add a class with the id of the linked entity "bedroom".
$form->add('beds', EntityType::class, array(
'class' => 'DamiasResaBundle:Bed',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('b')
->orderBy('b.id', 'ASC');
},
'choice_label' => 'id',
'label' => 'lits ',
'multiple' => true,
'expanded' =>true,
'attr' => array(
'class' => function ($bed) {
return $bed->getBedroom()->getId();
}
),
))
I have two problems:
'attr' => array('class'=>'test) return a class attribut in the div containing the input, not a class attribut in the input.
This previous code does not work and returns:
An exception has been thrown during the rendering of a template ("Catchable Fatal Error: Object of class Closure could not be converted to string") in form_div_layout.html.twig at line 358.
Thank you for your help

I see you are using checkboxes.
Your code seems ok, and since you use query_builder, the values should be a Bed Entity. Note that attr is not mentioned in the EntityType documentation, and I think you need to use choice_attr instead.
Can you try this. I'm not sure if it will work or not:
$form->add('beds', EntityType::class, array(
'class' => 'DamiasResaBundle:Bed',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('b')
->orderBy('b.id', 'ASC');
},
'choice_label' => 'id',
'label' => 'lits ',
'multiple' => true,
'expanded' =>true,
'choice_attr' => function ($val) {
return ['class' => $val->getId()];
},
))
Let us know the results.

You need to customize form rendering
Previous code doesn't work because you're trying to pass Closure object instead of string value. attr array is used as field attributes, so it must contain only string values (or objects with __toString() method).

For EntityType it would rather look like this:
$form->add('beds', EntityType::class, array(
'class' => 'DamiasResaBundle:Bed',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('b')
->orderBy('b.id', 'ASC');
},
'choice_label' => 'id',
'label' => 'lits ',
'multiple' => true,
'expanded' =>true,
'choice_attr' => function (Bed $bed, $key, $index) {
return ['class' => $bed->getBedroom()->getId();];
},
))

Since choice_attr seems not to be working anymore, I am writing another solution. I wasn't able to set attribute (exactly "min") directly from formBuilder. I managed to add it with help of js. I simply searched element by ID given by formBuilder and added atribute.
Inspect your form in browser element inspector and find id.
<div id="form_deadLine">
<input type="date" id="form_deadLine_date" name="form[deadLine][date]" required="required" value="2020-02-20"/>
</div>
Id you wanna look for in my case is form_deadLine_date.
Then you wanna connect .js file to you twig template and write there simple script.
const form = document.getElementById('form_deadLine_date');
if(form){
form.setAttribute("min", "2020-01-02")
}
then my code looks like:
<div id="form_deadLine">
<input type="date" id="form_deadLine_date" name="form[deadLine][date]" required="required" value="2020-02-20"/>
</div>

Related

Empty option in a form query symfony 3.4

I must display an entity in a query_builder form
here is my code in the form type:
$builder->add('dispositif', EntityType::class, array(
'class' => 'LeaPrestaBundle:EgwDispositif',
'label' => 'nomDispositif',
'required' => true,
'empty_data' => null,
'query_builder' => function( $er)
{
return $er->createQueryBuilder('d')
->where('d.isActive = :isActive')
->setParameter('isActive', 1 )
->orderBy('d.nomDispositif','ASC');
},
));
The problem is that the option is empty :
<select id="egw_presta_dispositif" name="egw_presta[dispositif]">
<option value="52"></option>
<option value="55"></option>
<option value="62"></option>
<option value="58"></option>
</select>
For example, aside the value 52, there should have a label for "dispositif" (name of dispositif).
Does it coming from the entity ?
Thanks in advance for your help!
Try adding a 'choice_label' property with the EgwDispositif field containing what you want to display:
$builder->add('dispositif', EntityType::class, array(
'class' => 'LeaPrestaBundle:EgwDispositif',
/** label will be displayed next to your form field unless it's a translation key or else **/
'label' => 'Nom du dispositif',
'required' => true,
'empty_data' => null,
/** any field containing what you want to display as option label **/
'choice_label' => 'nomDispositif',
'query_builder' => function( $er)
{
return $er->createQueryBuilder('d')
->where('d.isActive = :isActive')
->setParameter('isActive', 1 )
->orderBy('d.nomDispositif','ASC');
},
));
It seems like you were confusing the option 'label' of the form field property with the option 'choice_label' . You probably want your label to be something user will read (bu maybe not, it's up to you)
take a look here : https://symfony.com/doc/current/reference/forms/types/entity.html

How to customize EntityType option text?

I would like to display selection with options from DB. In this case, I am using EntityType with query_builder:
$builder
->add('internships', EntityType::class, array(
'class' => 'IndexBundle\Entity\Internship',
'property' => 'id',
'empty_value' => 'Choose',
'query_builder' => function (EntityRepository $er) use ($trainee) {
return $er->createQueryBuilder('i')
->where('i.trainee = :trainee')
->andWhere('i.state = :state')
->setParameter('trainee', $trainee)
->setParameter('state', 'unverified');
},
'constraints' => array(
new NotBlank(array(
'message' => 'choice.not.blank'
))
)
))
Now all is fine. I get select element with necessary options within with text of id value.
<select>
<option value="id">id</option>
...
</select>
How do I customize it?
For example I would like it to be combination of id and type table columns:
<select>
<option value="id">#id (type)</option>
...
</select>
You can use the choice_label option to customize your options.
You can either pass a function to retrieve the text you want, or you can add a getter to your entity if you reuse it at another place.
With a function:
$builder
->add('internships', EntityType::class, array(
'class' => 'IndexBundle\Entity\Internship',
'property' => 'id',
'empty_value' => 'Choose',
'query_builder' => function (EntityRepository $er) use ($trainee) {
return $er->createQueryBuilder('i')
->where('i.trainee = :trainee')
->andWhere('i.state = :state')
->setParameter('trainee', $trainee)
->setParameter('state', 'unverified');
},
'choice_label' => function ($internship) {
return '#'.$internship->getId().' ('.$internship->getType().')';
},
'constraints' => array(
new NotBlank(array(
'message' => 'choice.not.blank'
))
)
))
With a getter:
$builder
->add('internships', EntityType::class, array(
'class' => 'IndexBundle\Entity\Internship',
'property' => 'id',
'empty_value' => 'Choose',
'query_builder' => function (EntityRepository $er) use ($trainee) {
return $er->createQueryBuilder('i')
->where('i.trainee = :trainee')
->andWhere('i.state = :state')
->setParameter('trainee', $trainee)
->setParameter('state', 'unverified');
},
'choice_label' => 'idAndType',
'constraints' => array(
new NotBlank(array(
'message' => 'choice.not.blank'
))
)
))
Internship.php:
Class Internship
{
//...
public function getIdAndType()
{
return '#'.$this->id.' ('.$this->type.')';
}
}
Note:
For older Symfony versions (<= 2.6), this option was named property and use something supported by the PropertyAccessor component, so you can't use a function, only a getter for it.

Not to validate the form in Symfony 2

Here is my form, I build in the controller:
$defaulData = ....
$formBuilder = $this->createFormBuilder($defaultData);
$entity_options = array(
'class' => 'MyBundle:Param',
'property' => 'description',
'query_builder' => function(EntityRepository $er) {
return $er->getParamsFromCategorieQueryBuilder(MyController::$category_for_list);
},
'label' => 'Donnée à afficher'
);
$formBuilder
->add('entity_types', 'entity', $entity_options);
The form is a list of Param objects, it displays good but for some reason, when I submit the form, I have an error on entity_types field saying that the value cannot be blank though there is one Param selected (even by default).
So I was wondering if I could disable validation.
When whould I put this validation_groups to false ? if it is in $entity_options, I tried it already and it does not work.
ty
You should modify you options like this (both require and groups are needed):
$entity_options = array(
'class' => 'MyBundle:Param',
'property' => 'description',
'query_builder' => function(EntityRepository $er) {
return $er->getParamsFromCategorieQueryBuilder(MyController::$category_for_list);
},
'required' => false,
'validation_groups' => false,
'label' => 'Donnée à afficher'
);
If the error is instead on the Form class itself, you should change in:
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'validation_groups' => false,
));
}
The way to prevent validation for good is this one :
$formBuilder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
$event->stopPropagation();
}, 900);
It prevents from calling the validation event.
The solution that giosh94mhz gave me what not good because even with validation_group = false some validation are still done.

Symfony2 Form entity field with query_builder

I have a form with an entity field, without the query_builder work fine, but with the query_builder the form display the result of the query but is not valid when is submited.
//tecnicosType
$builder->add('dt', 'entity', array(
'class' => 'MSKLigaBundle:Jugadores',
'label' => 'DT',
'query_builder' => function(
\MSK\LigaBundle\Entity\JugadoresRepository $er) use($equipoId){
return $er->getJugadores($equipoId);
},
'property' => 'nombreCompleto',
'empty_value' => "Sin definir",
'required' => false
))
And the function is
public function getJugadoresQueryBuilder($equipo)
{
$queryBuilder = $this->createQueryBuilder('j');
return $queryBuilder->select('j')
->where('j.equipo_id = :equipo')
->setParameter('equipo', $equipo);
}
when the form is submited return
array
'dt' =>
array
0 => string 'This value is not valid.'
If i coment the query_builder the form validate fine.
I can't find the solution, thank for any help.

Symfony2 form populating entitiy based on other entity

I'm using Symfony2 form component to create and modify forms. I'm currently loading all model entities as choices, but I need to get only the Models related to the selected (posted) value from manufacturer.
How can I achieve this?
class VehicleType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('manufacturer', 'entity', array(
'label' => 'Brand',
'attr' => array('class' => 'input-block-level'),
'class' => 'BalslevCarBundle:Manufacturers',
'property' => 'short_name',
'empty_value' => 'All',
'required' => false
));
$builder->add('model', 'entity', array(
'label' => 'Model',
'class' => 'BalslevCarBundle:Models',
'property' => 'model',
'empty_value' => 'All',
'required' => false
));
}
public function getName()
{
return 'search';
}
}
First of all, you have to create "dynamically" your choices based onto user selection.
There are two ways, strictly coupled with your application behaviour, that leads (in both cases) at the same "core" code; the difference is only the way you call it.
So, let's explain the two possibilities:
Select manufacturer "statically" and don't change it over the time of request: use data retrieved from your business logic
Select manufacturer "dinamically" and can change them over the time of request: replace your form at every request; new form will be provided by business logic
So, the HEART of your question is: how can I retrieve only associated entities?
Answer
Into your VehicleType.php (where entity, in this case, is VehicleType ?)
private $manufacturerId;
public function __construct($manufacturerId)
{
$this->manufacturerId = $manufacturerId;
}
public function BuildForm(FormBuilderInterface $builder)
{
$manufacturerId = $this->manufacturerId;
$manufacturerQuery = function(EntityRepository $repo) use ($manufacturerId ){
return $repo->createQueryBuilder('m')
->where('m.id = :id')
->setParameter('id',$manufacturerId );};
$builder->add('manufacturer', 'entity', array(
'label' => 'Brand',
'attr' => array('class' => 'input-block-level'),
'class' => 'BalslevCarBundle:Manufacturers',
'property' => 'short_name',
'empty_value' => 'All',
'required' => false,
'query_builder' => $manufacturerQuery;
));
$builder->add('model', 'entity', array(
'label' => 'Brand',
'attr' => array('class' => 'input-block-level'),
'class' => 'BalslevCarBundle:Manufacturers',
'property' => 'short_name',
'empty_value' => 'All',
'required' => false,
'query_builder' => $modelQuery;
));
}
As you can see, in this way we use a custom repository to get only entities that are suitable for our needs. Obviously I am writing my DQL query without knowing your DB structure: it's your task and responsibility to adapt it to your real situation.
Moreover, you have to create another query for model (called $modelQuery in my answer) to retrieve correct models based on selected $id