I have a simple formType with an single checkBoxType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('domain_choose', CheckboxType::class, [
'label' => false,
]);
}
Then I render it inside a loop
{% for domain, availability in availabilities %}
<tr>
<td>{{ form_widget(form.domain_choose) }}</td>
</tr>
{% endfor %}
The problem is that, only the first checkbox of the loop is rendered.
I tried to manually change the form name without succes
{'full_name': 'domain_choose[domain_choose_' ~ loop.index ~ ']'},
Is there a way to render this checkbox multiple time inside my loop ? Or should I use a single checkbox input without formType ?
#Jérôme As per symfony form you do not repeat form element. If you need multiple checkbox then you can use something like this
$builder->add('domain_choose', ChoiceType::class, array(
'choices' => array(
'Select' => null,
'Domain1' => 'Domain1',
'Domain2' => 'Domain2',
),
'expanded' => true,
'multiple' => true
));
expanded => true and multiple => true is used for (multiple)checkbox, For more detail you can visit http://symfony.com/doc/current/reference/forms/types/choice.html
Related
I'm trying to create multiple HiddenType fields in with Form Builder using CollectionType, to group these fields when I'm dealing with them in my controller. But I want each field to have different attributes. Is it possible to use entry_options to set different options for each entry?
I'm using a javascript drag and drop plugin to drop elements in a container, when these elements are dropped a JS code updates these hidden fields that, I use to capture the information in my controller. So is mandatory that these fields are grouped somehow so I can deal with them easily in my controller.
An example:
$builder->add(self::FIELD_MAPPED_COLUMNS, CollectionType::class, [
'entry_type' => HiddenType::class,
'data' => ['field1', 'field2', 'field3'],
'label' => false,
'entry_options' => [
'attr' => [
'data-my-field' => '?????'
]
]
])->add('submit', SubmitType::class);
I want to set a different data-my-field for each HiddenType so I can use it in Javascript. Is it possible?
I just faced the same problem. Here is my workaround.
First add a template in the entry_options:
$builder->add(self::FIELD_MAPPED_COLUMNS, CollectionType::class, [
'entry_type' => HiddenType::class,
'data' => ['field1', 'field2', 'field3'],
'label' => false,
'entry_options' => [
'attr' => [
'data-my-field' => '%templateForMyFieldByFieldData%'
]
]
])->add('submit', SubmitType::class);
Then render each field of the collection individually in a Twig loop and replace the template by the required value:
...
{{ (form_widget(field) | replace('%templateForMyFieldByFieldData%', valueToInsert)) | raw }}
...
Hopefully it will be usefull to someone !
How can I cancel displaying form field in twig, if I do not need it?
<p>Form: <br>
$form ->add("rxOriginCode", ChoiceType::class, [<br>
"label" => "Rx Origin",<br>
"required" => true,<br>
"choices" => <br>PrescriptionOriginCode::getDictionary(EnumFactory::FLAG_SHORT),<br>
"mapped" => false,<br>
"data" => $data->getRx()->getRxOriginCode(),
If you are displaying your elements one by one, there is a parameter in the method form_end to prevent Twig from generating elements you did not display yes :
{{ form_end(form, {'render_rest': false}) }}
http://symfony.com/doc/current/reference/forms/twig_reference.html#form-end-view-variables
I want to set a form with a "preferred_choices" on top of my select field HTML corresponding to previous submitted datas selected by the user. I want to construct an entity field with a constant list AND a preferred_choices top element if the form is previously submitted.
I never ran correctly this function in symfony2.
Can you help me to construct correctly my field form.
Why my preferred_choices options select nothing when the form is construct ?
I setting this with correct object setted previously in the code.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$defaultCQSsearch = new CqsProSansMarque();
$defaultCQSsearch->setRayLibelle((!array_key_exists('ray_libelle', $options['attr'])) ? null : $options['attr']['ray_libelle']);
$defaultCQSsearch->setFamLibelle((!array_key_exists('fam_libelle', $options['attr'])) ? null : $options['attr']['fam_libelle']);
$defaultCQSsearch->setCaeLibelle((!array_key_exists('cae_libelle', $options['attr'])) ? null : $options['attr']['cae_libelle']);
$builder
->add('ray_libelle', 'entity', array(
'class' => 'ApplicationDriveBundle:CqsProSansMarque',
'data_class' => 'Application\DriveBundle\Entity\CqsProSansMarque',
'property' => 'ray_libelle',
'query_builder' => function(CqsProSansMarqueRepository $er){
return $er->createQueryBuilder('a')
->select('a')
->groupBy('a.ray_libelle');
},
'preferred_choices' => array($defaultCQSsearch),
'label' => 'rayon',
'required' => false,
))
preferred_choices option expects an array of values but you are passing an array of object (i.e. $defaultCQSsearch)
I'm trying to add the selected attribute to my <option> tags
{% for product in form.products %}
{# of course this should only done inside a if,
but for testing purpose, it's okay #}
{{ form_widget(product, { 'attr': {'selected': 'selected'} }) }}
{% endfor %}
However this does not work. Even exactly the same copy&paste from the symfony2 docs here does not work: http://symfony.com/doc/current/book/forms.html#rendering-each-field-by-hand
I'm adding the form element inside a FormType à la:
public function buildForm(FormBuilderInterface $builder, array $options) {
parent::buildForm($builder, $options);
$builder
->add('products', 'entity', array('attr' => array('class' => 'choseable input-xlarge'),
'property_path' => false, 'label' => 'form.products.title', 'class' => 'Test\Bundle\Entity\Product', 'choices' => $products, 'multiple' => true, 'empty_value' => 'form.products.placeholder'));
}
All variables ($products) are ok in the example above.
Is there a problem?
I'm using Symfony 2.1.9-dev.
Can you update the question with form creation code? I'm pretty sure that Symfony is able to make item selected only if it's present in your model. But since you field is marked with property_path => false I don't think you can override this behavior...
An idea:
Fetch all the data used in your entity field type and pass it to form object (either via constructor or options array)
Add field as you're currently doing it
Invoke setData right afterwards to set field data (using data fetched in step #1)
Btw, I am not big fan of setData but situation like this just calls for it :)
Hope that this helps...
There are several issues with your code. I reformatted the code below for better clarity.
public function buildForm(FormBuilderInterface $builder, array $options) {
parent::buildForm($builder, $options);
$builder->add('products', 'entity', array(
'attr' => array('class' => 'choseable input-xlarge'),
'property_path' => false,
'label' => 'form.products.title',
'class' => 'Test\Bundle\Entity\Product',
'choices' => $products,
'multiple' => true,
'empty_value' => 'form.products.placeholder'
));
}
Don't use class inheritance for form types (except of course extending AbstractType). Use getParent() for extending other types instead.
You can't set attributes of <option> tags manually. You would have to render the tags by hand.
For marking choices as selected, you need to pass default data to the field. Usually getProducts() would be called here to get the defaults, but you disabled that by setting property_path to false. So you should set the defaults manually by using the data option. Note that the defaults need to be an array/a collection, since multiple is true.
You are manually passing choices, which is a bad practice. If you just remove this option, the entity field can itself query the choices from the DB and optimize the needed statements for better performance.
Format your code. Really. :P
I'm rendering a form in Symfony2 with data_class mapped to Reservation entity, and this form has a entity field type, of class Service. The relation between Reservation and Service class is many to many. A service then has a ServiceType, which is another class, that is mapped as many to one from the Service class
What I want to do is display all services as checkboxes in the reservation form, grouped by service type. So far, I can display all the services together like this (the code is from ReservationType class):
$builder->add('services','entity', array(
'class' => 'MyBundle:Service',
'multiple' => true,
'expanded' => true
));
And displaying the form the default way:
<form action="{{ path('reservations', {'step': 2}) }}" method="post" {{ form_enctype(form) }}>
{{ form_widget(form) }}
<input type="submit" />
</form>
The result is something like this:
□ servicetype1 option
□ servicetype1 another option
□ servicetype2 option
□ servicetype2 another option
What I would like to achieve is:
servicetype1:
□ option
□ another option
servicetype2:
□ option
□ another option
I was trying to specify only subsets of services by using query_builder option like this:
$builder->add('services','entity', array(
'class' => 'MyBundle:Service',
'multiple' => true,
'expanded' => true,
'query_builder' => function (\My\Bundle\Entity\ServiceRepository $repository)
{return $repository->createQueryBuilder('s')->where('s.serviceType = ?1')->setParameter(1, 1);} ));
$builder->add('services','entity', array(
'class' => 'MyBundle:Service',
'multiple' => true,
'expanded' => true,
'query_builder' => function (\My\Bundle\Entity\ServiceRepository $repository)
{return $repository->createQueryBuilder('s')->where('s.serviceType = ?1')->setParameter(1, 2);} ));
This is wrong, because:
I have to specify the ServiceType id
Adding the 'services' to the builder twice, will overwrite the first addition (which is logical, but cannot be solved without changing the entities)
What would be the best option for handling forms like this? There are only 2 ServiceType-s so far, but I would like to keep it dynamic, and reusable.
I suppose the only way to do that is override rendering in the template. You should pass to your template entity MyBundle:Service and render it for example like this:
{% for service in services %}
<b>{{ service.name }}</b><br>
{% for option in service.options %}
<label>
<input type="checkbox" name="form_type_name[options][{{ option.id }}]" value="{{ option.id }}" {% if option in user.services.options %}checked="checked"{% endif %}>
{{ option.name }}
</label>
{% endfor %}
{% endfor %}
This can be solved by using the group_by option:
$builder->add('services','entity', array(
'class' => 'MyBundle:Service',
'group_by' => 'serviceType',
'multiple' => true,
'expanded' => true
));